diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
36 files changed, 452 insertions, 332 deletions
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index 45dc63aa17..1fb8b28b15 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -191,48 +191,6 @@ void main() { uv += 1e-5; } -#ifdef USE_ATTRIBUTES -#if 0 - if (bool(draw_data.flags & FLAGS_USE_SKELETON) && bone_weights != vec4(0.0)) { //must be a valid bone - //skeleton transform - ivec4 bone_indicesi = ivec4(bone_indices); - - uvec2 tex_ofs = bone_indicesi.x * 2; - - mat2x4 m; - m = mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.x; - - tex_ofs = bone_indicesi.y * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.y; - - tex_ofs = bone_indicesi.z * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.z; - - tex_ofs = bone_indicesi.w * 2; - - m += mat2x4( - texelFetch(skeleton_buffer, tex_ofs + 0), - texelFetch(skeleton_buffer, tex_ofs + 1)) * - bone_weights.w; - - mat4 bone_matrix = skeleton_data.skeleton_transform * transpose(mat4(m[0], m[1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))) * skeleton_data.skeleton_transform_inverse; - - //outvec = bone_matrix * outvec; - } -#endif -#endif - vertex = (canvas_data.canvas_transform * vec4(vertex, 0.0, 1.0)).xy; vertex_interp = vertex; @@ -544,6 +502,12 @@ void main() { if (normal_used || (using_light && bool(draw_data.flags & FLAGS_DEFAULT_NORMAL_MAP_USED))) { normal.xy = texture(sampler2D(normal_texture, texture_sampler), uv).xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); + if (bool(draw_data.flags & FLAGS_FLIP_H)) { + normal.x = -normal.x; + } + if (bool(draw_data.flags & FLAGS_FLIP_V)) { + normal.y = -normal.y; + } normal.z = sqrt(1.0 - dot(normal.xy, normal.xy)); normal_used = true; } else { @@ -598,13 +562,11 @@ void main() { normal = normalize((canvas_data.canvas_normal_transform * vec4(normal, 0.0)).xyz); } - vec3 base_color = color.rgb; + vec4 base_color = color; if (bool(draw_data.flags & FLAGS_USING_LIGHT_MASK)) { color = vec4(0.0); //invisible by default due to using light mask } - vec4 original_color = color; - #ifdef MODE_LIGHT_ONLY color = vec4(0.0); #elif !defined(MODE_UNSHADED) @@ -624,12 +586,14 @@ void main() { #ifdef LIGHT_CODE_USED vec4 shadow_modulate = vec4(1.0); - light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, true); + light_color = light_compute(light_vertex, vec3(direction, light_array.data[light_base].height), normal, light_color, light_color.a, specular_shininess, shadow_modulate, screen_uv, uv, base_color, true); #else if (normal_used) { vec3 light_vec = normalize(mix(vec3(direction, 0.0), vec3(0, 0, 1), light_array.data[light_base].height)); - light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + light_color.rgb = light_normal_compute(light_vec, normal, base_color.rgb, light_color.rgb, specular_shininess, specular_shininess_used); + } else { + light_color.rgb *= base_color.rgb; } #endif @@ -646,8 +610,6 @@ void main() { ); } - light_color.rgb *= original_color.rgb; - light_blend_compute(light_base, light_color, color.rgb); } @@ -657,20 +619,7 @@ void main() { if (i >= light_count) { break; } - uint light_base; - if (i < 8) { - if (i < 4) { - light_base = draw_data.lights[0]; - } else { - light_base = draw_data.lights[1]; - } - } else { - if (i < 12) { - light_base = draw_data.lights[2]; - } else { - light_base = draw_data.lights[3]; - } - } + uint light_base = draw_data.lights[i >> 2]; light_base >>= (i & 3) * 8; light_base &= 0xFF; @@ -685,7 +634,7 @@ void main() { vec3 light_position = vec3(light_array.data[light_base].position, light_array.data[light_base].height); light_color.rgb *= light_base_color.rgb; - light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, color, false); + light_color = light_compute(light_vertex, light_position, normal, light_color, light_base_color.a, specular_shininess, shadow_modulate, screen_uv, uv, base_color, false); #else light_color.rgb *= light_base_color.rgb * light_base_color.a; @@ -695,7 +644,9 @@ void main() { vec3 pos = light_vertex; vec3 light_vec = normalize(light_pos - pos); - light_color.rgb = light_normal_compute(light_vec, normal, base_color, light_color.rgb, specular_shininess, specular_shininess_used); + light_color.rgb = light_normal_compute(light_vec, normal, base_color.rgb, light_color.rgb, specular_shininess, specular_shininess_used); + } else { + light_color.rgb *= base_color.rgb; } #endif if (any(lessThan(tex_uv, vec2(0.0, 0.0))) || any(greaterThanEqual(tex_uv, vec2(1.0, 1.0)))) { @@ -743,8 +694,6 @@ void main() { ); } - light_color.rgb *= original_color.rgb; - light_blend_compute(light_base, light_color, color.rgb); } #endif diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index 1b627a3e81..a904f4e0a6 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -27,6 +27,9 @@ #define FLAGS_USE_MSDF (1 << 28) #define FLAGS_USE_LCD (1 << 29) +#define FLAGS_FLIP_H (1 << 30) +#define FLAGS_FLIP_V (1 << 31) + #define SAMPLER_NEAREST_CLAMP 0 #define SAMPLER_LINEAR_CLAMP 1 #define SAMPLER_NEAREST_WITH_MIPMAPS_CLAMP 2 @@ -134,7 +137,7 @@ layout(set = 0, binding = 4) uniform texture2D shadow_atlas_texture; layout(set = 0, binding = 5) uniform sampler shadow_sampler; -layout(set = 0, binding = 6) uniform texture2D screen_texture; +layout(set = 0, binding = 6) uniform texture2D color_buffer; layout(set = 0, binding = 7) uniform texture2D sdf_texture; layout(set = 0, binding = 8) uniform sampler material_samplers[12]; diff --git a/servers/rendering/renderer_rd/shaders/cluster_render.glsl b/servers/rendering/renderer_rd/shaders/cluster_render.glsl index 2fe230f0bf..8c26a67926 100644 --- a/servers/rendering/renderer_rd/shaders/cluster_render.glsl +++ b/servers/rendering/renderer_rd/shaders/cluster_render.glsl @@ -64,7 +64,7 @@ void main() { #version 450 #VERSION_DEFINES - +#ifndef MOLTENVK_USED // Metal will corrupt GPU state otherwise #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) && defined(has_GL_KHR_shader_subgroup_vote) #extension GL_KHR_shader_subgroup_ballot : enable @@ -73,6 +73,7 @@ void main() { #define USE_SUBGROUPS #endif +#endif layout(location = 0) in float depth_interp; layout(location = 1) in flat uint element_index; @@ -141,7 +142,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[usage_write_offset], usage_write_bit); } #endif @@ -161,7 +166,11 @@ void main() { } } #else - if (!gl_HelperInvocation) { +// MoltenVK/Metal fails to compile shaders using gl_HelperInvocation for some GPUs +#ifndef MOLTENVK_USED + if (!gl_HelperInvocation) +#endif + { atomicOr(cluster_render.data[z_write_offset], z_write_bit); } #endif diff --git a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl index cb06250cf2..31aabbe9d2 100644 --- a/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/blur_raster.glsl @@ -53,30 +53,31 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR - // Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect - - // note, for blur blur.luminance_multiplier is irrelavant, we would be multiplying and then dividing by this amount. - - 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; - } + // For Gaussian Blur we use 13 taps in a single pass instead of 12 taps over 2 passes. + // This minimizes the number of times we change framebuffers which is very important for mobile. + // Source: http://www.iryoku.com/next-generation-post-processing-in-call-of-duty-advanced-warfare + vec4 A = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, -1.0)); + vec4 B = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, -1.0)); + vec4 C = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, -1.0)); + vec4 D = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, -0.5)); + vec4 E = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, -0.5)); + vec4 F = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 0.0)); + vec4 G = texture(source_color, uv_interp); + vec4 H = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 0.0)); + vec4 I = texture(source_color, uv_interp + blur.pixel_size * vec2(-0.5, 0.5)); + vec4 J = texture(source_color, uv_interp + blur.pixel_size * vec2(0.5, 0.5)); + vec4 K = texture(source_color, uv_interp + blur.pixel_size * vec2(-1.0, 1.0)); + vec4 L = texture(source_color, uv_interp + blur.pixel_size * vec2(0.0, 1.0)); + vec4 M = texture(source_color, uv_interp + blur.pixel_size * vec2(1.0, 1.0)); + + float base_weight = 0.5 / 4.0; + float lesser_weight = 0.125 / 4.0; + + frag_color = (D + E + I + J) * base_weight; + frag_color += (A + B + G + F) * lesser_weight; + frag_color += (B + C + H + G) * lesser_weight; + frag_color += (F + G + L + K) * lesser_weight; + frag_color += (G + H + M + L) * lesser_weight; #endif #ifdef MODE_GAUSSIAN_GLOW diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl index bfe329b8ec..3a82861057 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl @@ -14,8 +14,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in; #define FLAG_FLIP_Y (1 << 5) #define FLAG_FORCE_LUMINANCE (1 << 6) #define FLAG_COPY_ALL_SOURCE (1 << 7) -#define FLAG_HIGH_QUALITY_GLOW (1 << 8) -#define FLAG_ALPHA_TO_ONE (1 << 9) +#define FLAG_ALPHA_TO_ONE (1 << 8) layout(push_constant, std430) uniform Params { ivec4 section; @@ -93,25 +92,14 @@ void main() { #ifdef MODE_GAUSSIAN_BLUR // First pass copy texture into 16x16 local memory for every 8x8 thread block - vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); + vec2 quad_center_uv = clamp(vec2(params.section.xy + gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16; -#ifdef MODE_GLOW - if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) { - vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw)); - - local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5; - local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5; - local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5; - local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5; - } else -#endif - { - local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); - local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); - local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); - local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); - } + local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0); + local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0); + local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0); + local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0); + #ifdef MODE_GLOW if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) { // Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html @@ -194,10 +182,10 @@ void main() { color = min(color * feedback, vec4(params.glow_luminance_cap)); } -#endif +#endif // MODE_GLOW imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_GAUSSIAN_BLUR #ifdef MODE_SIMPLE_COPY @@ -227,7 +215,7 @@ void main() { imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_SIMPLE_COPY #ifdef MODE_SIMPLE_COPY_DEPTH @@ -239,7 +227,7 @@ void main() { imageStore(dest_buffer, pos + params.target, vec4(color.r)); -#endif +#endif // MODE_SIMPLE_COPY_DEPTH #ifdef MODE_LINEARIZE_DEPTH_COPY @@ -253,7 +241,7 @@ void main() { } imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // MODE_LINEARIZE_DEPTH_COPY #if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) @@ -276,7 +264,7 @@ void main() { vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne #endif imageStore(dest_buffer, pos + params.target, color); -#endif +#endif // defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA) #ifdef MODE_SET_COLOR imageStore(dest_buffer, pos + params.target, params.set_color); diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl index 1c17eabb56..6137224162 100644 --- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl @@ -13,6 +13,14 @@ #endif // has_VK_KHR_multiview #endif //MULTIVIEW +#define FLAG_FLIP_Y (1 << 0) +#define FLAG_USE_SECTION (1 << 1) +#define FLAG_FORCE_LUMINANCE (1 << 2) +#define FLAG_ALPHA_TO_ZERO (1 << 3) +#define FLAG_SRGB (1 << 4) +#define FLAG_ALPHA_TO_ONE (1 << 5) +#define FLAG_LINEAR (1 << 6) + #ifdef MULTIVIEW layout(location = 0) out vec3 uv_interp; #else @@ -22,11 +30,10 @@ layout(location = 0) out vec2 uv_interp; layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; - bool flip_y; - bool use_section; + float luminance_multiplier; + uint flags; - bool force_luminance; - uint pad[3]; + vec4 color; } params; @@ -37,13 +44,13 @@ void main() { uv_interp.z = ViewIndex; #endif vec2 vpos = uv_interp.xy; - if (params.use_section) { + if (bool(params.flags & FLAG_USE_SECTION)) { vpos = params.section.xy + vpos * params.section.zw; } gl_Position = vec4(vpos * 2.0 - 1.0, 0.0, 1.0); - if (params.flip_y) { + if (bool(params.flags & FLAG_FLIP_Y)) { uv_interp.y = 1.0 - uv_interp.y; } } @@ -63,19 +70,25 @@ void main() { #endif // has_VK_KHR_multiview #endif //MULTIVIEW +#define FLAG_FLIP_Y (1 << 0) +#define FLAG_USE_SECTION (1 << 1) +#define FLAG_FORCE_LUMINANCE (1 << 2) +#define FLAG_ALPHA_TO_ZERO (1 << 3) +#define FLAG_SRGB (1 << 4) +#define FLAG_ALPHA_TO_ONE (1 << 5) +#define FLAG_LINEAR (1 << 6) + layout(push_constant, std430) uniform Params { vec4 section; vec2 pixel_size; - bool flip_y; - bool use_section; + float luminance_multiplier; + uint flags; - bool force_luminance; - bool alpha_to_zero; - bool srgb; - uint pad; + vec4 color; } params; +#ifndef MODE_SET_COLOR #ifdef MULTIVIEW layout(location = 0) in vec3 uv_interp; #else @@ -94,6 +107,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_color; layout(set = 1, binding = 0) uniform sampler2D source_color2; #endif /* MODE_TWO_SOURCES */ #endif /* MULTIVIEW */ +#endif /* !SET_COLOR */ layout(location = 0) out vec4 frag_color; @@ -104,7 +118,15 @@ vec3 linear_to_srgb(vec3 color) { return mix((vec3(1.0f) + a) * pow(color.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * color.rgb, lessThan(color.rgb, vec3(0.0031308f))); } +vec3 srgb_to_linear(vec3 color) { + return mix(pow((color.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), color.rgb * (1.0 / 12.92), lessThan(color.rgb, vec3(0.04045))); +} + void main() { +#ifdef MODE_SET_COLOR + frag_color = params.color; +#else + #ifdef MULTIVIEW vec3 uv = uv_interp; #else @@ -155,15 +177,22 @@ void main() { #endif /* MODE_TWO_SOURCES */ #endif /* MULTIVIEW */ - if (params.force_luminance) { + if (bool(params.flags & FLAG_FORCE_LUMINANCE)) { color.rgb = vec3(max(max(color.r, color.g), color.b)); } - if (params.alpha_to_zero) { + if (bool(params.flags & FLAG_ALPHA_TO_ZERO)) { color.rgb *= color.a; } - if (params.srgb) { + if (bool(params.flags & FLAG_SRGB)) { color.rgb = linear_to_srgb(color.rgb); } + if (bool(params.flags & FLAG_ALPHA_TO_ONE)) { + color.a = 1.0; + } + if (bool(params.flags & FLAG_LINEAR)) { + color.rgb = srgb_to_linear(color.rgb); + } - frag_color = color; + frag_color = color / params.luminance_multiplier; +#endif // MODE_SET_COLOR } diff --git a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl index 1bee428a6f..c0597fe3f3 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cubemap_roughness_inc.glsl @@ -70,17 +70,6 @@ float DistributionGGX(float NdotH, float roughness4) { return roughness4 / denom; } -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float GGX(float NdotV, float a) { - float k = a / 2.0; - return NdotV / (NdotV * (1.0 - k) + k); -} - -// https://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html -float G_Smith(float a, float nDotV, float nDotL) { - return GGX(nDotL, a * a) * GGX(nDotV, a * a); -} - float radicalInverse_VdC(uint bits) { bits = (bits << 16u) | (bits >> 16u); bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); diff --git a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl index c8eb78a2f0..221e97bece 100644 --- a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl @@ -1,32 +1,32 @@ -/*************************************************************************/ -/* fsr_upscale.glsl */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ +/**************************************************************************/ +/* fsr_upscale.glsl */ +/**************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/**************************************************************************/ +/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ +/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ #[compute] diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl index 0ee4cf6e31..0ee4cf6e31 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce.glsl diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl index 29ebd74a90..29ebd74a90 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster.glsl diff --git a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster_inc.glsl index b8860f6518..b8860f6518 100644 --- a/servers/rendering/renderer_rd/shaders/luminance_reduce_raster_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/luminance_reduce_raster_inc.glsl diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl index 9f86643e52..631d1968b0 100644 --- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl @@ -66,6 +66,19 @@ void main() { vec4 normal_roughness = imageLoad(source_normal_roughness, ssC); vec3 normal = normal_roughness.xyz * 2.0 - 1.0; + float roughness = normal_roughness.w; + + // The roughness cutoff of 0.6 is chosen to match the roughness fadeout from GH-69828. + if (roughness > 0.6) { + // Do not compute SSR for rough materials to improve performance at the cost of + // subtle artifacting. +#ifdef MODE_ROUGH + imageStore(blur_radius_image, ssC, vec4(0.0)); +#endif + imageStore(ssr_image, ssC, vec4(0.0)); + return; + } + normal = normalize(normal); normal.y = -normal.y; //because this code reads flipped @@ -81,8 +94,6 @@ void main() { imageStore(ssr_image, ssC, vec4(0.0)); return; } - //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0); - //ray_dir = normalize(vec3(1.0, 1.0, -1.0)); //////////////// @@ -121,7 +132,7 @@ void main() { // clip z and w advance to line advance vec2 line_advance = normalize(line_dir); // down to pixel - float step_size = length(line_advance) / length(line_dir); + float step_size = 1.0 / length(line_dir); float z_advance = z_dir * step_size; // adapt z advance to line advance float w_advance = w_dir * step_size; // adapt w advance to line advance @@ -139,6 +150,14 @@ void main() { float depth; vec2 prev_pos = pos; + if (ivec2(pos + line_advance - 0.5) == ssC) { + // It is possible for rounding to cause our first pixel to check to be the pixel we're reflecting. + // Make sure we skip it + pos += line_advance; + z += z_advance; + w += w_advance; + } + bool found = false; float steps_taken = 0.0; @@ -149,8 +168,8 @@ void main() { w += w_advance; // convert to linear depth - - depth = imageLoad(source_depth, ivec2(pos - 0.5)).r; + ivec2 test_pos = ivec2(pos - 0.5); + depth = imageLoad(source_depth, test_pos).r; if (sc_multiview) { 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)); @@ -161,13 +180,21 @@ void main() { z_to = z / w; if (depth > z_to) { - // if depth was surpassed - if (depth <= max(z_to, z_from) + params.depth_tolerance && -depth < params.camera_z_far * 0.95) { - // check the depth tolerance and far clip - // check that normal is valid - found = true; + // Test if our ray is hitting the "right" side of the surface, if not we're likely self reflecting and should skip. + vec4 test_normal_roughness = imageLoad(source_normal_roughness, test_pos); + vec3 test_normal = test_normal_roughness.xyz * 2.0 - 1.0; + test_normal = normalize(test_normal); + test_normal.y = -test_normal.y; //because this code reads flipped + + if (dot(ray_dir, test_normal) < 0.001) { + // if depth was surpassed + if (depth <= max(z_to, z_from) + params.depth_tolerance && -depth < params.camera_z_far * 0.95) { + // check the depth tolerance and far clip + // check that normal is valid + found = true; + } + break; } - break; } steps_taken += 1.0; @@ -196,6 +223,9 @@ void main() { float grad = (steps_taken + 1.0) / float(params.num_steps); float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in); float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade; + // This is an ad-hoc term to fade out the SSR as roughness increases. Values used + // are meant to match the visual appearance of a ReflectionProbe. + float roughness_fade = smoothstep(0.4, 0.7, 1.0 - normal_roughness.w); final_pos = pos; vec4 final_color; @@ -204,7 +234,6 @@ void main() { // if roughness is enabled, do screen space cone tracing float blur_radius = 0.0; - float roughness = normal_roughness.w; if (roughness > 0.001) { float cone_angle = min(roughness, 0.999) * M_PI * 0.5; @@ -230,7 +259,7 @@ void main() { #endif // MODE_ROUGH - final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend); + final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend * roughness_fade); // Schlick term. float metallic = texelFetch(source_metallic, ssC << 1, 0).w; diff --git a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl index 134aae5ce7..b1ff46dd3b 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ss_effects_downsample.glsl @@ -56,7 +56,7 @@ vec4 screen_space_to_view_space_depth(vec4 p_depth) { float depth_linearize_mul = params.z_near; float depth_linearize_add = params.z_far; - // Optimised version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" + // Optimized version of "-cameraClipNear / (cameraClipFar - projDepth * (cameraClipFar - cameraClipNear)) * cameraClipFar" // Set your depth_linearize_mul and depth_linearize_add to: // depth_linearize_mul = ( cameraClipFar * cameraClipNear) / ( cameraClipFar - cameraClipNear ); diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl index 2a87e273bc..ffaa6872c9 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssao.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao.glsl @@ -221,7 +221,7 @@ void SSAOTap(const int p_quality_level, inout float r_obscurance_sum, inout floa // snap to pixel center (more correct obscurance math, avoids artifacts) sample_offset = round(sample_offset); - // calculate MIP based on the sample distance from the centre, similar to as described + // calculate MIP based on the sample distance from the center, similar to as described // in http://graphics.cs.williams.edu/papers/SAOHPG12/. float mip_level = (p_quality_level < SSAO_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (sample_pow_2_len + p_mip_offset); @@ -259,7 +259,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o // get this pixel's viewspace depth pix_z = valuesUL.y; - // get left right top bottom neighbouring pixels for edge detection (gets compiled out on quality_level == 0) + // get left right top bottom neighboring pixels for edge detection (gets compiled out on quality_level == 0) pix_left_z = valuesUL.x; pix_top_z = valuesUL.z; pix_right_z = valuesBR.z; @@ -304,7 +304,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o float obscurance_sum = 0.0; float weight_sum = 0.0; - // edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge) + // edge mask for between this and left/right/top/bottom neighbor pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge) vec4 edgesLRTB = vec4(1.0, 1.0, 1.0, 1.0); // Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats @@ -318,7 +318,7 @@ void generate_SSAO_shadows_internal(out float r_shadow_term, out vec4 r_edges, o if (!p_adaptive_base && (p_quality_level >= SSAO_DETAIL_AO_ENABLE_AT_QUALITY_PRESET)) { // disable in case of quality level 4 (reference) if (p_quality_level != 4) { - //approximate neighbouring pixels positions (actually just deltas or "positions - pix_center_pos" ) + //approximate neighboring pixels positions (actually just deltas or "positions - pix_center_pos" ) vec3 normalized_viewspace_dir = vec3(pix_center_pos.xy / pix_center_pos.zz, 1.0); vec3 pixel_left_delta = vec3(-pixel_size_at_center.x, 0.0, 0.0) + normalized_viewspace_dir * (pix_left_z - pix_center_pos.z); vec3 pixel_right_delta = vec3(+pixel_size_at_center.x, 0.0, 0.0) + normalized_viewspace_dir * (pix_right_z - pix_center_pos.z); diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl index 04f98964e8..d234ab4417 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao_importance_map.glsl @@ -80,7 +80,7 @@ void main() { #ifdef PROCESS_MAPA vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0; - float centre = textureLod(source_importance, uv, 0.0).x; + float center = textureLod(source_importance, uv, 0.0).x; vec2 half_pixel = params.half_screen_pixel_size; @@ -98,7 +98,7 @@ void main() { #ifdef PROCESS_MAPB vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0; - float centre = textureLod(source_importance, uv, 0.0).x; + float center = textureLod(source_importance, uv, 0.0).x; vec2 half_pixel = params.half_screen_pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl index f6a9a92fac..45cc62d361 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssao_interleave.glsl @@ -60,8 +60,8 @@ void main() { int mx = int(pix_pos.x % 2); int my = int(pix_pos.y % 2); int index_center = mx + my * 2; // center index - int index_horizontal = (1 - mx) + my * 2; // neighbouring, horizontal - int index_vertical = mx + (1 - my) * 2; // neighbouring, vertical + int index_horizontal = (1 - mx) + my * 2; // neighboring, horizontal + int index_vertical = mx + (1 - my) * 2; // neighboring, vertical int index_diagonal = (1 - mx) + (1 - my) * 2; // diagonal vec2 center_val = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0).xy; diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl index 513791dfbf..de7b97953f 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssil.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil.glsl @@ -234,7 +234,7 @@ void SSILTap(const int p_quality_level, inout vec3 r_color_sum, inout float r_ob // snap to pixel center (more correct obscurance math, avoids artifacts) sample_offset = round(sample_offset); - // calculate MIP based on the sample distance from the centre, similar to as described + // calculate MIP based on the sample distance from the center, similar to as described // in http://graphics.cs.williams.edu/papers/SAOHPG12/. float mip_level = (p_quality_level < SSIL_DEPTH_MIPS_ENABLE_AT_QUALITY_PRESET) ? (0) : (sample_pow_2_len + p_mip_offset); @@ -272,7 +272,7 @@ void generate_SSIL(out vec3 r_color, out vec4 r_edges, out float r_obscurance, o // get this pixel's viewspace depth pix_z = valuesUL.y; - // get left right top bottom neighbouring pixels for edge detection (gets compiled out on quality_level == 0) + // get left right top bottom neighboring pixels for edge detection (gets compiled out on quality_level == 0) pix_left_z = valuesUL.x; pix_top_z = valuesUL.z; pix_right_z = valuesBR.z; @@ -318,7 +318,7 @@ void generate_SSIL(out vec3 r_color, out vec4 r_edges, out float r_obscurance, o float obscurance_sum = 0.0; float weight_sum = 0.0; - // edge mask for between this and left/right/top/bottom neighbour pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge) + // edge mask for between this and left/right/top/bottom neighbor pixels - not used in quality level 0 so initialize to "no edge" (1 is no edge, 0 is edge) vec4 edgesLRTB = vec4(1.0, 1.0, 1.0, 1.0); // Move center pixel slightly towards camera to avoid imprecision artifacts due to using of 16bit depth buffer; a lot smaller offsets needed when using 32bit floats diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl index 47c56571f6..f48e6c4341 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_blur.glsl @@ -124,14 +124,14 @@ void main() { vec2 uv = (vec2(gl_GlobalInvocationID.xy) + vec2(0.5, 0.5)) * params.half_screen_pixel_size; - vec4 centre = textureLod(source_ssil, uv, 0.0); + vec4 center = textureLod(source_ssil, uv, 0.0); vec4 value = textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x * 3, -half_pixel.y)), 0.0) * 0.2; value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x, -half_pixel.y * 3)), 0.0) * 0.2; value += textureLod(source_ssil, vec2(uv + vec2(-half_pixel.x, +half_pixel.y * 3)), 0.0) * 0.2; value += textureLod(source_ssil, vec2(uv + vec2(+half_pixel.x * 3, +half_pixel.y)), 0.0) * 0.2; - vec4 sampled = value + centre * 0.2; + vec4 sampled = value + center * 0.2; #else #ifdef MODE_SMART diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl index 6b6b02739d..193e3458ab 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_importance_map.glsl @@ -82,7 +82,7 @@ void main() { #ifdef PROCESS_MAPA vec2 uv = (vec2(ssC) + 0.5) * params.half_screen_pixel_size * 2.0; - float centre = textureLod(source_importance, uv, 0.0).x; + float center = textureLod(source_importance, uv, 0.0).x; vec2 half_pixel = params.half_screen_pixel_size; @@ -100,7 +100,7 @@ void main() { #ifdef PROCESS_MAPB vec2 uv = (vec2(ssC) + 0.5f) * params.half_screen_pixel_size * 2.0; - float centre = textureLod(source_importance, uv, 0.0).x; + float center = textureLod(source_importance, uv, 0.0).x; vec2 half_pixel = params.half_screen_pixel_size; diff --git a/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl index 9e86ac0cf0..ed85b8ee4c 100644 --- a/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/ssil_interleave.glsl @@ -62,8 +62,8 @@ void main() { int mx = int(pix_pos.x % 2); int my = int(pix_pos.y % 2); int index_center = mx + my * 2; // center index - int index_horizontal = (1 - mx) + my * 2; // neighbouring, horizontal - int index_vertical = mx + (1 - my) * 2; // neighbouring, vertical + int index_horizontal = (1 - mx) + my * 2; // neighboring, horizontal + int index_vertical = mx + (1 - my) * 2; // neighboring, vertical int index_diagonal = (1 - mx) + (1 - my) * 2; // diagonal vec4 color = texelFetch(source_texture, ivec3(pix_pos / uvec2(params.size_modifier), index_center), 0); diff --git a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl index b0a0839836..02566d8e35 100644 --- a/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/taa_resolve.glsl @@ -32,7 +32,9 @@ // Based on Spartan Engine's TAA implementation (without TAA upscale). // <https://github.com/PanosK92/SpartanEngine/blob/a8338d0609b85dc32f3732a5c27fb4463816a3b9/Data/shaders/temporal_antialiasing.hlsl> +#ifndef MOLTENVK_USED #define USE_SUBGROUPS +#endif // MOLTENVK_USED #define GROUP_SIZE 8 #define FLT_MIN 0.00000001 diff --git a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl index 5ef83c0b44..b450bb9fe9 100644 --- a/servers/rendering/renderer_rd/shaders/effects/vrs.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/vrs.glsl @@ -63,10 +63,18 @@ void main() { #ifdef MULTIVIEW vec4 color = textureLod(source_color, uv, 0.0); + frag_color = uint(color.r * 255.0); #else /* MULTIVIEW */ vec4 color = textureLod(source_color, uv, 0.0); -#endif /* MULTIVIEW */ - // See if we can change the sampler to one that returns int... - frag_color = uint(color.r * 256.0); + // for user supplied VRS map we do a color mapping + color.r *= 3.0; + frag_color = int(color.r) << 2; + + color.g *= 3.0; + frag_color += int(color.g); + + // note 1x4, 4x1, 1x8, 8x1, 2x8 and 8x2 are not supported + // 4x8, 8x4 and 8x8 are only available on some GPUs +#endif /* MULTIVIEW */ } diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl index ab927df678..459c4dcb1d 100644 --- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl @@ -108,7 +108,9 @@ layout(set = 0, binding = 18, std140) uniform SceneData { } scene_data; +#ifdef USE_VRS layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer; +#endif layout(push_constant, std430) uniform Params { uint max_voxel_gi_instances; @@ -661,6 +663,7 @@ void main() { ivec2 pos = ivec2(gl_GlobalInvocationID.xy); uint vrs_x, vrs_y; +#ifdef USE_VRS if (sc_use_vrs) { ivec2 vrs_pos; @@ -684,6 +687,7 @@ void main() { return; } } +#endif if (sc_half_res) { pos <<= 1; @@ -708,6 +712,7 @@ void main() { imageStore(ambient_buffer, pos, ambient_light); imageStore(reflection_buffer, pos, reflection_light); +#ifdef USE_VRS if (sc_use_vrs) { if (vrs_x > 1) { imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light); @@ -766,4 +771,5 @@ void main() { imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light); } } +#endif } diff --git a/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl index 9f7449b8aa..06709f65d3 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_direct_light.glsl @@ -24,7 +24,7 @@ struct ProcessVoxel { uint albedo; // rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors. uint light; // rgbe8985 encoded total saved light, extra 2 bits for neighbors. uint light_aniso; // 55555 light anisotropy, extra 2 bits for neighbors. - //total neighbours: 26 + //total neighbors: 26 }; #ifdef MODE_PROCESS_STATIC @@ -443,10 +443,10 @@ void main() { imageStore(dst_aniso1, positioni, vec4(aniso1, 0.0, 0.0)); imageStore(dst_light, positioni, uvec4(light_total_rgbe)); - //also fill neighbours, so light interpolation during the indirect pass works + //also fill neighbors, so light interpolation during the indirect pass works - //recover the neighbour list from the leftover bits - uint neighbours = (voxel_albedo >> 21) | ((voxel_position >> 21) << 11) | ((process_voxels.data[voxel_index].light >> 30) << 22) | ((process_voxels.data[voxel_index].light_aniso >> 30) << 24); + //recover the neighbor list from the leftover bits + uint neighbors = (voxel_albedo >> 21) | ((voxel_position >> 21) << 11) | ((process_voxels.data[voxel_index].light >> 30) << 22) | ((process_voxels.data[voxel_index].light_aniso >> 30) << 24); const uint max_neighbours = 26; const ivec3 neighbour_positions[max_neighbours] = ivec3[]( @@ -478,7 +478,7 @@ void main() { ivec3(1, 1, 1)); for (uint i = 0; i < max_neighbours; i++) { - if (bool(neighbours & (1 << i))) { + if (bool(neighbors & (1 << i))) { ivec3 neighbour_pos = positioni + neighbour_positions[i]; imageStore(dst_light, neighbour_pos, uvec4(light_total_rgbe)); imageStore(dst_aniso0, neighbour_pos, aniso0); diff --git a/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl index bce98f4054..dd35ae3b73 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sdfgi_preprocess.glsl @@ -102,10 +102,10 @@ dispatch_data; struct ProcessVoxel { uint position; // xyz 7 bit packed, extra 11 bits for neighbors. - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours - uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours - uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours - //total neighbours: 26 + uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors + uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbors + uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbors + //total neighbors: 26 }; layout(set = 0, binding = 11, std430) restrict buffer writeonly ProcessVoxels { @@ -135,10 +135,10 @@ dispatch_data; struct ProcessVoxel { uint position; // xyz 7 bit packed, extra 11 bits for neighbors. - uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbours - uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbours - uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbours - //total neighbours: 26 + uint albedo; //rgb bits 0-15 albedo, bits 16-21 are normal bits (set if geometry exists toward that side), extra 11 bits for neighbors + uint light; //rgbe8985 encoded total saved light, extra 2 bits for neighbors + uint light_aniso; //55555 light anisotropy, extra 2 bits for neighbors + //total neighbors: 26 }; layout(set = 0, binding = 6, std430) restrict buffer readonly ProcessVoxels { @@ -1016,14 +1016,14 @@ void main() { store_positions[index].albedo = rgb >> 1; //store as it comes (555) to avoid precision loss (and move away the alpha bit) store_positions[index].albedo |= (facing & 0x3F) << 15; // store facing in bits 15-21 - store_positions[index].albedo |= neighbour_bits << 21; //store lower 11 bits of neighbours with remaining albedo - store_positions[index].position |= (neighbour_bits >> 11) << 21; //store 11 bits more of neighbours with position + store_positions[index].albedo |= neighbour_bits << 21; //store lower 11 bits of neighbors with remaining albedo + store_positions[index].position |= (neighbour_bits >> 11) << 21; //store 11 bits more of neighbors with position store_positions[index].light = imageLoad(src_light, pos).r; store_positions[index].light_aniso = imageLoad(src_light_aniso, pos).r; - //add neighbours - store_positions[index].light |= (neighbour_bits >> 22) << 30; //store 2 bits more of neighbours with light - store_positions[index].light_aniso |= (neighbour_bits >> 24) << 30; //store 2 bits more of neighbours with aniso + //add neighbors + store_positions[index].light |= (neighbour_bits >> 22) << 30; //store 2 bits more of neighbors with light + store_positions[index].light_aniso |= (neighbour_bits >> 24) << 30; //store 2 bits more of neighbors with aniso } groupMemoryBarrier(); diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl index d523461600..bf974a3fd5 100644 --- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl @@ -14,7 +14,7 @@ layout(location = 0) out vec2 uv_interp; layout(push_constant, std430) uniform Params { mat3 orientation; - vec4 projections[MAX_VIEWS]; + vec4 projection; // only applicable if not multiview vec3 position; float time; vec3 pad; @@ -54,7 +54,7 @@ layout(location = 0) in vec2 uv_interp; layout(push_constant, std430) uniform Params { mat3 orientation; - vec4 projections[MAX_VIEWS]; + vec4 projection; // only applicable if not multiview vec3 position; float time; vec3 pad; @@ -82,7 +82,10 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor } global_shader_uniforms; -layout(set = 0, binding = 2, std140) uniform SceneData { +layout(set = 0, binding = 2, std140) uniform SkySceneData { + mat4 view_inv_projections[2]; + vec4 view_eye_offsets[2]; + bool volumetric_fog_enabled; // 4 - 4 float volumetric_fog_inv_length; // 4 - 8 float volumetric_fog_detail_spread; // 4 - 12 @@ -101,7 +104,7 @@ layout(set = 0, binding = 2, std140) uniform SceneData { uint pad1; // 4 - 60 uint pad2; // 4 - 64 } -scene_data; +sky_scene_data; struct DirectionalLightData { vec4 direction_energy; @@ -124,6 +127,9 @@ layout(set = 2, binding = 0) uniform textureCube radiance; #ifdef USE_CUBEMAP_PASS layout(set = 2, binding = 1) uniform textureCube half_res; layout(set = 2, binding = 2) uniform textureCube quarter_res; +#elif defined(USE_MULTIVIEW) +layout(set = 2, binding = 1) uniform texture2DArray half_res; +layout(set = 2, binding = 2) uniform texture2DArray quarter_res; #else layout(set = 2, binding = 1) uniform texture2D half_res; layout(set = 2, binding = 2) uniform texture2D quarter_res; @@ -169,15 +175,15 @@ vec4 volumetric_fog_process(vec2 screen_uv) { } vec4 fog_process(vec3 view, vec3 sky_color) { - vec3 fog_color = mix(scene_data.fog_light_color, sky_color, scene_data.fog_aerial_perspective); + vec3 fog_color = mix(sky_scene_data.fog_light_color, sky_color, sky_scene_data.fog_aerial_perspective); - if (scene_data.fog_sun_scatter > 0.001) { + if (sky_scene_data.fog_sun_scatter > 0.001) { vec4 sun_scatter = vec4(0.0); float sun_total = 0.0; - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sky_scene_data.directional_light_count; i++) { vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w; float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0); - fog_color += light_color * light_amount * scene_data.fog_sun_scatter; + fog_color += light_color * light_amount * sky_scene_data.fog_sun_scatter; } } @@ -186,9 +192,17 @@ vec4 fog_process(vec3 view, vec3 sky_color) { void main() { vec3 cube_normal; +#ifdef USE_MULTIVIEW + // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject. + vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 1.0, 1.0); + vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject; + cube_normal = unprojected.xyz / unprojected.w; + cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz; +#else cube_normal.z = -1.0; - cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y; - cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w; + cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y; + cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projection.z)) / params.projection.w; +#endif cube_normal = mat3(params.orientation) * cube_normal; cube_normal = normalize(cube_normal); @@ -209,20 +223,33 @@ void main() { vec4 custom_fog = vec4(0.0); #ifdef USE_CUBEMAP_PASS + #ifdef USES_HALF_RES_COLOR half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier; #endif #ifdef USES_QUARTER_RES_COLOR quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier; #endif + #else + #ifdef USES_HALF_RES_COLOR +#ifdef USE_MULTIVIEW + half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier; +#else half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier; -#endif +#endif // USE_MULTIVIEW +#endif // USES_HALF_RES_COLOR + #ifdef USES_QUARTER_RES_COLOR +#ifdef USE_MULTIVIEW + quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier; +#else quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier; -#endif -#endif +#endif // USE_MULTIVIEW +#endif // USES_QUARTER_RES_COLOR + +#endif //USE_CUBEMAP_PASS { @@ -236,14 +263,14 @@ void main() { #if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS) // Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky. - if (scene_data.fog_enabled) { + if (sky_scene_data.fog_enabled) { vec4 fog = fog_process(cube_normal, frag_color.rgb); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.fog_sky_affect); + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.fog_sky_affect); } - if (scene_data.volumetric_fog_enabled) { + if (sky_scene_data.volumetric_fog_enabled) { vec4 fog = volumetric_fog_process(uv); - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.volumetric_fog_sky_affect); + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.volumetric_fog_sky_affect); } if (custom_fog.a > 0.0) { diff --git a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl index eed9038502..28507e6c12 100644 --- a/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl +++ b/servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl @@ -381,7 +381,7 @@ void main() { float cell_depth_size = abs(view_pos.z - get_depth_at_pos(fog_cell_size.z, pos.z + 1)); //compute directional lights - if (total_density > 0.001) { + if (total_density > 0.00005) { for (uint i = 0; i < params.directional_light_count; i++) { if (directional_lights.data[i].volumetric_fog_energy > 0.001) { vec3 shadow_attenuation = vec3(1.0); diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl index 1a8a1f3aa3..c6a3c42e57 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl @@ -62,7 +62,7 @@ vec3 oct_to_vec3(vec2 e) { vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } /* Varyings */ @@ -97,9 +97,7 @@ layout(location = 8) out vec4 prev_screen_position; #ifdef MATERIAL_UNIFORMS_USED layout(set = MATERIAL_UNIFORM_SET, binding = 0, std140) uniform MaterialUniforms{ - #MATERIAL_UNIFORMS - } material; #endif @@ -120,9 +118,15 @@ layout(location = 10) out flat uint instance_index_interp; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif // has_VK_KHR_multiview +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // USE_MULTIVIEW // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW invariant gl_Position; @@ -546,9 +550,15 @@ layout(location = 10) in flat uint instance_index_interp; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif // has_VK_KHR_multiview +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // USE_MULTIVIEW // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW //defines to keep compatibility with vertex @@ -691,7 +701,7 @@ vec4 fog_process(vec3 vertex) { void cluster_get_item_range(uint p_offset, out uint item_min, out uint item_max, out uint item_from, out uint item_to) { uint item_min_max = cluster_buffer.data[p_offset]; - item_min = item_min_max & 0xFFFF; + item_min = item_min_max & 0xFFFFu; item_max = item_min_max >> 16; item_from = item_min >> 5; @@ -828,7 +838,8 @@ void fragment_shader(in SceneData scene_data) { // alpha hash can be used in unison with alpha antialiasing #ifdef ALPHA_HASH_USED - if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) { + vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz; + if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) { discard; } #endif // ALPHA_HASH_USED @@ -958,9 +969,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1085,12 +1096,13 @@ void fragment_shader(in SceneData scene_data) { #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; - blend = modf(roughness * MAX_ROUGHNESS_LOD, lod); + + blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod); specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); #else - specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb; + specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb; #endif //USE_RADIANCE_CUBEMAP_ARRAY specular_light *= scene_data.IBL_exposure_normalization; @@ -1138,7 +1150,7 @@ void fragment_shader(in SceneData scene_data) { ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness); float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; - float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; + float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD; #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; @@ -1293,24 +1305,26 @@ void fragment_shader(in SceneData scene_data) { } if (sc_use_forward_gi && bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances - uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; - vec3 ref_vec = normalize(reflect(-view, normal)); - ref_vec = mix(ref_vec, normal, roughness * roughness); + // Make vertex orientation the world one, but still align to camera. + vec3 cam_pos = mat3(scene_data.inv_view_matrix) * vertex; + vec3 cam_normal = mat3(scene_data.inv_view_matrix) * normal; + vec3 ref_vec = mat3(scene_data.inv_view_matrix) * normalize(reflect(-view, normal)); + //find arbitrary tangent and bitangent, then build a matrix - vec3 v0 = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); - vec3 tangent = normalize(cross(v0, normal)); - vec3 bitangent = normalize(cross(tangent, normal)); - mat3 normal_mat = mat3(tangent, bitangent, normal); + vec3 v0 = abs(cam_normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(0.0, 1.0, 0.0); + vec3 tangent = normalize(cross(v0, cam_normal)); + vec3 bitangent = normalize(cross(tangent, cam_normal)); + mat3 normal_mat = mat3(tangent, bitangent, cam_normal); vec4 amb_accum = vec4(0.0); vec4 spec_accum = vec4(0.0); - voxel_gi_compute(index1, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + voxel_gi_compute(index1, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); uint index2 = instances.data[instance_index].gi_offset >> 16; if (index2 != 0xFFFF) { - voxel_gi_compute(index2, vertex, normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); + voxel_gi_compute(index2, cam_pos, cam_normal, ref_vec, normal_mat, roughness * roughness, ambient_light, specular_light, spec_accum, amb_accum); } if (amb_accum.a > 0.0) { @@ -1339,8 +1353,8 @@ void fragment_shader(in SceneData scene_data) { #endif // USE_MULTIVIEW for (int i = 0; i < 4; i++) { - const vec2 neighbours[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1)); - vec2 neighbour_coord = base_coord + neighbours[i] * scene_data.screen_pixel_size; + const vec2 neighbors[4] = vec2[](vec2(-1, 0), vec2(1, 0), vec2(0, -1), vec2(0, 1)); + vec2 neighbour_coord = base_coord + neighbors[i] * scene_data.screen_pixel_size; #ifdef USE_MULTIVIEW float neighbour_ang = dot(normal, textureLod(sampler2DArray(normal_roughness_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(neighbour_coord, ViewIndex), 0.0).xyz * 2.0 - 1.0); #else // USE_MULTIVIEW @@ -1419,9 +1433,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1447,18 +1461,24 @@ void fragment_shader(in SceneData scene_data) { } //finalize ambient light here - ambient_light *= albedo.rgb; - ambient_light *= ao; + { +#if defined(AMBIENT_LIGHT_DISABLED) + ambient_light = vec3(0.0, 0.0, 0.0); +#else + ambient_light *= albedo.rgb; + ambient_light *= ao; + + if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { + vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); + ambient_light *= 1.0 - ssil.a; + ambient_light += ssil.rgb * albedo.rgb; + } +#endif // AMBIENT_LIGHT_DISABLED + } // convert ao to direct light ao ao = mix(1.0, ao, ao_light_affect); - if (bool(implementation_data.ss_effects_flags & SCREEN_SPACE_EFFECTS_FLAGS_USE_SSIL)) { - vec4 ssil = textureLod(sampler2D(ssil_buffer, material_samplers[SAMPLER_LINEAR_CLAMP]), screen_uv, 0.0); - ambient_light *= 1.0 - ssil.a; - ambient_light += ssil.rgb * albedo.rgb; - } - //this saves some VGPRs vec3 f0 = F0(metallic, specular, albedo); @@ -1479,7 +1499,7 @@ void fragment_shader(in SceneData scene_data) { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, 0.0, 1.0); + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); #endif } @@ -1775,12 +1795,12 @@ void fragment_shader(in SceneData scene_data) { float shadow = 1.0; #ifndef SHADOWS_DISABLED if (i < 4) { - shadow = float(shadow0 >> (i * 8) & 0xFF) / 255.0; + shadow = float(shadow0 >> (i * 8u) & 0xFFu) / 255.0; } else { - shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; + shadow = float(shadow1 >> ((i - 4u) * 8u) & 0xFFu) / 255.0; } - shadow = shadow * directional_lights.data[i].shadow_opacity + 1.0 - directional_lights.data[i].shadow_opacity; + shadow = mix(1.0, shadow, directional_lights.data[i].shadow_opacity); #endif blur_shadow(shadow); @@ -1839,9 +1859,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -1910,9 +1930,9 @@ void fragment_shader(in SceneData scene_data) { while (merged_mask != 0) { uint bit = findMSB(merged_mask); - merged_mask &= ~(1 << bit); + merged_mask &= ~(1u << bit); #ifdef USE_SUBGROUPS - if (((1 << bit) & mask) == 0) { //do not process if not originally here + if (((1u << bit) & mask) == 0) { //do not process if not originally here continue; } #endif @@ -2064,8 +2084,8 @@ void fragment_shader(in SceneData scene_data) { float sRed = floor((cRed / pow(2.0f, exps - B - N)) + 0.5f); float sGreen = floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f); float sBlue = floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f); - //store as 8985 to have 2 extra neighbour bits - uint light_rgbe = ((uint(sRed) & 0x1FF) >> 1) | ((uint(sGreen) & 0x1FF) << 8) | (((uint(sBlue) & 0x1FF) >> 1) << 17) | ((uint(exps) & 0x1F) << 25); + //store as 8985 to have 2 extra neighbor bits + uint light_rgbe = ((uint(sRed) & 0x1FFu) >> 1) | ((uint(sGreen) & 0x1FFu) << 8) | (((uint(sBlue) & 0x1FFu) >> 1) << 17) | ((uint(exps) & 0x1Fu) << 25); imageStore(emission_grid, grid_pos, uvec4(light_rgbe)); imageStore(emission_aniso_grid, grid_pos, uvec4(light_aniso)); @@ -2099,8 +2119,8 @@ void fragment_shader(in SceneData scene_data) { if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_USE_VOXEL_GI)) { // process voxel_gi_instances uint index1 = instances.data[instance_index].gi_offset & 0xFFFF; uint index2 = instances.data[instance_index].gi_offset >> 16; - voxel_gi_buffer.x = index1 & 0xFF; - voxel_gi_buffer.y = index2 & 0xFF; + voxel_gi_buffer.x = index1 & 0xFFu; + voxel_gi_buffer.y = index2 & 0xFFu; } else { voxel_gi_buffer.x = 0xFF; voxel_gi_buffer.y = 0xFF; diff --git a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl index e8e2dce990..8ff7a784dc 100644 --- a/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl @@ -4,14 +4,15 @@ #define MAX_VOXEL_GI_INSTANCES 8 #define MAX_VIEWS 2 +#ifndef MOLTENVK_USED #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) #extension GL_KHR_shader_subgroup_ballot : enable #extension GL_KHR_shader_subgroup_arithmetic : enable #define USE_SUBGROUPS - #endif +#endif // MOLTENVK_USED #if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview) #extension GL_EXT_multiview : enable @@ -62,13 +63,14 @@ layout(set = 0, binding = 3) uniform sampler decal_sampler; layout(set = 0, binding = 4) uniform sampler light_projector_sampler; -#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5) -#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) -#define INSTANCE_FLAGS_USE_SDFGI (1 << 7) -#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) -#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) -#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) +#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 4) +#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 5) +#define INSTANCE_FLAGS_USE_SDFGI (1 << 6) +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 7) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 8) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) +#define INSTANCE_FLAGS_PARTICLES (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) @@ -266,19 +268,23 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid; #define color_buffer shadow_atlas #define normal_roughness_buffer shadow_atlas +#define multiviewSampler sampler2D #else -layout(set = 1, binding = 10) uniform texture2D depth_buffer; -layout(set = 1, binding = 11) uniform texture2D color_buffer; - #ifdef USE_MULTIVIEW +layout(set = 1, binding = 10) uniform texture2DArray depth_buffer; +layout(set = 1, binding = 11) uniform texture2DArray color_buffer; layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer; layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer; layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer; +#define multiviewSampler sampler2DArray #else // USE_MULTIVIEW +layout(set = 1, binding = 10) uniform texture2D depth_buffer; +layout(set = 1, binding = 11) uniform texture2D color_buffer; layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer; layout(set = 1, binding = 14) uniform texture2D ambient_buffer; layout(set = 1, binding = 15) uniform texture2D reflection_buffer; +#define multiviewSampler sampler2D #endif layout(set = 1, binding = 13) uniform texture2D ao_buffer; layout(set = 1, binding = 16) uniform texture2DArray sdfgi_lightprobe_texture; diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl index 33fd4c35b1..90e902ca33 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl @@ -63,7 +63,7 @@ vec3 oct_to_vec3(vec2 e) { vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } /* Varyings */ @@ -112,9 +112,15 @@ layout(location = 9) out highp float dp_clip; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW invariant gl_Position; @@ -523,9 +529,15 @@ layout(location = 9) highp in float dp_clip; // !BAS! This needs to become an input once we implement our fallback! #define ViewIndex 0 #endif +vec3 multiview_uv(vec2 uv) { + return vec3(uv, ViewIndex); +} #else // Set to zero, not supported in non stereo #define ViewIndex 0 +vec2 multiview_uv(vec2 uv) { + return uv; +} #endif //USE_MULTIVIEW //defines to keep compatibility with vertex @@ -779,7 +791,8 @@ void main() { // alpha hash can be used in unison with alpha antialiasing #ifdef ALPHA_HASH_USED - if (alpha < compute_alpha_hash_threshold(vertex, alpha_hash_scale)) { + vec3 object_pos = (inverse(read_model_matrix) * inv_view_matrix * vec4(vertex, 1.0)).xyz; + if (alpha < compute_alpha_hash_threshold(object_pos, alpha_hash_scale)) { discard; } #endif // ALPHA_HASH_USED @@ -865,7 +878,7 @@ void main() { uint decal_indices = draw_call.decals.x; for (uint i = 0; i < 8; i++) { uint decal_index = decal_indices & 0xFF; - if (i == 4) { + if (i == 3) { decal_indices = draw_call.decals.y; } else { decal_indices = decal_indices >> 8; @@ -986,12 +999,12 @@ void main() { #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; - blend = modf(roughness * MAX_ROUGHNESS_LOD, lod); + blend = modf(sqrt(roughness) * MAX_ROUGHNESS_LOD, lod); specular_light = texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod)).rgb; specular_light = mix(specular_light, texture(samplerCubeArray(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), vec4(ref_vec, lod + 1)).rgb, blend); #else // USE_RADIANCE_CUBEMAP_ARRAY - specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, roughness * MAX_ROUGHNESS_LOD).rgb; + specular_light = textureLod(samplerCube(radiance_cubemap, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), ref_vec, sqrt(roughness) * MAX_ROUGHNESS_LOD).rgb; #endif //USE_RADIANCE_CUBEMAP_ARRAY specular_light *= sc_luminance_multiplier; @@ -1041,7 +1054,7 @@ void main() { float horizon = min(1.0 + dot(ref_vec, normal), 1.0); ref_vec = scene_data.radiance_inverse_xform * ref_vec; - float roughness_lod = mix(0.001, 0.1, clearcoat_roughness) * MAX_ROUGHNESS_LOD; + float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD; #ifdef USE_RADIANCE_CUBEMAP_ARRAY float lod, blend; @@ -1147,7 +1160,7 @@ void main() { for (uint i = 0; i < 8; i++) { uint reflection_index = reflection_indices & 0xFF; - if (i == 4) { + if (i == 3) { reflection_indices = draw_call.reflection_probes.y; } else { reflection_indices = reflection_indices >> 8; @@ -1172,8 +1185,14 @@ void main() { } //Reflection probes // finalize ambient light here - ambient_light *= albedo.rgb; - ambient_light *= ao; + { +#if defined(AMBIENT_LIGHT_DISABLED) + ambient_light = vec3(0.0, 0.0, 0.0); +#else + ambient_light *= albedo.rgb; + ambient_light *= ao; +#endif // AMBIENT_LIGHT_DISABLED + } // convert ao to direct light ao ao = mix(1.0, ao, ao_light_affect); @@ -1198,7 +1217,7 @@ void main() { float a004 = min(r.x * r.x, exp2(-9.28 * ndotv)) * r.x + r.y; vec2 env = vec2(-1.04, 1.04) * a004 + r.zw; - specular_light *= env.x * f0 + env.y; + specular_light *= env.x * f0 + env.y * clamp(50.0 * f0.g, metallic, 1.0); #endif } @@ -1508,6 +1527,8 @@ void main() { } else { shadow = float(shadow1 >> ((i - 4) * 8) & 0xFF) / 255.0; } + + shadow = mix(1.0, shadow, directional_lights.data[i].shadow_opacity); #endif blur_shadow(shadow); @@ -1544,7 +1565,7 @@ void main() { uint light_indices = draw_call.omni_lights.x; for (uint i = 0; i < 8; i++) { uint light_index = light_indices & 0xFF; - if (i == 4) { + if (i == 3) { light_indices = draw_call.omni_lights.y; } else { light_indices = light_indices >> 8; @@ -1589,7 +1610,7 @@ void main() { uint light_indices = draw_call.spot_lights.x; for (uint i = 0; i < 8; i++) { uint light_index = light_indices & 0xFF; - if (i == 4) { + if (i == 3) { light_indices = draw_call.spot_lights.y; } else { light_indices = light_indices >> 8; diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl index 5e4999fa0f..78b39a356d 100644 --- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl @@ -55,13 +55,14 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; layout(set = 0, binding = 3) uniform sampler decal_sampler; layout(set = 0, binding = 4) uniform sampler light_projector_sampler; -#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 5) -#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 6) -#define INSTANCE_FLAGS_USE_SDFGI (1 << 7) -#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 8) -#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 9) -#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 10) -#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 11) +#define INSTANCE_FLAGS_NON_UNIFORM_SCALE (1 << 4) +#define INSTANCE_FLAGS_USE_GI_BUFFERS (1 << 5) +#define INSTANCE_FLAGS_USE_SDFGI (1 << 6) +#define INSTANCE_FLAGS_USE_LIGHTMAP_CAPTURE (1 << 7) +#define INSTANCE_FLAGS_USE_LIGHTMAP (1 << 8) +#define INSTANCE_FLAGS_USE_SH_LIGHTMAP (1 << 9) +#define INSTANCE_FLAGS_USE_VOXEL_GI (1 << 10) +#define INSTANCE_FLAGS_PARTICLES (1 << 11) #define INSTANCE_FLAGS_MULTIMESH (1 << 12) #define INSTANCE_FLAGS_MULTIMESH_FORMAT_2D (1 << 13) #define INSTANCE_FLAGS_MULTIMESH_HAS_COLOR (1 << 14) @@ -153,8 +154,15 @@ layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas; // this needs to change to providing just the lightmap we're using.. layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; +#ifdef USE_MULTIVIEW +layout(set = 1, binding = 9) uniform highp texture2DArray depth_buffer; +layout(set = 1, binding = 10) uniform mediump texture2DArray color_buffer; +#define multiviewSampler sampler2DArray +#else layout(set = 1, binding = 9) uniform highp texture2D depth_buffer; layout(set = 1, binding = 10) uniform mediump texture2D color_buffer; +#define multiviewSampler sampler2D +#endif // USE_MULTIVIEW /* Set 2 Skeleton & Instancing (can change per item) */ diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl index 3a6dd579b9..a609076e2c 100644 --- a/servers/rendering/renderer_rd/shaders/particles.glsl +++ b/servers/rendering/renderer_rd/shaders/particles.glsl @@ -243,8 +243,14 @@ void main() { if (params.trail_size > 1) { if (params.trail_pass) { + if (particle >= params.total_particles * (params.trail_size - 1)) { + return; + } particle += (particle / (params.trail_size - 1)) + 1; } else { + if (particle >= params.total_particles) { + return; + } particle *= params.trail_size; } } @@ -298,12 +304,17 @@ void main() { PARTICLE.flags = PARTICLE_FLAG_TRAILED | ((frame_history.data[0].frame & PARTICLE_FRAME_MASK) << PARTICLE_FRAME_SHIFT); //mark it as trailed, save in which frame it will start PARTICLE.xform = particles.data[src_idx].xform; } - + if (!bool(particles.data[src_idx].flags & PARTICLE_FLAG_ACTIVE)) { + // Disable the entire trail if the parent is no longer active. + PARTICLE.flags = 0; + return; + } if (bool(PARTICLE.flags & PARTICLE_FLAG_TRAILED) && ((PARTICLE.flags >> PARTICLE_FRAME_SHIFT) == (FRAME.frame & PARTICLE_FRAME_MASK))) { //check this is trailed and see if it should start now // we just assume that this is the first frame of the particle, the rest is deterministic PARTICLE.flags = PARTICLE_FLAG_ACTIVE | (particles.data[src_idx].flags & (PARTICLE_FRAME_MASK << PARTICLE_FRAME_SHIFT)); return; //- this appears like it should be correct, but it seems not to be.. wonder why. } + } else { PARTICLE.flags &= ~PARTICLE_FLAG_STARTED; } @@ -462,7 +473,7 @@ void main() { if (any(lessThan(uvw_pos, vec3(0.0))) || any(greaterThan(uvw_pos, vec3(1.0)))) { continue; } - vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * 2.0 - 1.0; + vec3 s = texture(sampler3D(sdf_vec_textures[FRAME.attractors[i].texture_index], material_samplers[SAMPLER_LINEAR_CLAMP]), uvw_pos).xyz * -2.0 + 1.0; dir = mat3(FRAME.attractors[i].transform) * safe_normalize(s); //revert direction amount = length(s); diff --git a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl index 048257e9ef..b57ee18521 100644 --- a/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_data_inc.glsl @@ -63,7 +63,7 @@ struct SceneData { float IBL_exposure_normalization; bool pancake_shadows; - uint pad1; + uint camera_visible_layers; uint pad2; uint pad3; }; diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl index 97c913d489..71510ee06a 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_aa_inc.glsl @@ -11,7 +11,8 @@ float hash_3d(vec3 p) { float compute_alpha_hash_threshold(vec3 pos, float hash_scale) { vec3 dx = dFdx(pos); - vec3 dy = dFdx(pos); + vec3 dy = dFdy(pos); + float delta_max_sqr = max(length(dx), length(dy)); float pix_scale = 1.0 / (hash_scale * delta_max_sqr); @@ -32,9 +33,9 @@ float compute_alpha_hash_threshold(vec3 pos, float hash_scale) { 1.0 - ((1.0 - a_interp) * (1.0 - a_interp) / (2.0 * min_lerp * (1.0 - min_lerp)))); float alpha_hash_threshold = - (lerp_factor < (1.0 - min_lerp)) ? ((lerp_factor < min_lerp) ? cases.x : cases.y) : cases.z; + (a_interp < (1.0 - min_lerp)) ? ((a_interp < min_lerp) ? cases.x : cases.y) : cases.z; - return clamp(alpha_hash_threshold, 0.0, 1.0); + return clamp(alpha_hash_threshold, 0.00001, 1.0); } #endif // ALPHA_HASH_USED diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl index 2fba1351f7..9dda62c28d 100644 --- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl @@ -134,7 +134,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte #endif #if defined(LIGHT_RIM_USED) - float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); + // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior. + float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0)); diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color; #endif @@ -202,7 +203,7 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte float cLdotH5 = SchlickFresnel(cLdotH); // Calculate Fresnel using specular occlusion term from Filament: // https://google.github.io/filament/Filament.html#lighting/occlusion/specularocclusion - float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), 0.0, 1.0); + float f90 = clamp(dot(f0, vec3(50.0 * 0.33)), metallic, 1.0); vec3 F = f0 + (f90 - f0) * cLdotH5; vec3 specular_brdf_NL = cNdotL * D * F * G; @@ -793,8 +794,13 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v float light_length = length(light_rel_vec); float spot_attenuation = get_omni_attenuation(light_length, spot_lights.data[idx].inv_radius, spot_lights.data[idx].attenuation); vec3 spot_dir = spot_lights.data[idx].direction; - float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[idx].cone_angle); - float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[idx].cone_angle)); + + // This conversion to a highp float is crucial to prevent light leaking + // due to precision errors in the following calculations (cone angle is mediump). + highp float cone_angle = spot_lights.data[idx].cone_angle; + float scos = max(dot(-normalize(light_rel_vec), spot_dir), cone_angle); + float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cone_angle)); + spot_attenuation *= 1.0 - pow(spot_rim, spot_lights.data[idx].cone_attenuation); float light_attenuation = spot_attenuation; vec3 color = spot_lights.data[idx].color; diff --git a/servers/rendering/renderer_rd/shaders/skeleton.glsl b/servers/rendering/renderer_rd/shaders/skeleton.glsl index 75bea9300b..f5b233cca0 100644 --- a/servers/rendering/renderer_rd/shaders/skeleton.glsl +++ b/servers/rendering/renderer_rd/shaders/skeleton.glsl @@ -63,7 +63,7 @@ vec3 oct_to_vec3(vec2 oct) { vec3 v = vec3(oct.xy, 1.0 - abs(oct.x) - abs(oct.y)); float t = max(-v.z, 0.0); v.xy += t * -sign(v.xy); - return v; + return normalize(v); } vec3 decode_uint_oct_to_norm(uint base) { @@ -143,8 +143,8 @@ void main() { uint skin_offset = params.skin_stride * index; uvec2 bones = uvec2(src_bone_weights.data[skin_offset + 0], src_bone_weights.data[skin_offset + 1]); - uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 3; //pre-add xform offset - uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 3; + uvec2 bones_01 = uvec2(bones.x & 0xFFFF, bones.x >> 16) * 2; //pre-add xform offset + uvec2 bones_23 = uvec2(bones.y & 0xFFFF, bones.y >> 16) * 2; skin_offset += params.skin_weight_offset; @@ -161,6 +161,13 @@ void main() { //reverse order because its transposed vertex = (vec4(vertex, 0.0, 1.0) * m).xy; } + + uint dst_offset = index * params.vertex_stride; + + uvec2 uvertex = floatBitsToUint(vertex); + dst_vertices.data[dst_offset + 0] = uvertex.x; + dst_vertices.data[dst_offset + 1] = uvertex.y; + #else vec3 vertex; vec3 normal; |