diff options
Diffstat (limited to 'drivers/gles3/shaders')
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 13 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas_uniforms_inc.glsl | 1 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 171 | ||||
-rw-r--r-- | drivers/gles3/shaders/skeleton.glsl | 2 | ||||
-rw-r--r-- | drivers/gles3/shaders/sky.glsl | 37 | ||||
-rw-r--r-- | drivers/gles3/shaders/stdlib_inc.glsl | 18 |
6 files changed, 172 insertions, 70 deletions
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index 65332c06be..e358230747 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -239,13 +239,6 @@ void main() { model_matrix = model_matrix * transpose(mat4(instance_xform0, instance_xform1, vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0))); #endif // USE_INSTANCING -#if !defined(USE_ATTRIBUTES) && !defined(USE_PRIMITIVE) - if (bool(read_draw_data_flags & FLAGS_USING_PARTICLES)) { - //scale by texture size - vertex /= read_draw_data_color_texture_pixel_size; - } -#endif - vec2 color_texture_pixel_size = read_draw_data_color_texture_pixel_size; #ifdef USE_POINT_SIZE @@ -346,14 +339,16 @@ uniform sampler2D color_texture; //texunit:0 layout(location = 0) out vec4 frag_color; +/* clang-format off */ +// This needs to be outside clang-format so the ubo comment is in the right place #ifdef MATERIAL_UNIFORMS_USED -layout(std140) uniform MaterialUniforms{ -//ubo:4 +layout(std140) uniform MaterialUniforms{ //ubo:4 #MATERIAL_UNIFORMS }; #endif +/* clang-format on */ #GLOBALS diff --git a/drivers/gles3/shaders/canvas_uniforms_inc.glsl b/drivers/gles3/shaders/canvas_uniforms_inc.glsl index 21fd4d3d9d..f6ad2b730a 100644 --- a/drivers/gles3/shaders/canvas_uniforms_inc.glsl +++ b/drivers/gles3/shaders/canvas_uniforms_inc.glsl @@ -14,7 +14,6 @@ #define FLAGS_TRANSPOSE_RECT uint(1 << 10) // (1 << 11) is for FLAGS_CONVERT_ATTRIBUTES_TO_LINEAR in RD backends, unused here. #define FLAGS_NINEPACH_DRAW_CENTER uint(1 << 12) -#define FLAGS_USING_PARTICLES uint(1 << 13) #define FLAGS_NINEPATCH_H_MODE_SHIFT 16 #define FLAGS_NINEPATCH_V_MODE_SHIFT 18 diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index be7a6aba57..6143ce2167 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -36,6 +36,7 @@ ADDITIVE_OMNI = false ADDITIVE_SPOT = false RENDER_MATERIAL = false SECOND_REFLECTION_PROBE = false +LIGHTMAP_BICUBIC_FILTER = false #[vertex] @@ -43,6 +44,7 @@ SECOND_REFLECTION_PROBE = false #define M_PI 3.14159265359 #define SHADER_IS_SRGB true +#define SHADER_SPACE_FAR -1.0 #include "stdlib_inc.glsl" @@ -582,6 +584,9 @@ void main() { /* clang-format on */ #define SHADER_IS_SRGB true +#define SHADER_SPACE_FAR -1.0 + +#define FLAGS_NON_UNIFORM_SCALE (1 << 4) /* Varyings */ @@ -869,13 +874,15 @@ uniform lowp uint directional_shadow_index; #if !defined(ADDITIVE_OMNI) float sample_shadow(highp sampler2DShadow shadow, float shadow_pixel_size, vec4 pos) { - float avg = textureProj(shadow, pos); + // Use textureProjLod with LOD set to 0.0 over textureProj, as textureProj not working correctly on ANGLE with Metal backend. + // https://github.com/godotengine/godot/issues/93537 + float avg = textureProjLod(shadow, pos, 0.0); #ifdef SHADOW_MODE_PCF_13 pos /= pos.w; - avg += textureProj(shadow, vec4(pos.xy + vec2(shadow_pixel_size * 2.0, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(-shadow_pixel_size * 2.0, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size * 2.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size * 2.0), pos.zw)); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(shadow_pixel_size * 2.0, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(-shadow_pixel_size * 2.0, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size * 2.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size * 2.0), pos.zw), 0.0); // Early bail if distant samples are fully shaded (or none are shaded) to improve performance. if (avg <= 0.000001) { @@ -886,23 +893,23 @@ float sample_shadow(highp sampler2DShadow shadow, float shadow_pixel_size, vec4 return 1.0; } - avg += textureProj(shadow, vec4(pos.xy + vec2(shadow_pixel_size, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(shadow_pixel_size, shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(shadow_pixel_size, -shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, -shadow_pixel_size), pos.zw)); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(shadow_pixel_size, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(shadow_pixel_size, shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(shadow_pixel_size, -shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, -shadow_pixel_size), pos.zw), 0.0); return avg * (1.0 / 13.0); #endif #ifdef SHADOW_MODE_PCF_5 pos /= pos.w; - avg += textureProj(shadow, vec4(pos.xy + vec2(shadow_pixel_size, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, 0.0), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size), pos.zw)); - avg += textureProj(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size), pos.zw)); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(shadow_pixel_size, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(-shadow_pixel_size, 0.0), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, shadow_pixel_size), pos.zw), 0.0); + avg += textureProjLod(shadow, vec4(pos.xy + vec2(0.0, -shadow_pixel_size), pos.zw), 0.0); return avg * (1.0 / 5.0); #endif @@ -921,6 +928,10 @@ uniform lowp uint lightmap_slice; uniform highp vec4 lightmap_uv_scale; uniform float lightmap_exposure_normalization; +#ifdef LIGHTMAP_BICUBIC_FILTER +uniform highp vec2 lightmap_texture_size; +#endif + #ifdef USE_SH_LIGHTMAP uniform mediump mat3 lightmap_normal_xform; #endif // USE_SH_LIGHTMAP @@ -953,6 +964,7 @@ ivec2 multiview_uv(ivec2 uv) { uniform highp mat4 world_transform; uniform mediump float opaque_prepass_threshold; +uniform highp uint model_flags; #if defined(RENDER_MATERIAL) layout(location = 0) out vec4 albedo_output_buffer; @@ -1412,6 +1424,67 @@ void reflection_process(samplerCube reflection_map, #endif // !MODE_RENDER_DEPTH +#ifdef LIGHTMAP_BICUBIC_FILTER +// w0, w1, w2, and w3 are the four cubic B-spline basis functions +float w0(float a) { + return (1.0 / 6.0) * (a * (a * (-a + 3.0) - 3.0) + 1.0); +} + +float w1(float a) { + return (1.0 / 6.0) * (a * a * (3.0 * a - 6.0) + 4.0); +} + +float w2(float a) { + return (1.0 / 6.0) * (a * (a * (-3.0 * a + 3.0) + 3.0) + 1.0); +} + +float w3(float a) { + return (1.0 / 6.0) * (a * a * a); +} + +// g0 and g1 are the two amplitude functions +float g0(float a) { + return w0(a) + w1(a); +} + +float g1(float a) { + return w2(a) + w3(a); +} + +// h0 and h1 are the two offset functions +float h0(float a) { + return -1.0 + w1(a) / (w0(a) + w1(a)); +} + +float h1(float a) { + return 1.0 + w3(a) / (w2(a) + w3(a)); +} + +vec4 textureArray_bicubic(sampler2DArray tex, vec3 uv, vec2 texture_size) { + vec2 texel_size = vec2(1.0) / texture_size; + + uv.xy = uv.xy * texture_size + vec2(0.5); + + vec2 iuv = floor(uv.xy); + vec2 fuv = fract(uv.xy); + + float g0x = g0(fuv.x); + float g1x = g1(fuv.x); + float h0x = h0(fuv.x); + float h1x = h1(fuv.x); + float h0y = h0(fuv.y); + float h1y = h1(fuv.y); + + vec2 p0 = (vec2(iuv.x + h0x, iuv.y + h0y) - vec2(0.5)) * texel_size; + vec2 p1 = (vec2(iuv.x + h1x, iuv.y + h0y) - vec2(0.5)) * texel_size; + vec2 p2 = (vec2(iuv.x + h0x, iuv.y + h1y) - vec2(0.5)) * texel_size; + vec2 p3 = (vec2(iuv.x + h1x, iuv.y + h1y) - vec2(0.5)) * texel_size; + + return (g0(fuv.y) * (g0x * texture(tex, vec3(p0, uv.z)) + g1x * texture(tex, vec3(p1, uv.z)))) + + (g1(fuv.y) * (g0x * texture(tex, vec3(p2, uv.z)) + g1x * texture(tex, vec3(p3, uv.z)))); +} +#endif //LIGHTMAP_BICUBIC_FILTER + void main() { //lay out everything, whatever is unused is optimized away anyway vec3 vertex = vertex_interp; @@ -1519,6 +1592,13 @@ void main() { vec3 light_vertex = vertex; #endif //LIGHT_VERTEX_USED + highp mat3 model_normal_matrix; + if (bool(model_flags & uint(FLAGS_NON_UNIFORM_SCALE))) { + model_normal_matrix = transpose(inverse(mat3(model_matrix))); + } else { + model_normal_matrix = mat3(model_matrix); + } + { #CODE : FRAGMENT } @@ -1607,6 +1687,7 @@ void main() { #ifdef BASE_PASS /////////////////////// LIGHTING ////////////////////////////// +#ifndef AMBIENT_LIGHT_DISABLED // IBL precalculations float ndotv = clamp(dot(normal, view), 0.0, 1.0); vec3 F = f0 + (max(vec3(1.0 - roughness), f0) - f0) * pow(1.0 - ndotv, 5.0); @@ -1719,43 +1800,45 @@ void main() { #ifdef USE_SH_LIGHTMAP uvw.z *= 4.0; // SH textures use 4 times more data. + +#ifdef LIGHTMAP_BICUBIC_FILTER + vec3 lm_light_l0 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), lightmap_texture_size).rgb; + vec3 lm_light_l1n1 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), lightmap_texture_size).rgb; + vec3 lm_light_l1_0 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), lightmap_texture_size).rgb; + vec3 lm_light_l1p1 = textureArray_bicubic(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), lightmap_texture_size).rgb; +#else vec3 lm_light_l0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 0.0), 0.0).rgb; vec3 lm_light_l1n1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 1.0), 0.0).rgb; vec3 lm_light_l1_0 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 2.0), 0.0).rgb; vec3 lm_light_l1p1 = textureLod(lightmap_textures, uvw + vec3(0.0, 0.0, 3.0), 0.0).rgb; +#endif vec3 n = normalize(lightmap_normal_xform * normal); - ambient_light += lm_light_l0 * 0.282095f; - ambient_light += lm_light_l1n1 * 0.32573 * n.y * lightmap_exposure_normalization; - ambient_light += lm_light_l1_0 * 0.32573 * n.z * lightmap_exposure_normalization; - ambient_light += lm_light_l1p1 * 0.32573 * n.x * lightmap_exposure_normalization; - if (metallic > 0.01) { // Since the more direct bounced light is lost, we can kind of fake it with this trick. - vec3 r = reflect(normalize(-vertex), normal); - specular_light += lm_light_l1n1 * 0.32573 * r.y * lightmap_exposure_normalization; - specular_light += lm_light_l1_0 * 0.32573 * r.z * lightmap_exposure_normalization; - specular_light += lm_light_l1p1 * 0.32573 * r.x * lightmap_exposure_normalization; - } + ambient_light += lm_light_l0 * lightmap_exposure_normalization; + ambient_light += lm_light_l1n1 * n.y * lightmap_exposure_normalization; + ambient_light += lm_light_l1_0 * n.z * lightmap_exposure_normalization; + ambient_light += lm_light_l1p1 * n.x * lightmap_exposure_normalization; +#else +#ifdef LIGHTMAP_BICUBIC_FILTER + ambient_light += textureArray_bicubic(lightmap_textures, uvw, lightmap_texture_size).rgb * lightmap_exposure_normalization; #else ambient_light += textureLod(lightmap_textures, uvw, 0.0).rgb * lightmap_exposure_normalization; #endif +#endif } #endif // USE_LIGHTMAP #endif // USE_LIGHTMAP_CAPTURE #endif // !DISABLE_LIGHTMAP - { -#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 - } + 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); - +#ifndef AMBIENT_LIGHT_DISABLED { #if defined(DIFFUSE_TOON) //simplify for toon, as @@ -1777,6 +1860,8 @@ void main() { #endif } +#endif // !AMBIENT_LIGHT_DISABLED + #ifndef DISABLE_LIGHT_DIRECTIONAL for (uint i = uint(0); i < scene_data.directional_light_count; i++) { #if defined(USE_LIGHTMAP) && !defined(DISABLE_LIGHTMAP) @@ -1869,7 +1954,7 @@ void main() { alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0)); #if defined(ALPHA_SCISSOR_USED) - if (alpha < alpha_scissor) { + if (alpha < alpha_scissor_threshold) { discard; } #endif // !ALPHA_SCISSOR_USED @@ -1920,11 +2005,7 @@ void main() { fog.xy = unpackHalf2x16(fog_rg); fog.zw = unpackHalf2x16(fog_ba); -#ifndef DISABLE_FOG - if (scene_data.fog_enabled) { - frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); - } -#endif // !DISABLE_FOG + frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a); #endif // !FOG_DISABLED // Tonemap before writing as we are writing to an sRGB framebuffer @@ -2131,11 +2212,7 @@ void main() { fog.xy = unpackHalf2x16(fog_rg); fog.zw = unpackHalf2x16(fog_ba); -#ifndef DISABLE_FOG - if (scene_data.fog_enabled) { - additive_light_color *= (1.0 - fog.a); - } -#endif // !DISABLE_FOG + additive_light_color *= (1.0 - fog.a); #endif // !FOG_DISABLED // Tonemap before writing as we are writing to an sRGB framebuffer diff --git a/drivers/gles3/shaders/skeleton.glsl b/drivers/gles3/shaders/skeleton.glsl index aad856a5a2..66befbc3b2 100644 --- a/drivers/gles3/shaders/skeleton.glsl +++ b/drivers/gles3/shaders/skeleton.glsl @@ -59,7 +59,7 @@ layout(location = 10) in highp uvec4 in_bone_attrib; layout(location = 11) in mediump vec4 in_weight_attrib; #endif -uniform mediump sampler2D skeleton_texture; // texunit:0 +uniform highp sampler2D skeleton_texture; // texunit:0 #endif /* clang-format on */ diff --git a/drivers/gles3/shaders/sky.glsl b/drivers/gles3/shaders/sky.glsl index 9de65ba960..f734e4b355 100644 --- a/drivers/gles3/shaders/sky.glsl +++ b/drivers/gles3/shaders/sky.glsl @@ -108,11 +108,11 @@ uniform float sky_energy_multiplier; uniform float luminance_multiplier; uniform float fog_aerial_perspective; -uniform vec3 fog_light_color; +uniform vec4 fog_light_color; uniform float fog_sun_scatter; uniform bool fog_enabled; uniform float fog_density; -uniform float z_far; +uniform float fog_sky_affect; uniform uint directional_light_count; #ifdef USE_MULTIVIEW @@ -135,6 +135,24 @@ vec3 interleaved_gradient_noise(vec2 pos) { } #endif +#if !defined(DISABLE_FOG) +vec4 fog_process(vec3 view, vec3 sky_color) { + vec3 fog_color = mix(fog_light_color.rgb, sky_color, fog_aerial_perspective); + + if (fog_sun_scatter > 0.001) { + vec4 sun_scatter = vec4(0.0); + float sun_total = 0.0; + for (uint i = 0u; i < 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 * fog_sun_scatter; + } + } + + return vec4(fog_color, 1.0); +} +#endif // !DISABLE_FOG + void main() { vec3 cube_normal; #ifdef USE_MULTIVIEW @@ -203,6 +221,21 @@ void main() { // Convert to Linear for tonemapping so color matches scene shader better color = srgb_to_linear(color); + +#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 (fog_enabled) { + vec4 fog = fog_process(cube_normal, color.rgb); + color.rgb = mix(color.rgb, fog.rgb, fog.a * fog_sky_affect); + } + + if (custom_fog.a > 0.0) { + color.rgb = mix(color.rgb, custom_fog.rgb, custom_fog.a); + } + +#endif // DISABLE_FOG + color *= exposure; #ifdef APPLY_TONEMAPPING color = apply_tonemapping(color, white); diff --git a/drivers/gles3/shaders/stdlib_inc.glsl b/drivers/gles3/shaders/stdlib_inc.glsl index 029084c34c..f88c218506 100644 --- a/drivers/gles3/shaders/stdlib_inc.glsl +++ b/drivers/gles3/shaders/stdlib_inc.glsl @@ -9,19 +9,17 @@ // Floating point pack/unpack functions are part of the GLSL ES 300 specification used by web and mobile. uint float2half(uint f) { - uint e = f & uint(0x7f800000); - if (e <= uint(0x38000000)) { - return uint(0); - } else { - return ((f >> uint(16)) & uint(0x8000)) | - (((e - uint(0x38000000)) >> uint(13)) & uint(0x7c00)) | - ((f >> uint(13)) & uint(0x03ff)); - } + uint b = f + uint(0x00001000); + uint e = (b & uint(0x7F800000)) >> 23; + uint m = b & uint(0x007FFFFF); + return (b & uint(0x80000000)) >> uint(16) | uint(e > uint(112)) * ((((e - uint(112)) << uint(10)) & uint(0x7C00)) | m >> uint(13)) | (uint(e < uint(113)) & uint(e > uint(101))) * ((((uint(0x007FF000) + m) >> (uint(125) - e)) + uint(1)) >> uint(1)) | uint(e > uint(143)) * uint(0x7FFF); } uint half2float(uint h) { - uint h_e = h & uint(0x7c00); - return ((h & uint(0x8000)) << uint(16)) | uint((h_e >> uint(10)) != uint(0)) * (((h_e + uint(0x1c000)) << uint(13)) | ((h & uint(0x03ff)) << uint(13))); + uint e = (h & uint(0x7C00)) >> uint(10); + uint m = (h & uint(0x03FF)) << uint(13); + uint v = m >> uint(23); + return (h & uint(0x8000)) << uint(16) | uint(e != uint(0)) * ((e + uint(112)) << uint(23) | m) | (uint(e == uint(0)) & uint(m != uint(0))) * ((v - uint(37)) << uint(23) | ((m << (uint(150) - v)) & uint(0x007FE000))); } uint godot_packHalf2x16(vec2 v) { |