From e210e0d7f218b5e2f10825a895f3125e768bc4ed Mon Sep 17 00:00:00 2001 From: Hopeless Tyromancy Date: Thu, 16 Apr 2026 16:40:43 -0400 Subject: [PATCH] Added dithering, renamed blit to ray to reflect that it is the raymarching passing --- shaders/post.frag | 2 +- shaders/{blit.frag => ray.frag} | 62 ++++++++++++++++++++++++++------- shaders/{blit.vert => ray.vert} | 0 src/pipelines.cpp | 12 +++---- src/pipelines.h | 2 +- src/renderer.cpp | 12 +++---- src/renderer.h | 4 +-- 7 files changed, 65 insertions(+), 29 deletions(-) rename shaders/{blit.frag => ray.frag} (57%) rename shaders/{blit.vert => ray.vert} (100%) diff --git a/shaders/post.frag b/shaders/post.frag index fddd934..c54e372 100644 --- a/shaders/post.frag +++ b/shaders/post.frag @@ -44,6 +44,6 @@ void main() { const mat3 sobely = mat3(-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0); - out_color = texture(screen, uv) + 0.01 * ((t(uv.x, uv.y) > 0.01)? + out_color = texture(screen, uv) + 0.1 * ((t(uv.x, uv.y) > 0.01)? vec4(abs(f(sobelx) + f(sobely)), 0.0, 0.0, 1.0) : vec4(0.0)); } \ No newline at end of file diff --git a/shaders/blit.frag b/shaders/ray.frag similarity index 57% rename from shaders/blit.frag rename to shaders/ray.frag index 991b01b..01986e6 100644 --- a/shaders/blit.frag +++ b/shaders/ray.frag @@ -20,21 +20,19 @@ const float EPS_DIST = 1e-6; float sdf(vec3 point){ - float time = time_padded.x; - float rad = 20 * abs(sin(time)); - vec3 pos = rad * vec3( - sin(time/20.0 + 3.4), cos(time/5.3), sin(time/2.3) * cos(time) - ); - return length(point-pos) - log(rad * time); + float t = 1.0 + 5.0*abs(sin(time_padded.x)); + vec3 s1_local = mod(point, vec3(t)) - vec3(t/2.0); + float s1 = length(s1_local) - 0.3; + return s1; } vec3 getnormal(vec3 p) { - float e = EPS_DIST; - return normalize(vec3( - sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)), - sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)), - sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e)) - )); + float e = EPS_DIST; + return normalize(vec3( + sdf(p + vec3(e, 0.0, 0.0)) - sdf(p - vec3(e, 0.0, 0.0)), + sdf(p + vec3(0.0, e, 0.0)) - sdf(p - vec3(0.0, e, 0.0)), + sdf(p + vec3(0.0, 0.0, e)) - sdf(p - vec3(0.0, 0.0, e)) + )); } vec4 march(vec3 point, vec3 ray, float max_depth) { @@ -82,12 +80,50 @@ float linearize_depth(vec2 uv) { return -view_pos.z; // view space, positive distance } +float brightness(vec3 color) { + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +float dither() { + if(length(texture(screen, uv).xyz) == 0.0) + return 0.0; + vec2 coord = uv * textureSize(screen, 0).xy; + + int x = int(mod(coord.x, 4.0)); + int y = int(mod(coord.y, 4.0)); + int index = x + y * 4; + + float threshold[16] = float[]( + 0.0/16.0, 8.0/16.0, 2.0/16.0, 10.0/16.0, + 12.0/16.0, 4.0/16.0, 14.0/16.0, 6.0/16.0, + 3.0/16.0, 11.0/16.0, 1.0/16.0, 9.0/16.0, + 15.0/16.0,7.0/16.0, 13.0/16.0, 5.0/16.0 + ); + + vec3 color = texture(screen, uv).rgb; + + return brightness(color) < threshold[index] ? 0.0 : 1.0; + +} + void main() { 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); + int t = int(fract(time_padded.x/5.0) * 30.0)/10; + switch(t) { + case 0: + out_color = texture(screen, uv); + break; + case 1: + out_color = vec4(brightness(texture(screen, uv).xyz) < 0.5? 0.0 : 1.0); + break; + case 2: + out_color = vec4(dither()); + break; + } } } + diff --git a/shaders/blit.vert b/shaders/ray.vert similarity index 100% rename from shaders/blit.vert rename to shaders/ray.vert diff --git a/src/pipelines.cpp b/src/pipelines.cpp index b2d906e..e2fbe1e 100644 --- a/src/pipelines.cpp +++ b/src/pipelines.cpp @@ -72,9 +72,9 @@ void ScenePipeline::destroy(SDL_GPUDevice* dev) { if (frag) SDL_ReleaseGPUShader(dev, frag); } -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, 2, 1); +void RayPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { + vert = load_shader(dev, "shaders/ray.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + frag = load_shader(dev, "shaders/ray.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 2, 1); SDL_GPUColorTargetDescription color_tgt { .format = SDL_GetGPUSwapchainTextureFormat(dev, win), @@ -103,17 +103,17 @@ void BlitPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { pipeline = SDL_CreateGPUGraphicsPipeline(dev, &info); if (!pipeline) - std::cerr << "Blit pipeline failed: " << SDL_GetError() << std::endl; + std::cerr << "Ray pipeline failed: " << SDL_GetError() << std::endl; } -void BlitPipeline::destroy(SDL_GPUDevice* dev) { +void RayPipeline::destroy(SDL_GPUDevice* dev) { if (pipeline) SDL_ReleaseGPUGraphicsPipeline(dev, pipeline); if (vert) SDL_ReleaseGPUShader(dev, vert); if (frag) SDL_ReleaseGPUShader(dev, frag); } void PostPipeline::create(SDL_GPUDevice* dev, SDL_Window* win) { - vert = load_shader(dev, "shaders/blit.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); + vert = load_shader(dev, "shaders/ray.vert.spv", SDL_GPU_SHADERSTAGE_VERTEX, 0, 0); frag = load_shader(dev, "shaders/post.frag.spv", SDL_GPU_SHADERSTAGE_FRAGMENT, 1, 1); SDL_GPUColorTargetDescription color_tgt { diff --git a/src/pipelines.h b/src/pipelines.h index 12281c7..2fef44a 100644 --- a/src/pipelines.h +++ b/src/pipelines.h @@ -10,7 +10,7 @@ struct ScenePipeline { void destroy(SDL_GPUDevice* dev); }; -struct BlitPipeline { +struct RayPipeline { SDL_GPUGraphicsPipeline* pipeline = nullptr; SDL_GPUShader* vert = nullptr; SDL_GPUShader* frag = nullptr; diff --git a/src/renderer.cpp b/src/renderer.cpp index a5eba8e..0967ef9 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -30,10 +30,10 @@ bool Renderer::init(SDL_Window* w) { resize_render_texture(960, 540); scene.create(dev, win); - blit.create(dev, win); + ray.create(dev, win); post.create(dev, win); - return scene.pipeline && blit.pipeline; + return scene.pipeline && ray.pipeline; } void Renderer::destroy() { @@ -43,7 +43,7 @@ void Renderer::destroy() { if (vert_buff) SDL_ReleaseGPUBuffer(dev, vert_buff); if (depth_tex) SDL_ReleaseGPUTexture(dev, depth_tex); scene.destroy(dev); - blit.destroy(dev); + ray.destroy(dev); post.destroy(dev); SDL_DestroyGPUDevice(dev); } @@ -161,7 +161,7 @@ void Renderer::pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { SDL_EndGPURenderPass(pass); } -void Renderer::pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { +void Renderer::pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo) { SDL_PushGPUFragmentUniformData(cmd, 0, &ubo, sizeof(ubo)); SDL_GPUColorTargetInfo tgt { @@ -171,7 +171,7 @@ 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_BindGPUGraphicsPipeline(pass, ray.pipeline); SDL_GPUTextureSamplerBinding texs[2] = { { .texture = render_tex, .sampler = render_sampler }, { .texture = depth_tex, .sampler = depth_sampler }, @@ -311,7 +311,7 @@ void Renderer::draw(const CameraUBO& ubo) { resize_render_texture(sw_w, sw_h); pass_scene(cmd, ubo); - pass_blit(cmd, ubo); + pass_ray(cmd, ubo); pass_post(cmd, swapchain, ubo); SDL_SubmitGPUCommandBuffer(cmd); diff --git a/src/renderer.h b/src/renderer.h index 123610a..4272249 100644 --- a/src/renderer.h +++ b/src/renderer.h @@ -9,7 +9,7 @@ struct Renderer { SDL_Window* win = nullptr; ScenePipeline scene; - BlitPipeline blit; + RayPipeline ray; PostPipeline post; SDL_GPUBuffer* vert_buff = nullptr; @@ -33,6 +33,6 @@ private: void add_gol_layer(); void resize_render_texture(uint32_t w, uint32_t h); void pass_scene(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); - void pass_blit(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); + void pass_ray(SDL_GPUCommandBuffer* cmd, const CameraUBO& ubo); void pass_post(SDL_GPUCommandBuffer* cmd, SDL_GPUTexture* swapchain, const CameraUBO& ubo); };