Added dithering, renamed blit to ray to reflect that it is the raymarching passing

This commit is contained in:
Hopeless Tyromancy 2026-04-16 16:40:43 -04:00
parent 793987409f
commit e210e0d7f2
7 changed files with 65 additions and 29 deletions

View File

@ -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));
}

View File

@ -20,12 +20,10 @@ 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) {
@ -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 {
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;
}
}
}

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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);
};