From 196533be9559253979833e63ad0fa453510f485e Mon Sep 17 00:00:00 2001 From: Katajisto Date: Wed, 22 Oct 2025 23:46:14 +0300 Subject: [PATCH] implement box blur for ssao --- src/rendering/backend_sokol.jai | 10 +- src/rendering/pipelines.jai | 94 ++++++- src/shaders/jai/shader_op.jai | 420 ++++++++++++++++++++++++++++++++ src/shaders/shader_op.glsl | 35 +++ 4 files changed, 556 insertions(+), 3 deletions(-) create mode 100644 src/shaders/jai/shader_op.jai create mode 100644 src/shaders/shader_op.glsl diff --git a/src/rendering/backend_sokol.jai b/src/rendering/backend_sokol.jai index eb62597..7bbf273 100644 --- a/src/rendering/backend_sokol.jai +++ b/src/rendering/backend_sokol.jai @@ -256,8 +256,7 @@ backend_process_command_buckets :: () { in_gbuffer_pass = false; current_trile_offset_index = 0; // This is not optimal, but it is nice and simple. - // --- TODO: Do SSAO pass here: - sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = g_ssao_attachments})); + sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = g_postprocess_attach_a })); sg_apply_pipeline(gPipelines.ssao.pipeline); gPipelines.ssao.bind.images[0] = g_gbuf_position; gPipelines.ssao.bind.images[1] = g_gbuf_normal; @@ -272,6 +271,13 @@ backend_process_command_buckets :: () { sg_draw(0, 6, 1); sg_end_pass(); + sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = g_ssao_attachments })); + sg_apply_pipeline(gPipelines.op.pipeline); + gPipelines.op.bind.images[0] = g_postprocess_a; + sg_apply_bindings(*gPipelines.op.bind); + sg_draw(0, 6, 1); + sg_end_pass(); + // 5. Main pass sg_begin_pass(*(sg_pass.{ action = state.pass_action_clear, attachments = g_rendertex_attachments})); for render_command_buckets.main { diff --git a/src/rendering/pipelines.jai b/src/rendering/pipelines.jai index 21fcf28..4093287 100644 --- a/src/rendering/pipelines.jai +++ b/src/rendering/pipelines.jai @@ -28,6 +28,14 @@ g_ssao_noise_buf : sg_image; g_ssaobuf_depth : sg_image; g_ssao_attachments : sg_attachments; +g_postprocess_a : sg_image; +g_postprocess_b : sg_image; +g_postprocess_a_depth : sg_image; +g_postprocess_b_depth : sg_image; +g_postprocess_attach_a : sg_attachments; +g_postprocess_attach_b : sg_attachments; + + gPipelines : struct { // G-Buffer generation for SSAO and other effects gbuffer: Pipeline_Binding; @@ -52,6 +60,8 @@ gPipelines : struct { // Post-processing pipeline postprocess : Pipeline_Binding; + op : Pipeline_Binding; + // Renders the SSAO texture using things from the gbuffer pass. ssao: Pipeline_Binding; } @@ -125,6 +135,7 @@ create_pipelines :: () { create_plane_pipeline(); create_postprocess_pipeline(); create_ssao_pipeline(); + create_op_pipeline(); create_shadowmap_image(); create_final_image(); @@ -678,9 +689,73 @@ create_postprocess_pipeline :: () { } +create_op_pipeline :: () { + platconf := get_plat_conf(); + pipeline: sg_pipeline_desc; + shader_desc := op_shader_desc(sg_query_backend()); + pipeline.shader = sg_make_shader(*shader_desc); + + pipeline.layout.attrs[ATTR_op_position] = .{ format = .FLOAT2 }; + pipeline.layout.attrs[ATTR_op_uv] = .{ format = .FLOAT2 }; + pipeline.index_type = .UINT16; + + color_state := sg_color_target_state.{ + blend = .{ + enabled = true, + src_factor_rgb = .SRC_ALPHA, + dst_factor_rgb = .ONE_MINUS_SRC_ALPHA + } + }; + pipeline.depth = .{ + write_enabled = true, + compare = .LESS_EQUAL, + pixel_format = .DEPTH + }; + + pipeline.color_count = 1; + pipeline.colors[0] = color_state; + + gPipelines.op.pipeline = sg_make_pipeline(*pipeline); + + quad_vertices : [16]float = .[ + -1.0, 1.0, 0.0, flip_if_plat(1.0), // top-let + -1.0, -1.0, 0.0, flip_if_plat(0.0), // bottom-let + 1.0, -1.0, 1.0, flip_if_plat(0.0), // bottom-right + 1.0, 1.0, 1.0, flip_if_plat(1.0), // top-right + ]; + quad_indices : [6]u16 = .[ + 0, 1, 2, 0, 2, 3 + ]; + + vbuffer := sg_buffer_desc.{ size = size_of(float) * 16, data = .{ + ptr = quad_vertices.data, + size = 16 * 4 + }}; + ibuffer := sg_buffer_desc.{ size = size_of(u16) * 6, data = .{ + ptr = quad_indices.data, + size = 6 * 2 + }, + type = .INDEXBUFFER, + }; + + gPipelines.op.bind.vertex_buffers[0] = sg_make_buffer(*vbuffer); + gPipelines.op.bind.index_buffer = sg_make_buffer(*ibuffer); + gPipelines.op.bind.samplers[0] = sg_make_sampler(*(sg_sampler_desc.{ + wrap_u = .CLAMP_TO_EDGE, + wrap_v = .CLAMP_TO_EDGE, + min_filter = .NEAREST, + mag_filter = .NEAREST, + })); + +} + create_ssao_images :: () { if g_ssaobuf.id != INVALID_ID then sg_destroy_image(g_ssaobuf); if g_ssaobuf_depth.id != INVALID_ID then sg_destroy_image(g_ssaobuf_depth); + if g_postprocess_a.id != INVALID_ID then sg_destroy_image(g_postprocess_a); + if g_postprocess_a_depth.id != INVALID_ID then sg_destroy_image(g_postprocess_a_depth); + if g_postprocess_b.id != INVALID_ID then sg_destroy_image(g_postprocess_b); + if g_postprocess_b_depth.id != INVALID_ID then sg_destroy_image(g_postprocess_b_depth); w,h := get_render_size(); img_desc := sg_image_desc.{ width = w, @@ -689,6 +764,8 @@ create_ssao_images :: () { }; img_desc.sample_count = 1; g_ssaobuf = sg_make_image(*img_desc); + g_postprocess_a = sg_make_image(*img_desc); + g_postprocess_b = sg_make_image(*img_desc); img_desc = sg_image_desc.{ width = w, height = h, @@ -697,13 +774,28 @@ create_ssao_images :: () { }; img_desc.sample_count = 1; g_ssaobuf_depth = sg_make_image(*img_desc); - + g_postprocess_a_depth = sg_make_image(*img_desc); + g_postprocess_b_depth = sg_make_image(*img_desc); + attachmentsDesc := sg_attachments_desc.{ colors[0].image = g_ssaobuf, depth_stencil.image = g_ssaobuf_depth }; sg_destroy_attachments(g_ssao_attachments); g_ssao_attachments = sg_make_attachments(*attachmentsDesc); + + attachmentsDescA := sg_attachments_desc.{ + colors[0].image = g_postprocess_a, + depth_stencil.image = g_postprocess_a_depth + }; + attachmentsDescB := sg_attachments_desc.{ + colors[0].image = g_postprocess_b, + depth_stencil.image = g_postprocess_b_depth + }; + sg_destroy_attachments(g_postprocess_attach_a); + g_postprocess_attach_a = sg_make_attachments(*attachmentsDescA); + sg_destroy_attachments(g_postprocess_attach_b); + g_postprocess_attach_b = sg_make_attachments(*attachmentsDescB); } create_ssao_pipeline :: () { diff --git a/src/shaders/jai/shader_op.jai b/src/shaders/jai/shader_op.jai new file mode 100644 index 0000000..e35fa4a --- /dev/null +++ b/src/shaders/jai/shader_op.jai @@ -0,0 +1,420 @@ +/* + #version:1# (machine generated, don't edit!) + + Generated by sokol-shdc (https://github.com/floooh/sokol-tools) + + Cmdline: + sokol-shdc -i shader_op.glsl -o ./jai/shader_op.jai -l glsl430:glsl300es:metal_macos -f sokol_jai + + Overview: + ========= + Shader program: 'op': + Get shader desc: op_shader_desc(sg_query_backend()) + Vertex Shader: vs_op + Fragment Shader: fs_op + Attributes: + ATTR_op_position => 0 + ATTR_op_uv => 1 + Bindings: + Image 'optex': + Image type: ._2D + Sample type: .FLOAT + Multisampled: false + Bind slot: IMG_optex => 0 + Sampler 'opsmp': + Type: .FILTERING + Bind slot: SMP_opsmp => 0 +*/ +ATTR_op_position :: 0; +ATTR_op_uv :: 1; +IMG_optex :: 0; +SMP_opsmp :: 0; +/* + #version 430 + + layout(location = 0) in vec2 position; + layout(location = 0) out vec2 texcoord; + layout(location = 1) in vec2 uv; + + void main() + { + gl_Position = vec4(position, 0.5, 1.0); + texcoord = uv; + } + +*/ +vs_op_source_glsl430 := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x6c,0x61, + 0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20, + 0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f,0x73,0x69,0x74, + 0x69,0x6f,0x6e,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61, + 0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f,0x75,0x74,0x20,0x76,0x65, + 0x63,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x3b,0x0a,0x6c,0x61,0x79, + 0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31, + 0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x0a,0x76, + 0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20, + 0x20,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x76, + 0x65,0x63,0x34,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e, + 0x35,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x74,0x65,0x78, + 0x63,0x6f,0x6f,0x72,0x64,0x20,0x3d,0x20,0x75,0x76,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, + +]; +/* + #version 430 + + layout(binding = 16) uniform sampler2D optex_opsmp; + + layout(location = 0) in vec2 texcoord; + layout(location = 0) out vec4 frag_color; + + void main() + { + vec2 _28 = vec2(1.0) / vec2(textureSize(optex_opsmp, 0)); + float result = 0.0; + for (int x = -3; x < 3; x++) + { + for (int y = -3; y < 3; y++) + { + result += texture(optex_opsmp, texcoord + (vec2(float(x), float(y)) * _28)).x; + } + } + float _84 = result * 0.02777777798473834991455078125; + frag_color = vec4(_84, _84, _84, 1.0); + } + +*/ +fs_op_source_glsl430 := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x34,0x33,0x30,0x0a,0x0a,0x6c,0x61, + 0x79,0x6f,0x75,0x74,0x28,0x62,0x69,0x6e,0x64,0x69,0x6e,0x67,0x20,0x3d,0x20,0x31, + 0x36,0x29,0x20,0x75,0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x73,0x61,0x6d,0x70,0x6c, + 0x65,0x72,0x32,0x44,0x20,0x6f,0x70,0x74,0x65,0x78,0x5f,0x6f,0x70,0x73,0x6d,0x70, + 0x3b,0x0a,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69, + 0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20, + 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74, + 0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30,0x29,0x20,0x6f, + 0x75,0x74,0x20,0x76,0x65,0x63,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c, + 0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f,0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29, + 0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x38,0x20, + 0x3d,0x20,0x76,0x65,0x63,0x32,0x28,0x31,0x2e,0x30,0x29,0x20,0x2f,0x20,0x76,0x65, + 0x63,0x32,0x28,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x53,0x69,0x7a,0x65,0x28,0x6f, + 0x70,0x74,0x65,0x78,0x5f,0x6f,0x70,0x73,0x6d,0x70,0x2c,0x20,0x30,0x29,0x29,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6f,0x72, + 0x20,0x28,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x2d,0x33,0x3b,0x20,0x78,0x20, + 0x3c,0x20,0x33,0x3b,0x20,0x78,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x7b,0x0a, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74, + 0x20,0x79,0x20,0x3d,0x20,0x2d,0x33,0x3b,0x20,0x79,0x20,0x3c,0x20,0x33,0x3b,0x20, + 0x79,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65,0x73,0x75,0x6c, + 0x74,0x20,0x2b,0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x28,0x6f,0x70,0x74, + 0x65,0x78,0x5f,0x6f,0x70,0x73,0x6d,0x70,0x2c,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f, + 0x72,0x64,0x20,0x2b,0x20,0x28,0x76,0x65,0x63,0x32,0x28,0x66,0x6c,0x6f,0x61,0x74, + 0x28,0x78,0x29,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x28,0x79,0x29,0x29,0x20,0x2a, + 0x20,0x5f,0x32,0x38,0x29,0x29,0x2e,0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c, + 0x6f,0x61,0x74,0x20,0x5f,0x38,0x34,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74, + 0x20,0x2a,0x20,0x30,0x2e,0x30,0x32,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x39,0x38, + 0x34,0x37,0x33,0x38,0x33,0x34,0x39,0x39,0x31,0x34,0x35,0x35,0x30,0x37,0x38,0x31, + 0x32,0x35,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c, + 0x6f,0x72,0x20,0x3d,0x20,0x76,0x65,0x63,0x34,0x28,0x5f,0x38,0x34,0x2c,0x20,0x5f, + 0x38,0x34,0x2c,0x20,0x5f,0x38,0x34,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x00, +]; +/* + #version 300 es + + layout(location = 0) in vec2 position; + out vec2 texcoord; + layout(location = 1) in vec2 uv; + + void main() + { + gl_Position = vec4(position, 0.5, 1.0); + texcoord = uv; + } + +*/ +vs_op_source_glsl300es := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a, + 0x0a,0x6c,0x61,0x79,0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e, + 0x20,0x3d,0x20,0x30,0x29,0x20,0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x70,0x6f, + 0x73,0x69,0x74,0x69,0x6f,0x6e,0x3b,0x0a,0x6f,0x75,0x74,0x20,0x76,0x65,0x63,0x32, + 0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x3b,0x0a,0x6c,0x61,0x79,0x6f,0x75, + 0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x31,0x29,0x20, + 0x69,0x6e,0x20,0x76,0x65,0x63,0x32,0x20,0x75,0x76,0x3b,0x0a,0x0a,0x76,0x6f,0x69, + 0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x67, + 0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x76,0x65,0x63, + 0x34,0x28,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x35,0x2c, + 0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x74,0x65,0x78,0x63,0x6f, + 0x6f,0x72,0x64,0x20,0x3d,0x20,0x75,0x76,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +]; +/* + #version 300 es + precision mediump float; + precision highp int; + + uniform highp sampler2D optex_opsmp; + + in highp vec2 texcoord; + layout(location = 0) out highp vec4 frag_color; + + void main() + { + highp vec2 _28 = vec2(1.0) / vec2(textureSize(optex_opsmp, 0)); + highp float result = 0.0; + for (int x = -3; x < 3; x++) + { + for (int y = -3; y < 3; y++) + { + result += texture(optex_opsmp, texcoord + (vec2(float(x), float(y)) * _28)).x; + } + } + highp float _84 = result * 0.02777777798473834991455078125; + frag_color = vec4(_84, _84, _84, 1.0); + } + +*/ +fs_op_source_glsl300es := u8.[ + 0x23,0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,0x20,0x33,0x30,0x30,0x20,0x65,0x73,0x0a, + 0x70,0x72,0x65,0x63,0x69,0x73,0x69,0x6f,0x6e,0x20,0x6d,0x65,0x64,0x69,0x75,0x6d, + 0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x3b,0x0a,0x70,0x72,0x65,0x63,0x69,0x73,0x69, + 0x6f,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x69,0x6e,0x74,0x3b,0x0a,0x0a,0x75, + 0x6e,0x69,0x66,0x6f,0x72,0x6d,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x73,0x61,0x6d, + 0x70,0x6c,0x65,0x72,0x32,0x44,0x20,0x6f,0x70,0x74,0x65,0x78,0x5f,0x6f,0x70,0x73, + 0x6d,0x70,0x3b,0x0a,0x0a,0x69,0x6e,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65, + 0x63,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x3b,0x0a,0x6c,0x61,0x79, + 0x6f,0x75,0x74,0x28,0x6c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x20,0x3d,0x20,0x30, + 0x29,0x20,0x6f,0x75,0x74,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x34, + 0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x3b,0x0a,0x0a,0x76,0x6f, + 0x69,0x64,0x20,0x6d,0x61,0x69,0x6e,0x28,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20, + 0x68,0x69,0x67,0x68,0x70,0x20,0x76,0x65,0x63,0x32,0x20,0x5f,0x32,0x38,0x20,0x3d, + 0x20,0x76,0x65,0x63,0x32,0x28,0x31,0x2e,0x30,0x29,0x20,0x2f,0x20,0x76,0x65,0x63, + 0x32,0x28,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x53,0x69,0x7a,0x65,0x28,0x6f,0x70, + 0x74,0x65,0x78,0x5f,0x6f,0x70,0x73,0x6d,0x70,0x2c,0x20,0x30,0x29,0x29,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20, + 0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x2d, + 0x33,0x3b,0x20,0x78,0x20,0x3c,0x20,0x33,0x3b,0x20,0x78,0x2b,0x2b,0x29,0x0a,0x20, + 0x20,0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72, + 0x20,0x28,0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x2d,0x33,0x3b,0x20,0x79,0x20, + 0x3c,0x20,0x33,0x3b,0x20,0x79,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20, + 0x20,0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x74,0x65,0x78,0x74,0x75,0x72, + 0x65,0x28,0x6f,0x70,0x74,0x65,0x78,0x5f,0x6f,0x70,0x73,0x6d,0x70,0x2c,0x20,0x74, + 0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x20,0x2b,0x20,0x28,0x76,0x65,0x63,0x32,0x28, + 0x66,0x6c,0x6f,0x61,0x74,0x28,0x78,0x29,0x2c,0x20,0x66,0x6c,0x6f,0x61,0x74,0x28, + 0x79,0x29,0x29,0x20,0x2a,0x20,0x5f,0x32,0x38,0x29,0x29,0x2e,0x78,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20, + 0x20,0x20,0x20,0x68,0x69,0x67,0x68,0x70,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f, + 0x38,0x34,0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x20,0x30,0x2e, + 0x30,0x32,0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x39,0x38,0x34,0x37,0x33,0x38,0x33, + 0x34,0x39,0x39,0x31,0x34,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20,0x3d,0x20, + 0x76,0x65,0x63,0x34,0x28,0x5f,0x38,0x34,0x2c,0x20,0x5f,0x38,0x34,0x2c,0x20,0x5f, + 0x38,0x34,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x7d,0x0a,0x0a,0x00, +]; +/* + #include + #include + + using namespace metal; + + struct main0_out + { + float2 texcoord [[user(locn0)]]; + float4 gl_Position [[position]]; + }; + + struct main0_in + { + float2 position [[attribute(0)]]; + float2 uv [[attribute(1)]]; + }; + + vertex main0_out main0(main0_in in [[stage_in]]) + { + main0_out out = {}; + out.gl_Position = float4(in.position, 0.5, 1.0); + out.texcoord = in.uv; + return out; + } + +*/ +vs_op_source_metal_macos := u8.[ + 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, + 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, + 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, + 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20, + 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d, + 0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x32,0x20,0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x20,0x5b, + 0x5b,0x75,0x73,0x65,0x72,0x28,0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x20,0x67,0x6c,0x5f,0x50,0x6f, + 0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b,0x5b,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f, + 0x6e,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20, + 0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x32,0x20,0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x20,0x5b, + 0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x30,0x29,0x5d,0x5d,0x3b, + 0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x75,0x76,0x20,0x5b, + 0x5b,0x61,0x74,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x28,0x31,0x29,0x5d,0x5d,0x3b, + 0x0a,0x7d,0x3b,0x0a,0x0a,0x76,0x65,0x72,0x74,0x65,0x78,0x20,0x6d,0x61,0x69,0x6e, + 0x30,0x5f,0x6f,0x75,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e, + 0x30,0x5f,0x69,0x6e,0x20,0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f, + 0x69,0x6e,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e, + 0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x67,0x6c,0x5f,0x50,0x6f,0x73,0x69,0x74, + 0x69,0x6f,0x6e,0x20,0x3d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x69,0x6e,0x2e, + 0x70,0x6f,0x73,0x69,0x74,0x69,0x6f,0x6e,0x2c,0x20,0x30,0x2e,0x35,0x2c,0x20,0x31, + 0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x6f,0x75,0x74,0x2e,0x74,0x65,0x78, + 0x63,0x6f,0x6f,0x72,0x64,0x20,0x3d,0x20,0x69,0x6e,0x2e,0x75,0x76,0x3b,0x0a,0x20, + 0x20,0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d, + 0x0a,0x0a,0x00, +]; +/* + #include + #include + + using namespace metal; + + struct main0_out + { + float4 frag_color [[color(0)]]; + }; + + struct main0_in + { + float2 texcoord [[user(locn0)]]; + }; + + fragment main0_out main0(main0_in in [[stage_in]], texture2d optex [[texture(0)]], sampler opsmp [[sampler(0)]]) + { + main0_out out = {}; + float2 _28 = float2(1.0) / float2(int2(optex.get_width(), optex.get_height())); + float result = 0.0; + for (int x = -3; x < 3; x++) + { + for (int y = -3; y < 3; y++) + { + result += optex.sample(opsmp, (in.texcoord + (float2(float(x), float(y)) * _28))).x; + } + } + float _84 = result * 0.02777777798473834991455078125; + out.frag_color = float4(_84, _84, _84, 1.0); + return out; + } + +*/ +fs_op_source_metal_macos := u8.[ + 0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,0x20,0x3c,0x6d,0x65,0x74,0x61,0x6c,0x5f, + 0x73,0x74,0x64,0x6c,0x69,0x62,0x3e,0x0a,0x23,0x69,0x6e,0x63,0x6c,0x75,0x64,0x65, + 0x20,0x3c,0x73,0x69,0x6d,0x64,0x2f,0x73,0x69,0x6d,0x64,0x2e,0x68,0x3e,0x0a,0x0a, + 0x75,0x73,0x69,0x6e,0x67,0x20,0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,0x20, + 0x6d,0x65,0x74,0x61,0x6c,0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d, + 0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x34,0x20,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72, + 0x20,0x5b,0x5b,0x63,0x6f,0x6c,0x6f,0x72,0x28,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d, + 0x3b,0x0a,0x0a,0x73,0x74,0x72,0x75,0x63,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f, + 0x69,0x6e,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20, + 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x20,0x5b,0x5b,0x75,0x73,0x65,0x72,0x28, + 0x6c,0x6f,0x63,0x6e,0x30,0x29,0x5d,0x5d,0x3b,0x0a,0x7d,0x3b,0x0a,0x0a,0x66,0x72, + 0x61,0x67,0x6d,0x65,0x6e,0x74,0x20,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x6f,0x75,0x74, + 0x20,0x6d,0x61,0x69,0x6e,0x30,0x28,0x6d,0x61,0x69,0x6e,0x30,0x5f,0x69,0x6e,0x20, + 0x69,0x6e,0x20,0x5b,0x5b,0x73,0x74,0x61,0x67,0x65,0x5f,0x69,0x6e,0x5d,0x5d,0x2c, + 0x20,0x74,0x65,0x78,0x74,0x75,0x72,0x65,0x32,0x64,0x3c,0x66,0x6c,0x6f,0x61,0x74, + 0x3e,0x20,0x6f,0x70,0x74,0x65,0x78,0x20,0x5b,0x5b,0x74,0x65,0x78,0x74,0x75,0x72, + 0x65,0x28,0x30,0x29,0x5d,0x5d,0x2c,0x20,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x20, + 0x6f,0x70,0x73,0x6d,0x70,0x20,0x5b,0x5b,0x73,0x61,0x6d,0x70,0x6c,0x65,0x72,0x28, + 0x30,0x29,0x5d,0x5d,0x29,0x0a,0x7b,0x0a,0x20,0x20,0x20,0x20,0x6d,0x61,0x69,0x6e, + 0x30,0x5f,0x6f,0x75,0x74,0x20,0x6f,0x75,0x74,0x20,0x3d,0x20,0x7b,0x7d,0x3b,0x0a, + 0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x20,0x5f,0x32,0x38,0x20,0x3d, + 0x20,0x66,0x6c,0x6f,0x61,0x74,0x32,0x28,0x31,0x2e,0x30,0x29,0x20,0x2f,0x20,0x66, + 0x6c,0x6f,0x61,0x74,0x32,0x28,0x69,0x6e,0x74,0x32,0x28,0x6f,0x70,0x74,0x65,0x78, + 0x2e,0x67,0x65,0x74,0x5f,0x77,0x69,0x64,0x74,0x68,0x28,0x29,0x2c,0x20,0x6f,0x70, + 0x74,0x65,0x78,0x2e,0x67,0x65,0x74,0x5f,0x68,0x65,0x69,0x67,0x68,0x74,0x28,0x29, + 0x29,0x29,0x3b,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x72,0x65, + 0x73,0x75,0x6c,0x74,0x20,0x3d,0x20,0x30,0x2e,0x30,0x3b,0x0a,0x20,0x20,0x20,0x20, + 0x66,0x6f,0x72,0x20,0x28,0x69,0x6e,0x74,0x20,0x78,0x20,0x3d,0x20,0x2d,0x33,0x3b, + 0x20,0x78,0x20,0x3c,0x20,0x33,0x3b,0x20,0x78,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20, + 0x20,0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x66,0x6f,0x72,0x20,0x28, + 0x69,0x6e,0x74,0x20,0x79,0x20,0x3d,0x20,0x2d,0x33,0x3b,0x20,0x79,0x20,0x3c,0x20, + 0x33,0x3b,0x20,0x79,0x2b,0x2b,0x29,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + 0x7b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x72,0x65, + 0x73,0x75,0x6c,0x74,0x20,0x2b,0x3d,0x20,0x6f,0x70,0x74,0x65,0x78,0x2e,0x73,0x61, + 0x6d,0x70,0x6c,0x65,0x28,0x6f,0x70,0x73,0x6d,0x70,0x2c,0x20,0x28,0x69,0x6e,0x2e, + 0x74,0x65,0x78,0x63,0x6f,0x6f,0x72,0x64,0x20,0x2b,0x20,0x28,0x66,0x6c,0x6f,0x61, + 0x74,0x32,0x28,0x66,0x6c,0x6f,0x61,0x74,0x28,0x78,0x29,0x2c,0x20,0x66,0x6c,0x6f, + 0x61,0x74,0x28,0x79,0x29,0x29,0x20,0x2a,0x20,0x5f,0x32,0x38,0x29,0x29,0x29,0x2e, + 0x78,0x3b,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x0a,0x20,0x20,0x20, + 0x20,0x7d,0x0a,0x20,0x20,0x20,0x20,0x66,0x6c,0x6f,0x61,0x74,0x20,0x5f,0x38,0x34, + 0x20,0x3d,0x20,0x72,0x65,0x73,0x75,0x6c,0x74,0x20,0x2a,0x20,0x30,0x2e,0x30,0x32, + 0x37,0x37,0x37,0x37,0x37,0x37,0x37,0x39,0x38,0x34,0x37,0x33,0x38,0x33,0x34,0x39, + 0x39,0x31,0x34,0x35,0x35,0x30,0x37,0x38,0x31,0x32,0x35,0x3b,0x0a,0x20,0x20,0x20, + 0x20,0x6f,0x75,0x74,0x2e,0x66,0x72,0x61,0x67,0x5f,0x63,0x6f,0x6c,0x6f,0x72,0x20, + 0x3d,0x20,0x66,0x6c,0x6f,0x61,0x74,0x34,0x28,0x5f,0x38,0x34,0x2c,0x20,0x5f,0x38, + 0x34,0x2c,0x20,0x5f,0x38,0x34,0x2c,0x20,0x31,0x2e,0x30,0x29,0x3b,0x0a,0x20,0x20, + 0x20,0x20,0x72,0x65,0x74,0x75,0x72,0x6e,0x20,0x6f,0x75,0x74,0x3b,0x0a,0x7d,0x0a, + 0x0a,0x00, +]; +op_shader_desc :: (backend: sg_backend) -> sg_shader_desc { + desc: sg_shader_desc; + desc.label = "op_shader"; + if backend == { + case .GLCORE; + desc.vertex_func.source = xx *vs_op_source_glsl430; + desc.vertex_func.entry = "main"; + desc.fragment_func.source = xx *fs_op_source_glsl430; + desc.fragment_func.entry = "main"; + desc.attrs[0].base_type = .FLOAT; + desc.attrs[0].glsl_name = "position"; + desc.attrs[1].base_type = .FLOAT; + desc.attrs[1].glsl_name = "uv"; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + desc.image_sampler_pairs[0].glsl_name = "optex_opsmp"; + case .GLES3; + desc.vertex_func.source = xx *vs_op_source_glsl300es; + desc.vertex_func.entry = "main"; + desc.fragment_func.source = xx *fs_op_source_glsl300es; + desc.fragment_func.entry = "main"; + desc.attrs[0].base_type = .FLOAT; + desc.attrs[0].glsl_name = "position"; + desc.attrs[1].base_type = .FLOAT; + desc.attrs[1].glsl_name = "uv"; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + desc.image_sampler_pairs[0].glsl_name = "optex_opsmp"; + case .METAL_MACOS; + desc.vertex_func.source = xx *vs_op_source_metal_macos; + desc.vertex_func.entry = "main0"; + desc.fragment_func.source = xx *fs_op_source_metal_macos; + desc.fragment_func.entry = "main0"; + desc.attrs[0].base_type = .FLOAT; + desc.attrs[1].base_type = .FLOAT; + desc.images[0].stage = .FRAGMENT; + desc.images[0].multisampled = false; + desc.images[0].image_type = ._2D; + desc.images[0].sample_type = .FLOAT; + desc.images[0].msl_texture_n = 0; + desc.samplers[0].stage = .FRAGMENT; + desc.samplers[0].sampler_type = .FILTERING; + desc.samplers[0].msl_sampler_n = 0; + desc.image_sampler_pairs[0].stage = .FRAGMENT; + desc.image_sampler_pairs[0].image_slot = 0; + desc.image_sampler_pairs[0].sampler_slot = 0; + } + return desc; +} diff --git a/src/shaders/shader_op.glsl b/src/shaders/shader_op.glsl new file mode 100644 index 0000000..5368138 --- /dev/null +++ b/src/shaders/shader_op.glsl @@ -0,0 +1,35 @@ +@vs vs_op +in vec2 position; +in vec2 uv; + +out vec2 texcoord; + +void main() { + gl_Position = vec4(position, 0.5, 1.0); + texcoord = uv; +} +@end + +@fs fs_op +in vec2 texcoord; +out vec4 frag_color; + +layout(binding = 0) uniform texture2D optex; +layout(binding = 0) uniform sampler opsmp; + +void main() { + vec2 texelSize = 1.0 / vec2(textureSize(sampler2D(optex, opsmp), 0)); + float result = 0.0; + for (int x = -2; x < 2; ++x) + { + for (int y = -2; y < 2; ++y) + { + vec2 offset = vec2(float(x), float(y)) * texelSize; + result += texture(sampler2D(optex, opsmp), texcoord + offset).r; + } + } + frag_color = vec4(vec3(result / (4.0 * 4.0)), 1.0); +} +@end + +@program op vs_op fs_op