You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-13 13:31:48 +00:00
Merge pull request #37808 from reduz/port-effects-to-compute
Moved most of the effect code to compute.
This commit is contained in:
@@ -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")
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
|
||||
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(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;
|
||||
|
||||
gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
[fragment]
|
||||
|
||||
#version 450
|
||||
|
||||
VERSION_DEFINES
|
||||
|
||||
layout(location = 0) in vec2 uv_interp;
|
||||
/* clang-format on */
|
||||
|
||||
#ifdef MODE_CUBE_TO_DP
|
||||
|
||||
layout(set = 0, binding = 0) uniform samplerCube source_cube;
|
||||
|
||||
layout(push_constant, binding = 0, std430) uniform Params {
|
||||
float bias;
|
||||
float z_far;
|
||||
float z_near;
|
||||
bool z_flip;
|
||||
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;
|
||||
|
||||
layout(location = 0) out float depth_buffer;
|
||||
layout(set = 0, binding = 0) uniform sampler2D source_color;
|
||||
|
||||
#ifdef GLOW_USE_AUTO_EXPOSURE
|
||||
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef MODE_CUBE_TO_DP
|
||||
|
||||
vec3 normal = vec3(uv_interp * 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;
|
||||
// Pixel being shaded
|
||||
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
||||
if (any(greaterThan(pos, params.section.zw))) { //too large, do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
float depth = texture(source_cube, normal).r;
|
||||
depth_buffer = depth;
|
||||
#ifdef MODE_MIPMAP
|
||||
|
||||
// absolute values for direction cosines, bigger value equals closer to basis axis
|
||||
vec3 unorm = abs(normal);
|
||||
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;
|
||||
|
||||
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);
|
||||
imageStore(dest_buffer, pos + params.target, color);
|
||||
#endif
|
||||
|
||||
#ifdef MODE_GAUSSIAN_BLUR
|
||||
|
||||
//Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
|
||||
|
||||
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 {
|
||||
// oh-no we messed up code
|
||||
// has to be
|
||||
unorm = vec3(1.0, 0.0, 0.0);
|
||||
|
||||
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
|
||||
|
||||
#ifdef MODE_GAUSSIAN_GLOW
|
||||
|
||||
//Glow uses larger sigma 1 for a more rounded blur effect
|
||||
|
||||
#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; \
|
||||
} \
|
||||
}
|
||||
|
||||
float depth_fix = 1.0 / dot(normal, unorm);
|
||||
vec4 color = vec4(0.0);
|
||||
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
#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 {
|
||||
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);
|
||||
}
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
68
servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
Normal file
68
servers/rendering/rasterizer_rd/shaders/copy_to_fb.glsl
Normal file
@@ -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;
|
||||
}
|
||||
72
servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
Normal file
72
servers/rendering/rasterizer_rd/shaders/cube_to_dp.glsl
Normal file
@@ -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));
|
||||
}
|
||||
Reference in New Issue
Block a user