added depth buffer and successfully used it in raymarcher
This commit is contained in:
parent
361e988930
commit
0bb9be2d36
2
Makefile
2
Makefile
@ -4,7 +4,7 @@ SHADER_DIR := shaders
|
||||
BUILD_DIR := build
|
||||
|
||||
CXX := g++
|
||||
CXXFLAGS := -std=c++20 -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-unused-function
|
||||
CXXFLAGS := -g -std=c++20 -Wall -Wextra -Wpedantic -Wno-missing-field-initializers -Wno-unused-function
|
||||
LDFLAGS := -lSDL3
|
||||
|
||||
GLSLC := glslc
|
||||
|
||||
61
flake.lock
generated
Normal file
61
flake.lock
generated
Normal file
@ -0,0 +1,61 @@
|
||||
{
|
||||
"nodes": {
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1731533236,
|
||||
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1776169885,
|
||||
"narHash": "sha256-l/iNYDZ4bGOAFQY2q8y5OAfBBtrDAaPuRQqWaFHVRXM=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "4bd9165a9165d7b5e33ae57f3eecbcb28fb231c9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@ -3,18 +3,22 @@
|
||||
layout(location = 0) in vec2 uv;
|
||||
layout(location = 0) out vec4 out_color;
|
||||
layout(set = 2, binding = 0) uniform sampler2D screen;
|
||||
layout(set = 2, binding = 1) uniform sampler2D depth_tex;
|
||||
|
||||
layout(std140, set = 3, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
float time;
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
mat4 inv_view;
|
||||
mat4 inv_projection;
|
||||
vec4 time_padded;
|
||||
vec4 cam_pos;
|
||||
};
|
||||
|
||||
|
||||
float road(float x) { return cos(x); }
|
||||
|
||||
vec3 backup(vec2 uv) {
|
||||
float time = time_padded.x;
|
||||
float x_scale = time * 12.0;
|
||||
float y_scale = uv.x;
|
||||
|
||||
@ -36,7 +40,7 @@ const int MAX_MARCH_STEPS = 64;
|
||||
const float EPS_DIST = 1e-6;
|
||||
|
||||
float sdf(vec3 point) {
|
||||
// return length(point - vec3(6.0 * sin(time), 8.0*abs(sin(time * 0.7)*cos(time)), 5.0 * cos(time * 1.2))) - 0.4;
|
||||
float time = time_padded.x;
|
||||
float size = 8.0 + (3.0* sin(time));
|
||||
vec3 s1_local = mod(point, vec3(size)) - vec3(size/2.0);
|
||||
float s1 = length(s1_local) - 0.3;
|
||||
@ -54,14 +58,15 @@ vec3 getnormal(vec3 p) {
|
||||
|
||||
|
||||
|
||||
vec4 march(vec3 point, vec3 ray) {
|
||||
float MAX_DEPTH = texture(screen, uv).w * 1000.0;
|
||||
vec4 march(vec3 point, vec3 ray, float max_depth) {
|
||||
float totaldist = 0.0;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < MAX_MARCH_STEPS && totaldist < MAX_DEPTH; i += 1) {
|
||||
for (i = 0; i < MAX_MARCH_STEPS && totaldist < max_depth; i += 1) {
|
||||
float h = sdf(point);
|
||||
point += h * ray;
|
||||
if (h + totaldist > max_depth)
|
||||
break;
|
||||
if (h < EPS_DIST) {
|
||||
return vec4(point, totaldist + h);
|
||||
}
|
||||
@ -75,34 +80,35 @@ vec4 march(vec3 point, vec3 ray) {
|
||||
vec3 camray() {
|
||||
vec2 ndc = uv * 2.0 - 1.0;
|
||||
ndc.y = -ndc.y;
|
||||
vec4 clip = vec4(ndc, 1.0, 1.0);
|
||||
vec4 view_pos = inverse(projection) * clip;
|
||||
vec4 view_pos = inv_projection * vec4(ndc, 1.0, 1.0);
|
||||
view_pos /= view_pos.w;
|
||||
|
||||
vec3 ray_dir_view = normalize(view_pos.xyz);
|
||||
|
||||
vec3 ray_dir_world = normalize((inverse(view) * vec4(ray_dir_view, 0.0)).xyz);
|
||||
|
||||
return ray_dir_world;
|
||||
return normalize((inv_view * vec4(normalize(view_pos.xyz), 0.0)).xyz);
|
||||
}
|
||||
|
||||
vec3 camorigin() { return (inverse(view) * vec4(0, 0, 0, 1)).xyz; }
|
||||
|
||||
vec4 kernel() {
|
||||
vec3 cam_pos = camorigin();
|
||||
vec4 kernel(float max_depth) {
|
||||
max_depth = (max_depth > 0.0)? max_depth : 1000.0;
|
||||
vec3 cam_ray = camray();
|
||||
|
||||
return march(cam_pos, cam_ray);
|
||||
return march(cam_pos.xyz, cam_ray, max_depth);
|
||||
}
|
||||
|
||||
float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); }
|
||||
|
||||
void main() {
|
||||
float linearize_depth(vec2 uv) {
|
||||
float d = texture(depth_tex, uv).r;
|
||||
if (d >= 1.0) return 1000.0; // nothing written
|
||||
vec4 ndc = vec4((uv * 2.0 - 1.0), d * 2.0 - 1.0, 1.0);
|
||||
vec4 view_pos = inv_projection * ndc;
|
||||
view_pos /= view_pos.w;
|
||||
return -view_pos.z; // view space, positive distance
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 bg = (projection * view * vec4(uv, 1.0, 1.0)).xy;
|
||||
vec3 b = backup(bg);
|
||||
vec4 hit = kernel();
|
||||
if (hit.w > 0.0 && ((t(uv.x, uv.y) < 0.01) || (hit.w < (texture(screen, uv).w * 1000.0)))) {
|
||||
float max_depth = linearize_depth(uv);
|
||||
vec4 hit = kernel(max_depth);
|
||||
if (hit.w > 0.0) {
|
||||
out_color = vec4(getnormal(hit.xyz), 1.0);
|
||||
} else {
|
||||
out_color = texture(screen, uv);
|
||||
|
||||
@ -8,7 +8,10 @@ layout(std140, set = 3, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
float time;
|
||||
mat4 inv_view;
|
||||
mat4 inv_projection;
|
||||
vec4 time_padded;
|
||||
vec4 cam_pos;
|
||||
};
|
||||
|
||||
float t(float x, float y) { return length(texture(screen, vec2(x, y)).xyz); }
|
||||
|
||||
@ -8,10 +8,13 @@ layout(location = 1) out float depth;
|
||||
layout(location = 2) out vec3 v_normal_vs; // view-space normal
|
||||
|
||||
layout(std140, set = 1, binding = 0) uniform UniformBlock {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
float time;
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
mat4 inv_view;
|
||||
mat4 inv_projection;
|
||||
vec4 time_padded;
|
||||
vec4 cam_pos;
|
||||
};
|
||||
|
||||
void main() {
|
||||
|
||||
@ -18,7 +18,8 @@ void Camera::update() {
|
||||
vec3 d = dir();
|
||||
vec3 right = normalize(cross(d, up));
|
||||
target = pos + d;
|
||||
float shift_speed = shifted? 10.0 : 1.0;
|
||||
|
||||
float shift_speed = shifted? 100.0 : 1.0;
|
||||
float speed = move_speed * shift_speed;
|
||||
|
||||
if (move_forward) { pos += d * speed; target += d * speed; }
|
||||
@ -56,10 +57,15 @@ void Camera::on_mouse_motion(float dx, float dy) {
|
||||
}
|
||||
|
||||
CameraUBO Camera::ubo(float aspect) const {
|
||||
mat4 v = lookAt(pos, target, up);
|
||||
mat4 p = perspective(radians(fov), aspect, 0.01f, 1000.0f);
|
||||
return CameraUBO {
|
||||
.model = mat4(1.0f),
|
||||
.view = lookAt(pos, target, up),
|
||||
.proj = perspective(radians(fov), aspect, 0.01f, 1000.0f),
|
||||
.time = (float)SDL_GetTicks() / 1000.0f,
|
||||
.model = mat4(1.0f),
|
||||
.view = v,
|
||||
.proj = p,
|
||||
.inv_view = inverse(v),
|
||||
.inv_proj = inverse(p),
|
||||
.time = vec4((float)SDL_GetTicks() / 1000.0f, 0.0, 0.0, 0.0),
|
||||
.cam_pos = vec4(pos, 1.0),
|
||||
};
|
||||
}
|
||||
@ -48,9 +48,16 @@ void ScenePipeline::create(SDL_GPUDevice* dev, SDL_Window* win) {
|
||||
.cull_mode = SDL_GPU_CULLMODE_NONE,
|
||||
.front_face = SDL_GPU_FRONTFACE_COUNTER_CLOCKWISE,
|
||||
},
|
||||
.depth_stencil_state = {
|
||||
.compare_op = SDL_GPU_COMPAREOP_LESS,
|
||||
.enable_depth_test = true,
|
||||
.enable_depth_write = true,
|
||||
},
|
||||
.target_info = {
|
||||
.color_target_descriptions = &color_tgt,
|
||||
.num_color_targets = 1,
|
||||
.depth_stencil_format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
|
||||
.has_depth_stencil_target = true,
|
||||
},
|
||||
};
|
||||
|
||||
@ -67,7 +74,7 @@ void ScenePipeline::destroy(SDL_GPUDevice* dev) {
|
||||
|
||||
void BlitPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) {
|
||||
vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0);
|
||||
frag = load_shader(dev, "shaders/blit.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1);
|
||||
frag = load_shader(dev, "shaders/blit.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 2, 1);
|
||||
|
||||
SDL_GPUColorTargetDescription color_tgt {
|
||||
.format = SDL_GetGPUSwapchainTextureFormat(dev, win),
|
||||
|
||||
@ -15,6 +15,18 @@ bool Renderer::init(SDL_Window* w) {
|
||||
load_obj();
|
||||
|
||||
render_sampler = create_linear_sampler(dev);
|
||||
SDL_GPUSamplerCreateInfo depth_sampler_info {
|
||||
.min_filter = SDL_GPU_FILTER_NEAREST,
|
||||
.mag_filter = SDL_GPU_FILTER_NEAREST,
|
||||
.mipmap_mode = SDL_GPU_SAMPLERMIPMAPMODE_NEAREST,
|
||||
.address_mode_u = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||
.address_mode_v = SDL_GPU_SAMPLERADDRESSMODE_CLAMP_TO_EDGE,
|
||||
.compare_op = SDL_GPU_COMPAREOP_INVALID,
|
||||
.enable_compare = false,
|
||||
};
|
||||
depth_sampler = SDL_CreateGPUSampler(dev, &depth_sampler_info);
|
||||
|
||||
|
||||
resize_render_texture(960, 540);
|
||||
|
||||
scene.create(dev, win);
|
||||
@ -25,10 +37,11 @@ bool Renderer::init(SDL_Window* w) {
|
||||
}
|
||||
|
||||
void Renderer::destroy() {
|
||||
if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex);
|
||||
if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex);
|
||||
if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex);
|
||||
if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex);
|
||||
if (render_sampler) SDL_ReleaseGPUSampler(dev, render_sampler);
|
||||
if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff);
|
||||
if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff);
|
||||
if (depth_tex) SDL_ReleaseGPUTexture(dev, depth_tex);
|
||||
scene.destroy(dev);
|
||||
blit.destroy(dev);
|
||||
post.destroy(dev);
|
||||
@ -101,6 +114,19 @@ void Renderer::resize_render_texture(uint32_t w, uint32_t h) {
|
||||
SDL_WaitForGPUIdle(dev);
|
||||
if (render_tex) SDL_ReleaseGPUTexture(dev, render_tex);
|
||||
if (post_tex) SDL_ReleaseGPUTexture(dev, post_tex);
|
||||
if (depth_tex) SDL_ReleaseGPUTexture(dev, depth_tex);
|
||||
|
||||
SDL_GPUTextureCreateInfo depth_info {
|
||||
.type = SDL_GPU_TEXTURETYPE_2D,
|
||||
.format = SDL_GPU_TEXTUREFORMAT_D32_FLOAT,
|
||||
.usage = SDL_GPU_TEXTUREUSAGE_DEPTH_STENCIL_TARGET | SDL_GPU_TEXTUREUSAGE_SAMPLER,
|
||||
.width = w,
|
||||
.height = h,
|
||||
.layer_count_or_depth = 1,
|
||||
.num_levels = 1,
|
||||
};
|
||||
|
||||
depth_tex = SDL_CreateGPUTexture(dev, &depth_info);
|
||||
render_tex = create_render_texture(dev, win, w, h);
|
||||
post_tex = create_render_texture(dev, win, w, h);
|
||||
render_w = w;
|
||||
@ -118,7 +144,16 @@ void Renderer::pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) {
|
||||
.store_op = SDL_GPU_STOREOP_STORE,
|
||||
};
|
||||
|
||||
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL);
|
||||
SDL_GPUDepthStencilTargetInfo depth_tgt {
|
||||
.texture = depth_tex,
|
||||
.clear_depth = 1.0f,
|
||||
.load_op = SDL_GPU_LOADOP_CLEAR,
|
||||
.store_op = SDL_GPU_STOREOP_STORE,
|
||||
.stencil_load_op = SDL_GPU_LOADOP_DONT_CARE,
|
||||
.stencil_store_op = SDL_GPU_STOREOP_STORE,
|
||||
};
|
||||
|
||||
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, &depth_tgt);
|
||||
SDL_BindGPUGraphicsPipeline(pass, scene.pipeline);
|
||||
SDL_GPUBufferBinding binding { .buffer = vert_buff, .offset = 0 };
|
||||
SDL_BindGPUVertexBuffers(pass, 0, &binding, 1);
|
||||
@ -137,8 +172,11 @@ void Renderer::pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) {
|
||||
|
||||
SDL_GPURenderPass* pass = SDL_BeginGPURenderPass(cmd, &tgt, 1, NULL);
|
||||
SDL_BindGPUGraphicsPipeline(pass, blit.pipeline);
|
||||
SDL_GPUTextureSamplerBinding tex { .texture = render_tex, .sampler = render_sampler };
|
||||
SDL_BindGPUFragmentSamplers(pass, 0, &tex, 1);
|
||||
SDL_GPUTextureSamplerBinding texs[2] = {
|
||||
{ .texture = render_tex, .sampler = render_sampler },
|
||||
{ .texture = depth_tex, .sampler = depth_sampler },
|
||||
};
|
||||
SDL_BindGPUFragmentSamplers(pass, 0, texs, 2);
|
||||
SDL_DrawGPUPrimitives(pass, 3, 1, 0, 0);
|
||||
SDL_EndGPURenderPass(pass);
|
||||
}
|
||||
|
||||
@ -15,7 +15,9 @@ struct Renderer {
|
||||
SDL_GPUBuffer* vert_buff = nullptr;
|
||||
SDL_GPUTexture* render_tex = nullptr;
|
||||
SDL_GPUTexture* post_tex = nullptr;
|
||||
SDL_GPUTexture* depth_tex = nullptr;
|
||||
SDL_GPUSampler* render_sampler = nullptr;
|
||||
SDL_GPUSampler* depth_sampler = nullptr;
|
||||
uint32_t render_w = 0, render_h = 0;
|
||||
|
||||
std::vector<Vertex> vertices;
|
||||
|
||||
11
src/types.h
11
src/types.h
@ -10,8 +10,11 @@ struct Vertex {
|
||||
};
|
||||
|
||||
struct CameraUBO {
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
float time;
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
mat4 proj;
|
||||
mat4 inv_view;
|
||||
mat4 inv_proj;
|
||||
vec4 time;
|
||||
vec4 cam_pos;
|
||||
};
|
||||
Loading…
x
Reference in New Issue
Block a user