mirror of
https://github.com/PixelGuys/Cubyz.git
synced 2025-08-03 03:06:55 -04:00
Add stars and a simple skybox (#1043)
* really bad and inefficient star code i think * add stars that dont work during the day but look cool * remove galaxy shape and replace it with a simple sphere * add broken background * make stars affected by fog * make the stars additive * remove commented code in shaders * remove unused variables in the shader * make the stars spin * make stars not have bloom * fix formatting * temp changes * fix formatting (still temp changes) * switch to cubyz random numbers * multiply star matrix in cpu instead of gpu * changed star to be twice as big, not affect by resolution as much, and also be loaded from a texture * remove trailing whitespaces * remove unused constants * simplify the code by removing a log and power * optimizing the stars * remove debug code * make stars triangles instead of points * simplify the math more * give star ssbo unique id * fix formatting issues * make array multiline * fix formatting * remove files i accidentally added * remove random obj file * fix some issues * use square distance * fix formatting * small change * fix some stuff * fix other things * comp error * more stuff * fix some stuff with the stars * test * fix formatting * fix more formatting * test 2 * fixes * changes * changes * fix formatting * fixes * remove patch
This commit is contained in:
parent
a2911710a6
commit
9181b31a6d
14
assets/cubyz/shaders/skybox/star.fs
Normal file
14
assets/cubyz/shaders/skybox/star.fs
Normal file
@ -0,0 +1,14 @@
|
||||
#version 430
|
||||
|
||||
in vec3 pos;
|
||||
in flat vec3 centerPos;
|
||||
in flat vec3 color;
|
||||
|
||||
layout (location = 0, index = 0) out vec4 fragColor;
|
||||
|
||||
void main() {
|
||||
if (dot(pos - centerPos, pos - centerPos) > 1.0/12.0)
|
||||
discard;
|
||||
|
||||
fragColor = vec4(color, 1);
|
||||
}
|
29
assets/cubyz/shaders/skybox/star.vs
Normal file
29
assets/cubyz/shaders/skybox/star.vs
Normal file
@ -0,0 +1,29 @@
|
||||
#version 430
|
||||
|
||||
struct star {
|
||||
vec4 vertexPositions[3];
|
||||
|
||||
vec3 pos;
|
||||
float padding1;
|
||||
vec3 color;
|
||||
float padding2;
|
||||
};
|
||||
|
||||
layout (std430, binding = 12) buffer _starBuffer {
|
||||
star starData[];
|
||||
};
|
||||
|
||||
uniform mat4 mvp;
|
||||
uniform float starOpacity;
|
||||
|
||||
out vec3 pos;
|
||||
out flat vec3 centerPos;
|
||||
out flat vec3 color;
|
||||
|
||||
void main() {
|
||||
gl_Position = mvp*vec4(starData[gl_VertexID/3].vertexPositions[gl_VertexID%3].xyz, 1);
|
||||
|
||||
pos = starData[gl_VertexID/3].vertexPositions[gl_VertexID%3].xyz;
|
||||
centerPos = starData[gl_VertexID/3].pos;
|
||||
color = starData[gl_VertexID/3].color*starOpacity;
|
||||
}
|
BIN
assets/cubyz/star.png
Normal file
BIN
assets/cubyz/star.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
@ -641,7 +641,7 @@ pub const Player = struct { // MARK: Player
|
||||
};
|
||||
|
||||
pub const World = struct { // MARK: World
|
||||
const dayCycle: u63 = 12000; // Length of one in-game day in 100ms. Midnight is at DAY_CYCLE/2. Sunrise and sunset each take about 1/16 of the day. Currently set to 20 minutes
|
||||
pub const dayCycle: u63 = 12000; // Length of one in-game day in 100ms. Midnight is at DAY_CYCLE/2. Sunrise and sunset each take about 1/16 of the day. Currently set to 20 minutes
|
||||
|
||||
conn: *Connection,
|
||||
manager: *ConnectionManager,
|
||||
|
@ -14,6 +14,7 @@ const GuiComponent = gui.GuiComponent;
|
||||
pub const Samples = enum(u8) {
|
||||
screenbuffer_clear,
|
||||
clear,
|
||||
skybox,
|
||||
animation,
|
||||
chunk_rendering_preparation,
|
||||
chunk_rendering_previous_visible,
|
||||
@ -33,6 +34,7 @@ pub const Samples = enum(u8) {
|
||||
const names = [_][]const u8{
|
||||
"Screenbuffer clear",
|
||||
"Clear",
|
||||
"Skybox",
|
||||
"Pre-processing Block Animations",
|
||||
"Chunk Rendering Preparation",
|
||||
"Chunk Rendering Previous Visible",
|
||||
|
@ -53,6 +53,17 @@ pub fn nextFloatSigned(seed: *u64) f32 {
|
||||
return @as(f32, @floatFromInt(@as(i24, @bitCast(nextInt(u24, seed)))))/(1 << 23);
|
||||
}
|
||||
|
||||
pub fn nextFloatExp(seed: *u64) f32 {
|
||||
return -@log(nextFloat(seed));
|
||||
}
|
||||
|
||||
pub fn nextFloatGauss(seed: *u64) f32 {
|
||||
const a = nextFloat(seed);
|
||||
const b = nextFloat(seed);
|
||||
|
||||
return @sqrt(-2.0*@log(a))*@cos(2.0*std.math.pi*b);
|
||||
}
|
||||
|
||||
pub fn nextFloatVector(len: comptime_int, seed: *u64) @Vector(len, f32) {
|
||||
var result: @Vector(len, f32) = undefined;
|
||||
inline for(0..len) |i| {
|
||||
|
175
src/renderer.zig
175
src/renderer.zig
@ -72,6 +72,7 @@ pub fn init() void {
|
||||
MenuBackGround.init() catch |err| {
|
||||
std.log.err("Failed to initialize the Menu Background: {s}", .{@errorName(err)});
|
||||
};
|
||||
Skybox.init();
|
||||
chunk_meshing.init();
|
||||
mesh_storage.init();
|
||||
reflectionCubeMap = .init();
|
||||
@ -86,6 +87,7 @@ pub fn deinit() void {
|
||||
Bloom.deinit();
|
||||
MeshSelection.deinit();
|
||||
MenuBackGround.deinit();
|
||||
Skybox.deinit();
|
||||
mesh_storage.deinit();
|
||||
chunk_meshing.deinit();
|
||||
reflectionCubeMap.deinit();
|
||||
@ -134,11 +136,10 @@ pub fn render(playerPosition: Vec3d, deltaTime: f64) void {
|
||||
ambient[0] = @max(0.1, world.ambientLight);
|
||||
ambient[1] = @max(0.1, world.ambientLight);
|
||||
ambient[2] = @max(0.1, world.ambientLight);
|
||||
const skyColor = vec.xyz(world.clearColor);
|
||||
game.fog.skyColor = skyColor;
|
||||
game.fog.skyColor = vec.xyz(world.clearColor);
|
||||
|
||||
itemdrop.ItemDisplayManager.update(deltaTime);
|
||||
renderWorld(world, ambient, skyColor, playerPosition);
|
||||
renderWorld(world, ambient, Skybox.getSkyColor(), playerPosition);
|
||||
const startTime = std.time.milliTimestamp();
|
||||
mesh_storage.updateMeshes(startTime + maximumMeshTime);
|
||||
} else {
|
||||
@ -183,6 +184,10 @@ pub fn renderWorld(world: *World, ambientLight: Vec3f, skyColor: Vec3f, playerPo
|
||||
|
||||
const time: u32 = @intCast(std.time.milliTimestamp() & std.math.maxInt(u32));
|
||||
|
||||
gpu_performance_measuring.startQuery(.skybox);
|
||||
Skybox.render();
|
||||
gpu_performance_measuring.stopQuery();
|
||||
|
||||
gpu_performance_measuring.startQuery(.animation);
|
||||
blocks.meshes.preProcessAnimationData(time);
|
||||
gpu_performance_measuring.stopQuery();
|
||||
@ -611,6 +616,170 @@ pub const MenuBackGround = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub const Skybox = struct {
|
||||
var starShader: Shader = undefined;
|
||||
var starUniforms: struct {
|
||||
mvp: c_int,
|
||||
starOpacity: c_int,
|
||||
} = undefined;
|
||||
|
||||
var starVao: c_uint = undefined;
|
||||
|
||||
var starSsbo: graphics.SSBO = undefined;
|
||||
|
||||
const numStars = 10000;
|
||||
|
||||
fn getStarPos(seed: *u64) Vec3f {
|
||||
const x: f32 = @floatCast(main.random.nextFloatGauss(seed));
|
||||
const y: f32 = @floatCast(main.random.nextFloatGauss(seed));
|
||||
const z: f32 = @floatCast(main.random.nextFloatGauss(seed));
|
||||
|
||||
const r = std.math.cbrt(main.random.nextFloat(seed))*5000.0;
|
||||
|
||||
return vec.normalize(Vec3f{x, y, z})*@as(Vec3f, @splat(r));
|
||||
}
|
||||
|
||||
fn getStarColor(temperature: f32, light: f32, image: graphics.Image) Vec3f {
|
||||
const rgbCol = image.getRGB(@intFromFloat(std.math.clamp(temperature/15000.0*@as(f32, @floatFromInt(image.width)), 0.0, @as(f32, @floatFromInt(image.width - 1)))), 0);
|
||||
var rgb: Vec3f = @floatFromInt(Vec3i{rgbCol.r, rgbCol.g, rgbCol.b});
|
||||
rgb /= @splat(255.0);
|
||||
|
||||
rgb *= @as(Vec3f, @splat(light));
|
||||
|
||||
const m = @reduce(.Max, rgb);
|
||||
if(m > 1.0) {
|
||||
rgb /= @as(Vec3f, @splat(m));
|
||||
}
|
||||
|
||||
return rgb;
|
||||
}
|
||||
|
||||
fn init() void {
|
||||
const starColorImage = graphics.Image.readFromFile(main.stackAllocator, "assets/cubyz/star.png") catch |err| {
|
||||
std.log.err("Failed to load star image: {s}", .{@errorName(err)});
|
||||
return;
|
||||
};
|
||||
defer starColorImage.deinit(main.stackAllocator);
|
||||
|
||||
starShader = Shader.initAndGetUniforms("assets/cubyz/shaders/skybox/star.vs", "assets/cubyz/shaders/skybox/star.fs", "", &starUniforms);
|
||||
starShader.bind();
|
||||
|
||||
var starData: [numStars*20]f32 = undefined;
|
||||
|
||||
const starDist = 200.0;
|
||||
|
||||
const off: f32 = @sqrt(3.0)/6.0;
|
||||
|
||||
const triVertA = Vec3f{0.5, starDist, -off};
|
||||
const triVertB = Vec3f{-0.5, starDist, -off};
|
||||
const triVertC = Vec3f{0.0, starDist, @sqrt(3.0)/2.0 - off};
|
||||
|
||||
var seed: u64 = 0;
|
||||
|
||||
for(0..numStars) |i| {
|
||||
var pos: Vec3f = undefined;
|
||||
|
||||
var radius: f32 = undefined;
|
||||
|
||||
var temperature: f32 = undefined;
|
||||
|
||||
var light: f32 = 0;
|
||||
|
||||
while(light < 0.1) {
|
||||
pos = getStarPos(&seed);
|
||||
|
||||
radius = @floatCast(main.random.nextFloatExp(&seed)*4 + 0.2);
|
||||
|
||||
temperature = @floatCast(@abs(main.random.nextFloatGauss(&seed)*3000.0 + 5000.0) + 1000.0);
|
||||
|
||||
// 3.6e-12 can be modified to change the brightness of the stars
|
||||
light = (3.6e-12*radius*radius*temperature*temperature*temperature*temperature)/(vec.dot(pos, pos));
|
||||
}
|
||||
|
||||
pos = vec.normalize(pos)*@as(Vec3f, @splat(starDist));
|
||||
|
||||
const normPos = vec.normalize(pos);
|
||||
|
||||
const color = getStarColor(temperature, light, starColorImage);
|
||||
|
||||
const latitude: f32 = @floatCast(std.math.asin(normPos[2]));
|
||||
const longitude: f32 = @floatCast(std.math.atan2(-normPos[0], normPos[1]));
|
||||
|
||||
const mat = Mat4f.rotationZ(longitude).mul(Mat4f.rotationX(latitude));
|
||||
|
||||
const posA = vec.xyz(mat.mulVec(.{triVertA[0], triVertA[1], triVertA[2], 1.0}));
|
||||
const posB = vec.xyz(mat.mulVec(.{triVertB[0], triVertB[1], triVertB[2], 1.0}));
|
||||
const posC = vec.xyz(mat.mulVec(.{triVertC[0], triVertC[1], triVertC[2], 1.0}));
|
||||
|
||||
starData[i*20 ..][0..3].* = posA;
|
||||
starData[i*20 + 4 ..][0..3].* = posB;
|
||||
starData[i*20 + 8 ..][0..3].* = posC;
|
||||
|
||||
starData[i*20 + 12 ..][0..3].* = pos;
|
||||
starData[i*20 + 16 ..][0..3].* = color;
|
||||
}
|
||||
|
||||
starSsbo = graphics.SSBO.initStatic(f32, &starData);
|
||||
|
||||
c.glGenVertexArrays(1, &starVao);
|
||||
c.glBindVertexArray(starVao);
|
||||
c.glEnableVertexAttribArray(0);
|
||||
}
|
||||
|
||||
pub fn deinit() void {
|
||||
starShader.deinit();
|
||||
starSsbo.deinit();
|
||||
c.glDeleteVertexArrays(1, &starVao);
|
||||
}
|
||||
|
||||
pub fn getSkyColor() Vec3f {
|
||||
return game.fog.skyColor*@as(Vec3f, @splat(@reduce(.Add, game.fog.skyColor)/3.0));
|
||||
}
|
||||
|
||||
pub fn render() void {
|
||||
const viewMatrix = game.camera.viewMatrix;
|
||||
|
||||
const time = game.world.?.gameTime.load(.monotonic);
|
||||
|
||||
var starOpacity: f32 = 0;
|
||||
const dayTime = @abs(@mod(time, game.World.dayCycle) -% game.World.dayCycle/2);
|
||||
if(dayTime < game.World.dayCycle/4 - game.World.dayCycle/16) {
|
||||
starOpacity = 1;
|
||||
} else if(dayTime > game.World.dayCycle/4 + game.World.dayCycle/16) {
|
||||
starOpacity = 0;
|
||||
} else {
|
||||
starOpacity = 1 - @as(f32, @floatFromInt(dayTime - (game.World.dayCycle/4 - game.World.dayCycle/16)))/@as(f32, @floatFromInt(game.World.dayCycle/8));
|
||||
}
|
||||
|
||||
if(starOpacity != 0) {
|
||||
c.glDisable(c.GL_CULL_FACE);
|
||||
c.glDisable(c.GL_DEPTH_TEST);
|
||||
|
||||
c.glBlendFunc(c.GL_ONE, c.GL_ONE);
|
||||
c.glEnable(c.GL_BLEND);
|
||||
|
||||
starShader.bind();
|
||||
|
||||
const starMatrix = game.projectionMatrix.mul(viewMatrix.mul(Mat4f.rotationX(@as(f32, @floatFromInt(time))/@as(f32, @floatFromInt(main.game.World.dayCycle)))));
|
||||
|
||||
starSsbo.bind(12);
|
||||
|
||||
c.glUniform1f(starUniforms.starOpacity, starOpacity);
|
||||
c.glUniformMatrix4fv(starUniforms.mvp, 1, c.GL_TRUE, @ptrCast(&starMatrix));
|
||||
|
||||
c.glBindVertexArray(starVao);
|
||||
c.glDrawArrays(c.GL_TRIANGLES, 0, numStars*3);
|
||||
|
||||
c.glBindBuffer(c.GL_SHADER_STORAGE_BUFFER, 0);
|
||||
|
||||
c.glBlendFunc(c.GL_SRC_ALPHA, c.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
c.glEnable(c.GL_CULL_FACE);
|
||||
c.glEnable(c.GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub const Frustum = struct { // MARK: Frustum
|
||||
const Plane = struct {
|
||||
pos: Vec3f,
|
||||
|
Loading…
x
Reference in New Issue
Block a user