diff options
author | Juan Linietsky <reduzio@gmail.com> | 2020-04-11 23:38:05 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-11 23:38:05 -0300 |
commit | 9dc19f7619633dc55bcebc4270d54fddc03bc97f (patch) | |
tree | f500648fe3d7a2e2b0cf1b2e0859f143e4430294 /servers/rendering/rasterizer_rd/shaders | |
parent | 636d4bad99db3293cb3b7ac13b7f7e3c69a83296 (diff) | |
parent | d81911490b447541b21305c16d27b078c184f9fe (diff) |
Merge pull request #37808 from reduz/port-effects-to-compute
Moved most of the effect code to compute.
Diffstat (limited to 'servers/rendering/rasterizer_rd/shaders')
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/SCsub | 5 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/blur.glsl | 301 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/blur_inc.glsl | 35 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/copy.glsl | 239 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl | 68 | ||||
-rw-r--r-- | servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl | 72 |
6 files changed, 329 insertions, 391 deletions
diff --git a/servers/rendering/rasterizer_rd/shaders/SCsub b/servers/rendering/rasterizer_rd/shaders/SCsub index 04a43e3251..a454d144aa 100644 --- a/servers/rendering/rasterizer_rd/shaders/SCsub +++ b/servers/rendering/rasterizer_rd/shaders/SCsub @@ -5,14 +5,15 @@ Import("env") if "RD_GLSL" in env["BUILDERS"]: env.RD_GLSL("canvas.glsl") env.RD_GLSL("canvas_occlusion.glsl") - env.RD_GLSL("blur.glsl") + env.RD_GLSL("copy.glsl") + env.RD_GLSL("copy_to_fb.glsl") env.RD_GLSL("cubemap_roughness.glsl") env.RD_GLSL("cubemap_downsampler.glsl") env.RD_GLSL("cubemap_filter.glsl") env.RD_GLSL("scene_high_end.glsl") env.RD_GLSL("sky.glsl") env.RD_GLSL("tonemap.glsl") - env.RD_GLSL("copy.glsl") + env.RD_GLSL("cube_to_dp.glsl") env.RD_GLSL("giprobe.glsl") env.RD_GLSL("giprobe_debug.glsl") env.RD_GLSL("giprobe_sdf.glsl") diff --git a/servers/rendering/rasterizer_rd/shaders/blur.glsl b/servers/rendering/rasterizer_rd/shaders/blur.glsl deleted file mode 100644 index 5dfdc614a4..0000000000 --- a/servers/rendering/rasterizer_rd/shaders/blur.glsl +++ /dev/null @@ -1,301 +0,0 @@ -/* clang-format off */ -[vertex] - -#version 450 - -VERSION_DEFINES - -#include "blur_inc.glsl" - -layout(location = 0) out vec2 uv_interp; -/* clang-format on */ - -void main() { - - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; - - if (bool(blur.flags & FLAG_USE_BLUR_SECTION)) { - uv_interp = blur.section.xy + uv_interp * blur.section.zw; - } - - gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); - - if (bool(blur.flags & FLAG_FLIP_Y)) { - uv_interp.y = 1.0 - uv_interp.y; - } -} - -/* clang-format off */ -[fragment] - -#version 450 - -VERSION_DEFINES - -#include "blur_inc.glsl" - -layout(location = 0) in vec2 uv_interp; -/* clang-format on */ - -layout(set = 0, binding = 0) uniform sampler2D source_color; - -#ifdef MODE_SSAO_MERGE -layout(set = 1, binding = 0) uniform sampler2D source_ssao; -#endif - -#ifdef GLOW_USE_AUTO_EXPOSURE -layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; -#endif - -layout(location = 0) out vec4 frag_color; - -//DOF -#if defined(MODE_DOF_FAR_BLUR) || defined(MODE_DOF_NEAR_BLUR) - -layout(set = 1, binding = 0) uniform sampler2D dof_source_depth; - -#ifdef DOF_NEAR_BLUR_MERGE -layout(set = 2, binding = 0) uniform sampler2D source_dof_original; -#endif - -#ifdef DOF_QUALITY_LOW -const int dof_kernel_size = 5; -const int dof_kernel_from = 2; -const float dof_kernel[5] = float[](0.153388, 0.221461, 0.250301, 0.221461, 0.153388); -#endif - -#ifdef DOF_QUALITY_MEDIUM -const int dof_kernel_size = 11; -const int dof_kernel_from = 5; -const float dof_kernel[11] = float[](0.055037, 0.072806, 0.090506, 0.105726, 0.116061, 0.119726, 0.116061, 0.105726, 0.090506, 0.072806, 0.055037); - -#endif - -#ifdef DOF_QUALITY_HIGH -const int dof_kernel_size = 21; -const int dof_kernel_from = 10; -const float dof_kernel[21] = float[](0.028174, 0.032676, 0.037311, 0.041944, 0.046421, 0.050582, 0.054261, 0.057307, 0.059587, 0.060998, 0.061476, 0.060998, 0.059587, 0.057307, 0.054261, 0.050582, 0.046421, 0.041944, 0.037311, 0.032676, 0.028174); -#endif - -#endif - -void main() { - -#ifdef MODE_MIPMAP - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(-0.5, -0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(0.5, -0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(0.5, 0.5) * pix_size); - color += texture(source_color, uv_interp + vec2(-0.5, 0.5) * pix_size); - frag_color = color / 4.0; - -#endif - -#ifdef MODE_GAUSSIAN_BLUR - - //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect - - if (bool(blur.flags & FLAG_HORIZONTAL)) { - - vec2 pix_size = blur.pixel_size; - pix_size *= 0.5; //reading from larger buffer, so use more samples - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.214607; - color += texture(source_color, uv_interp + vec2(1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(3.0, 0.0) * pix_size) * 0.071303; - color += texture(source_color, uv_interp + vec2(-1.0, 0.0) * pix_size) * 0.189879; - color += texture(source_color, uv_interp + vec2(-2.0, 0.0) * pix_size) * 0.131514; - color += texture(source_color, uv_interp + vec2(-3.0, 0.0) * pix_size) * 0.071303; - frag_color = color; - } else { - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.38774; - color += texture(source_color, uv_interp + vec2(0.0, 1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, 2.0) * pix_size) * 0.06136; - color += texture(source_color, uv_interp + vec2(0.0, -1.0) * pix_size) * 0.24477; - color += texture(source_color, uv_interp + vec2(0.0, -2.0) * pix_size) * 0.06136; - frag_color = color; - } -#endif - -#ifdef MODE_GAUSSIAN_GLOW - - //Glow uses larger sigma 1 for a more rounded blur effect - -#define GLOW_ADD(m_ofs, m_mult) \ - { \ - vec2 ofs = uv_interp + m_ofs * pix_size; \ - vec4 c = texture(source_color, ofs) * m_mult; \ - if (any(lessThan(ofs, vec2(0.0))) || any(greaterThan(ofs, vec2(1.0)))) { \ - c *= 0.0; \ - } \ - color += c; \ - } - - if (bool(blur.flags & FLAG_HORIZONTAL)) { - - vec2 pix_size = blur.pixel_size; - pix_size *= 0.5; //reading from larger buffer, so use more samples - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.174938; - GLOW_ADD(vec2(1.0, 0.0), 0.165569); - GLOW_ADD(vec2(2.0, 0.0), 0.140367); - GLOW_ADD(vec2(3.0, 0.0), 0.106595); - GLOW_ADD(vec2(-1.0, 0.0), 0.165569); - GLOW_ADD(vec2(-2.0, 0.0), 0.140367); - GLOW_ADD(vec2(-3.0, 0.0), 0.106595); - color *= blur.glow_strength; - frag_color = color; - } else { - - vec2 pix_size = blur.pixel_size; - vec4 color = texture(source_color, uv_interp + vec2(0.0, 0.0) * pix_size) * 0.288713; - GLOW_ADD(vec2(0.0, 1.0), 0.233062); - GLOW_ADD(vec2(0.0, 2.0), 0.122581); - GLOW_ADD(vec2(0.0, -1.0), 0.233062); - GLOW_ADD(vec2(0.0, -2.0), 0.122581); - color *= blur.glow_strength; - frag_color = color; - } - -#undef GLOW_ADD - - if (bool(blur.flags & FLAG_GLOW_FIRST_PASS)) { -#ifdef GLOW_USE_AUTO_EXPOSURE - - frag_color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / blur.glow_auto_exposure_grey; -#endif - frag_color *= blur.glow_exposure; - - float luminance = max(frag_color.r, max(frag_color.g, frag_color.b)); - float feedback = max(smoothstep(blur.glow_hdr_threshold, blur.glow_hdr_threshold + blur.glow_hdr_scale, luminance), blur.glow_bloom); - - frag_color = min(frag_color * feedback, vec4(blur.glow_luminance_cap)); - } - -#endif - -#ifdef MODE_DOF_FAR_BLUR - - vec4 color_accum = vec4(0.0); - - float depth = texture(dof_source_depth, uv_interp, 0.0).r; - depth = depth * 2.0 - 1.0; - - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - depth = ((depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); - } - - float amount = smoothstep(blur.dof_begin, blur.dof_end, depth); - float k_accum = 0.0; - - for (int i = 0; i < dof_kernel_size; i++) { - - int int_ofs = i - dof_kernel_from; - vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * amount * blur.dof_radius; - - float tap_k = dof_kernel[i]; - - float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; - tap_depth = tap_depth * 2.0 - 1.0; - - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - - tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); - } - - float tap_amount = mix(smoothstep(blur.dof_begin, blur.dof_end, tap_depth), 1.0, int_ofs == 0); - tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect - - vec4 tap_color = texture(source_color, tap_uv, 0.0) * tap_k; - - k_accum += tap_k * tap_amount; - color_accum += tap_color * tap_amount; - } - - if (k_accum > 0.0) { - color_accum /= k_accum; - } - - frag_color = color_accum; ///k_accum; - -#endif - -#ifdef MODE_DOF_NEAR_BLUR - - vec4 color_accum = vec4(0.0); - - float max_accum = 0.0; - - for (int i = 0; i < dof_kernel_size; i++) { - - int int_ofs = i - dof_kernel_from; - vec2 tap_uv = uv_interp + blur.dof_dir * float(int_ofs) * blur.dof_radius; - float ofs_influence = max(0.0, 1.0 - float(abs(int_ofs)) / float(dof_kernel_from)); - - float tap_k = dof_kernel[i]; - - vec4 tap_color = texture(source_color, tap_uv, 0.0); - - float tap_depth = texture(dof_source_depth, tap_uv, 0.0).r; - tap_depth = tap_depth * 2.0 - 1.0; - if (bool(blur.flags & FLAG_USE_ORTHOGONAL_PROJECTION)) { - - tap_depth = ((tap_depth + (blur.camera_z_far + blur.camera_z_near) / (blur.camera_z_far - blur.camera_z_near)) * (blur.camera_z_far - blur.camera_z_near)) / 2.0; - } else { - tap_depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - tap_depth * (blur.camera_z_far - blur.camera_z_near)); - } - float tap_amount = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth); - tap_amount *= tap_amount * tap_amount; //prevent undesired glow effect - - if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) { - tap_color.a = 1.0 - smoothstep(blur.dof_end, blur.dof_begin, tap_depth); - } - - max_accum = max(max_accum, tap_amount * ofs_influence); - - color_accum += tap_color * tap_k; - } - - color_accum.a = max(color_accum.a, sqrt(max_accum)); - -#ifdef DOF_NEAR_BLUR_MERGE - { - vec4 original = texture(source_dof_original, uv_interp, 0.0); - color_accum = mix(original, color_accum, color_accum.a); - } -#endif - - if (bool(blur.flags & FLAG_DOF_NEAR_FIRST_TAP)) { - frag_color = color_accum; - } -#endif - -#ifdef MODE_SIMPLE_COPY - vec4 color = texture(source_color, uv_interp, 0.0); - if (bool(blur.flags & FLAG_COPY_FORCE_LUMINANCE)) { - color.rgb = vec3(max(max(color.r, color.g), color.b)); - } - frag_color = color; -#endif - -#ifdef MODE_LINEARIZE_DEPTH_COPY - float depth = texture(source_color, uv_interp, 0.0).r; - depth = depth * 2.0 - 1.0; - depth = 2.0 * blur.camera_z_near * blur.camera_z_far / (blur.camera_z_far + blur.camera_z_near - depth * (blur.camera_z_far - blur.camera_z_near)); - frag_color = vec4(depth / blur.camera_z_far); -#endif - -#ifdef MODE_SSAO_MERGE - vec4 color = texture(source_color, uv_interp, 0.0); - float ssao = texture(source_ssao, uv_interp, 0.0).r; - frag_color = vec4(mix(color.rgb, color.rgb * mix(blur.ssao_color.rgb, vec3(1.0), ssao), color.a), 1.0); - -#endif -} diff --git a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl b/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl deleted file mode 100644 index 33ba9de7bb..0000000000 --- a/servers/rendering/rasterizer_rd/shaders/blur_inc.glsl +++ /dev/null @@ -1,35 +0,0 @@ -#define FLAG_HORIZONTAL (1 << 0) -#define FLAG_USE_BLUR_SECTION (1 << 1) -#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2) -#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3) -#define FLAG_GLOW_FIRST_PASS (1 << 4) -#define FLAG_FLIP_Y (1 << 5) -#define FLAG_COPY_FORCE_LUMINANCE (1 << 6) - -layout(push_constant, binding = 1, std430) uniform Blur { - vec4 section; - vec2 pixel_size; - uint flags; - uint pad; - // Glow. - float glow_strength; - float glow_bloom; - float glow_hdr_threshold; - float glow_hdr_scale; - float glow_exposure; - float glow_white; - float glow_luminance_cap; - float glow_auto_exposure_grey; - // DOF. - float dof_begin; - float dof_end; - float dof_radius; - float dof_pad; - - vec2 dof_dir; - float camera_z_far; - float camera_z_near; - - vec4 ssao_color; -} -blur; diff --git a/servers/rendering/rasterizer_rd/shaders/copy.glsl b/servers/rendering/rasterizer_rd/shaders/copy.glsl index 2b541f2660..48c49ff7de 100644 --- a/servers/rendering/rasterizer_rd/shaders/copy.glsl +++ b/servers/rendering/rasterizer_rd/shaders/copy.glsl @@ -1,87 +1,220 @@ /* clang-format off */ -[vertex] +[compute] #version 450 VERSION_DEFINES -layout(location = 0) out vec2 uv_interp; +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; /* clang-format on */ -void main() { +#define FLAG_HORIZONTAL (1 << 0) +#define FLAG_USE_BLUR_SECTION (1 << 1) +#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2) +#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3) +#define FLAG_GLOW_FIRST_PASS (1 << 4) +#define FLAG_FLIP_Y (1 << 5) +#define FLAG_FORCE_LUMINANCE (1 << 6) +#define FLAG_COPY_ALL_SOURCE (1 << 7) + +layout(push_constant, binding = 1, std430) uniform Params { + ivec4 section; + ivec2 target; + uint flags; + uint pad; + // Glow. + float glow_strength; + float glow_bloom; + float glow_hdr_threshold; + float glow_hdr_scale; + + float glow_exposure; + float glow_white; + float glow_luminance_cap; + float glow_auto_exposure_grey; + // DOF. + float camera_z_far; + float camera_z_near; + uvec2 pad2; +} +params; - vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); - uv_interp = base_arr[gl_VertexIndex]; +layout(set = 0, binding = 0) uniform sampler2D source_color; - gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); -} +#ifdef GLOW_USE_AUTO_EXPOSURE +layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure; +#endif -/* clang-format off */ -[fragment] +#if defined(MODE_LINEARIZE_DEPTH_COPY) || defined(MODE_SIMPLE_COPY_DEPTH) +layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#elif defined(DST_IMAGE_8BIT) +layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#else +layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer; +#endif -#version 450 +void main() { -VERSION_DEFINES + // Pixel being shaded + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing + return; + } -layout(location = 0) in vec2 uv_interp; -/* clang-format on */ +#ifdef MODE_MIPMAP -#ifdef MODE_CUBE_TO_DP + ivec2 base_pos = (pos + params.section.xy) << 1; + vec4 color = texelFetch(source_color, base_pos, 0); + color += texelFetch(source_color, base_pos + ivec2(0, 1), 0); + color += texelFetch(source_color, base_pos + ivec2(1, 0), 0); + color += texelFetch(source_color, base_pos + ivec2(1, 1), 0); + color /= 4.0; -layout(set = 0, binding = 0) uniform samplerCube source_cube; + imageStore(dest_buffer, pos + params.target, color); +#endif -layout(push_constant, binding = 0, std430) uniform Params { - float bias; - float z_far; - float z_near; - bool z_flip; -} -params; +#ifdef MODE_GAUSSIAN_BLUR + + //Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect -layout(location = 0) out float depth_buffer; + if (bool(params.flags & FLAG_HORIZONTAL)) { + + ivec2 base_pos = (pos + params.section.xy) << 1; + vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607; + color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879; + color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514; + color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303; + color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879; + color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514; + color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303; + imageStore(dest_buffer, pos + params.target, color); + } else { + ivec2 base_pos = (pos + params.section.xy); + vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774; + color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477; + color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136; + color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477; + color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136; + imageStore(dest_buffer, pos + params.target, color); + } #endif -void main() { +#ifdef MODE_GAUSSIAN_GLOW -#ifdef MODE_CUBE_TO_DP + //Glow uses larger sigma 1 for a more rounded blur effect - vec3 normal = vec3(uv_interp * 2.0 - 1.0, 0.0); +#define GLOW_ADD(m_ofs, m_mult) \ + { \ + ivec2 ofs = base_pos + m_ofs; \ + if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \ + color += texelFetch(source_color, ofs, 0) * m_mult; \ + } \ + } - normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); - normal = normalize(normal); + vec4 color = vec4(0.0); - normal.y = -normal.y; //needs to be flipped to match projection matrix - if (!params.z_flip) { - normal.z = -normal.z; + if (bool(params.flags & FLAG_HORIZONTAL)) { + + ivec2 base_pos = (pos + params.section.xy) << 1; + ivec2 section_begin = params.section.xy << 1; + ivec2 section_end = section_begin + (params.section.zw << 1); + + GLOW_ADD(ivec2(0, 0), 0.174938); + GLOW_ADD(ivec2(1, 0), 0.165569); + GLOW_ADD(ivec2(2, 0), 0.140367); + GLOW_ADD(ivec2(3, 0), 0.106595); + GLOW_ADD(ivec2(-1, 0), 0.165569); + GLOW_ADD(ivec2(-2, 0), 0.140367); + GLOW_ADD(ivec2(-3, 0), 0.106595); + color *= params.glow_strength; + } else { + + ivec2 base_pos = pos + params.section.xy; + ivec2 section_begin = params.section.xy; + ivec2 section_end = section_begin + params.section.zw; + + GLOW_ADD(ivec2(0, 0), 0.288713); + GLOW_ADD(ivec2(0, 1), 0.233062); + GLOW_ADD(ivec2(0, 2), 0.122581); + GLOW_ADD(ivec2(0, -1), 0.233062); + GLOW_ADD(ivec2(0, -2), 0.122581); + color *= params.glow_strength; } - float depth = texture(source_cube, normal).r; - depth_buffer = depth; - - // absolute values for direction cosines, bigger value equals closer to basis axis - vec3 unorm = abs(normal); - - if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { - // x code - unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0); - } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { - // y code - unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0); - } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { - // z code - unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0); +#undef GLOW_ADD + + if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { +#ifdef GLOW_USE_AUTO_EXPOSURE + + color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.glow_auto_exposure_grey; +#endif + color *= params.glow_exposure; + + float luminance = max(color.r, max(color.g, color.b)); + float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom); + + color = min(color * feedback, vec4(params.glow_luminance_cap)); + } + + imageStore(dest_buffer, pos + params.target, color); + +#endif + +#ifdef MODE_SIMPLE_COPY + + vec4 color; + if (bool(params.flags & FLAG_COPY_ALL_SOURCE)) { + vec2 uv = vec2(pos) / vec2(params.section.zw); + if (bool(params.flags & FLAG_FLIP_Y)) { + uv.y = 1.0 - uv.y; + } + color = textureLod(source_color, uv, 0.0); + + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + imageStore(dest_buffer, pos + params.target, color); + } else { - // oh-no we messed up code - // has to be - unorm = vec3(1.0, 0.0, 0.0); + color = texelFetch(source_color, pos + params.section.xy, 0); + + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; + } + + imageStore(dest_buffer, pos + params.target, color); } - float depth_fix = 1.0 / dot(normal, unorm); +#endif + +#ifdef MODE_SIMPLE_COPY_DEPTH + + vec4 color = texelFetch(source_color, pos + params.section.xy, 0); + + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; + } - depth = 2.0 * depth - 1.0; - float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); - depth_buffer = (linear_depth * depth_fix) / params.z_far; + imageStore(dest_buffer, pos + params.target, vec4(color.r)); + +#endif + +#ifdef MODE_LINEARIZE_DEPTH_COPY + + float depth = texelFetch(source_color, pos + params.section.xy, 0).r; + depth = depth * 2.0 - 1.0; + depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near)); + vec4 color = vec4(depth / params.camera_z_far); + + if (bool(params.flags & FLAG_FLIP_Y)) { + pos.y = params.section.w - pos.y - 1; + } + imageStore(dest_buffer, pos + params.target, color); #endif } diff --git a/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl new file mode 100644 index 0000000000..1f499cf372 --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl @@ -0,0 +1,68 @@ +/* clang-format off */ +[vertex] + +#version 450 + +VERSION_DEFINES + +layout(location = 0) out vec2 uv_interp; +/* clang-format on */ + +layout(push_constant, binding = 1, std430) uniform Params { + vec4 section; + vec2 pixel_size; + bool flip_y; + bool use_section; + bool force_luminance; + uint pad[3]; +} +params; + +void main() { + + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); + uv_interp = base_arr[gl_VertexIndex]; + + if (params.use_section) { + uv_interp = params.section.xy + uv_interp * params.section.zw; + } + + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); + + if (params.flip_y) { + uv_interp.y = 1.0 - uv_interp.y; + } +} + +/* clang-format off */ +[fragment] + +#version 450 + +VERSION_DEFINES + +layout(push_constant, binding = 1, std430) uniform Params { + vec4 section; + vec2 pixel_size; + bool flip_y; + bool use_section; + bool force_luminance; + uint pad[3]; +} params; + + +layout(location = 0) in vec2 uv_interp; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform sampler2D source_color; + +layout(location = 0) out vec4 frag_color; + +void main() { + + vec4 color = texture(source_color, uv_interp, 0.0); + if (params.force_luminance) { + color.rgb = vec3(max(max(color.r, color.g), color.b)); + } + frag_color = color; +} diff --git a/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl new file mode 100644 index 0000000000..02ebe1a53b --- /dev/null +++ b/servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl @@ -0,0 +1,72 @@ +/* clang-format off */ +[compute] + +#version 450 + +VERSION_DEFINES + +layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; +/* clang-format on */ + +layout(set = 0, binding = 0) uniform samplerCube source_cube; + +layout(push_constant, binding = 1, std430) uniform Params { + ivec2 screen_size; + ivec2 offset; + float bias; + float z_far; + float z_near; + bool z_flip; +} +params; + +layout(r32f, set = 1, binding = 0) uniform restrict writeonly image2D depth_buffer; + +void main() { + + ivec2 pos = ivec2(gl_GlobalInvocationID.xy); + if (any(greaterThan(pos, params.screen_size))) { //too large, do nothing + return; + } + + vec2 pixel_size = 1.0 / vec2(params.screen_size); + vec2 uv = (vec2(pos) + 0.5) * pixel_size; + + vec3 normal = vec3(uv * 2.0 - 1.0, 0.0); + + normal.z = 0.5 - 0.5 * ((normal.x * normal.x) + (normal.y * normal.y)); + normal = normalize(normal); + + normal.y = -normal.y; //needs to be flipped to match projection matrix + if (!params.z_flip) { + normal.z = -normal.z; + } + + float depth = texture(source_cube, normal).r; + + // absolute values for direction cosines, bigger value equals closer to basis axis + vec3 unorm = abs(normal); + + if ((unorm.x >= unorm.y) && (unorm.x >= unorm.z)) { + // x code + unorm = normal.x > 0.0 ? vec3(1.0, 0.0, 0.0) : vec3(-1.0, 0.0, 0.0); + } else if ((unorm.y > unorm.x) && (unorm.y >= unorm.z)) { + // y code + unorm = normal.y > 0.0 ? vec3(0.0, 1.0, 0.0) : vec3(0.0, -1.0, 0.0); + } else if ((unorm.z > unorm.x) && (unorm.z > unorm.y)) { + // z code + unorm = normal.z > 0.0 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 0.0, -1.0); + } else { + // oh-no we messed up code + // has to be + unorm = vec3(1.0, 0.0, 0.0); + } + + float depth_fix = 1.0 / dot(normal, unorm); + + depth = 2.0 * depth - 1.0; + float linear_depth = 2.0 * params.z_near * params.z_far / (params.z_far + params.z_near - depth * (params.z_far - params.z_near)); + depth = (linear_depth * depth_fix) / params.z_far; + + imageStore(depth_buffer, pos + params.offset, vec4(depth)); +} |