diff options
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
8 files changed, 244 insertions, 279 deletions
diff --git a/servers/rendering/renderer_rd/shaders/blit.glsl b/servers/rendering/renderer_rd/shaders/blit.glsl index d451647bec..fe6416f03c 100644 --- a/servers/rendering/renderer_rd/shaders/blit.glsl +++ b/servers/rendering/renderer_rd/shaders/blit.glsl @@ -8,6 +8,10 @@ layout(push_constant, std140) uniform Pos { vec4 src_rect; vec4 dst_rect; + float rotation_sin; + float rotation_cos; + vec2 pad; + vec2 eye_center; float k1; float k2; @@ -15,17 +19,23 @@ layout(push_constant, std140) uniform Pos { float upscale; float aspect_ratio; uint layer; - uint pad1; + bool convert_to_srgb; } data; layout(location = 0) out vec2 uv; void main() { + mat4 swapchain_transform = mat4(1.0); + swapchain_transform[0][0] = data.rotation_cos; + swapchain_transform[0][1] = -data.rotation_sin; + swapchain_transform[1][0] = data.rotation_sin; + swapchain_transform[1][1] = data.rotation_cos; + vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv = data.src_rect.xy + base_arr[gl_VertexIndex] * data.src_rect.zw; vec2 vtx = data.dst_rect.xy + base_arr[gl_VertexIndex] * data.dst_rect.zw; - gl_Position = vec4(vtx * 2.0 - 1.0, 0.0, 1.0); + gl_Position = swapchain_transform * vec4(vtx * 2.0 - 1.0, 0.0, 1.0); } #[fragment] @@ -38,6 +48,10 @@ layout(push_constant, std140) uniform Pos { vec4 src_rect; vec4 dst_rect; + float rotation_sin; + float rotation_cos; + vec2 pad; + vec2 eye_center; float k1; float k2; diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index dafcce37ad..f665bc24a4 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -28,7 +28,7 @@ layout(location = 11) in vec4 weight_attrib; layout(location = 4) out flat uint instance_index_interp; -#endif // USE_ATTRIBUTES +#endif // !USE_ATTRIBUTES layout(location = 0) out vec2 uv_interp; layout(location = 1) out vec4 color_interp; @@ -322,11 +322,7 @@ vec4 light_compute( #ifdef USE_NINEPATCH float map_ninepatch_axis(float pixel, float draw_size, float tex_pixel_size, float margin_begin, float margin_end, int np_repeat, inout int draw_center) { -#ifdef USE_ATTRIBUTES - const InstanceData draw_data = instances.data[params.base_instance_index]; -#else const InstanceData draw_data = instances.data[instance_index]; -#endif // USE_ATTRIBUTES float tex_size = 1.0 / tex_pixel_size; @@ -567,7 +563,7 @@ void main() { if (specular_shininess_used || (using_light && normal_used && bool(draw_data.flags & FLAGS_DEFAULT_SPECULAR_MAP_USED))) { specular_shininess = texture(sampler2D(specular_texture, texture_sampler), uv); - specular_shininess *= unpackUnorm4x8(draw_data.specular_shininess); + specular_shininess *= unpackUnorm4x8(params.specular_shininess); specular_shininess_used = true; } else { specular_shininess = vec4(1.0); diff --git a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl index ead8c459a4..84017a1fe1 100644 --- a/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas_uniforms_inc.glsl @@ -37,7 +37,7 @@ struct InstanceData { vec2 world_y; vec2 world_ofs; uint flags; - uint specular_shininess; + uint pad2; #ifdef USE_PRIMITIVE vec2 points[3]; vec2 uvs[3]; @@ -57,8 +57,8 @@ struct InstanceData { layout(push_constant, std430) uniform Params { uint base_instance_index; // base index to instance data uint sc_packed_0; - uint pad2; - uint pad3; + uint specular_shininess; + uint pad; } params; @@ -68,7 +68,7 @@ params; // Pull the constants from the draw call's push constants. uint sc_packed_0() { - return draw_call.sc_packed_0; + return params.sc_packed_0; } #else diff --git a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl index 3fb93dda35..b45e310b61 100644 --- a/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl +++ b/servers/rendering/renderer_rd/shaders/effects/cube_to_dp.glsl @@ -8,7 +8,6 @@ layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; - vec4 screen_rect; } params; @@ -17,8 +16,7 @@ layout(location = 0) out vec2 uv_interp; void main() { vec2 base_arr[4] = vec2[](vec2(0.0, 0.0), vec2(0.0, 1.0), vec2(1.0, 1.0), vec2(1.0, 0.0)); uv_interp = base_arr[gl_VertexIndex]; - vec2 screen_pos = uv_interp * params.screen_rect.zw + params.screen_rect.xy; - gl_Position = vec4(screen_pos * 2.0 - 1.0, 0.0, 1.0); + gl_Position = vec4(uv_interp * 2.0 - 1.0, 0.0, 1.0); } #[fragment] @@ -35,7 +33,6 @@ layout(push_constant, std430) uniform Params { float z_far; float z_near; vec2 texel_size; - vec4 screen_rect; } params; 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 72236dcd9f..81d3d87a22 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 @@ -211,6 +211,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec } #endif +uint multimesh_stride() { + uint stride = sc_multimesh_format_2d() ? 2 : 3; + stride += sc_multimesh_has_color() ? 1 : 0; + stride += sc_multimesh_has_custom_data() ? 1 : 0; + return stride; +} + void vertex_shader(vec3 vertex_input, #ifdef NORMAL_USED in vec3 normal_input, @@ -219,7 +226,7 @@ void vertex_shader(vec3 vertex_input, in vec3 tangent_input, in vec3 binormal_input, #endif - in uint instance_index, in bool is_multimesh, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { + in uint instance_index, in uint multimesh_offset, in SceneData scene_data, in mat4 model_matrix, out vec4 screen_pos) { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) color_interp = color_attrib; @@ -248,7 +255,7 @@ void vertex_shader(vec3 vertex_input, mat4 matrix; mat4 read_model_matrix = model_matrix; - if (is_multimesh) { + if (sc_multimesh()) { //multimesh, instances are for it #ifdef USE_PARTICLE_TRAILS @@ -296,25 +303,10 @@ void vertex_shader(vec3 vertex_input, #endif #else - uint stride = 0; - { - //TODO implement a small lookup table for the stride - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { - stride += 2; - } else { - stride += 3; - } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { - stride += 1; - } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { - stride += 1; - } - } - + uint stride = multimesh_stride(); uint offset = stride * (gl_InstanceIndex + multimesh_offset); - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (sc_multimesh_format_2d()) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -322,14 +314,14 @@ void vertex_shader(vec3 vertex_input, offset += 3; } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (sc_multimesh_has_color()) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (sc_multimesh_has_custom_data()) { instance_custom = transforms.data[offset]; } @@ -427,7 +419,7 @@ void vertex_shader(vec3 vertex_input, // Then we combine the translations from the model matrix and the view matrix using emulated doubles. // We add the result to the vertex and ignore the final lost precision. vec3 model_origin = model_matrix[3].xyz; - if (is_multimesh) { + if (sc_multimesh()) { vertex = mat3(matrix) * vertex; model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); } @@ -708,9 +700,7 @@ void _unpack_vertex_attributes(vec4 p_vertex_in, vec3 p_compressed_aabb_position void main() { uint instance_index = draw_call.instance_index; - - bool is_multimesh = bool(instances.data[instance_index].flags & INSTANCE_FLAGS_MULTIMESH); - if (!is_multimesh) { + if (!sc_multimesh()) { instance_index += gl_InstanceIndex; } @@ -753,7 +743,7 @@ void main() { prev_tangent, prev_binormal, #endif - instance_index, is_multimesh, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); + instance_index, draw_call.multimesh_motion_vectors_previous_offset, scene_data_block.prev_data, instances.data[instance_index].prev_transform, prev_screen_position); #else // Unused output. vec4 screen_position; @@ -792,7 +782,7 @@ void main() { tangent, binormal, #endif - instance_index, is_multimesh, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); + instance_index, draw_call.multimesh_motion_vectors_current_offset, scene_data_block.data, model_matrix, screen_position); } #[fragment] 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 9f68d59be2..8f153f7ed5 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 @@ -59,6 +59,10 @@ uint sc_packed_0() { return draw_call.sc_packed_0; } +uint sc_packed_1() { + return draw_call.sc_packed_1; +} + uint uc_cull_mode() { return (draw_call.uc_packed_0 >> 0) & 3U; } @@ -67,11 +71,16 @@ uint uc_cull_mode() { // Pull the constants from the pipeline's specialization constants. layout(constant_id = 0) const uint pso_sc_packed_0 = 0; +layout(constant_id = 1) const uint pso_sc_packed_1 = 0; uint sc_packed_0() { return pso_sc_packed_0; } +uint sc_packed_1() { + return pso_sc_packed_1; +} + #endif bool sc_use_forward_gi() { @@ -107,19 +116,35 @@ bool sc_use_lightmap_bicubic_filter() { } uint sc_soft_shadow_samples() { - return (sc_packed_0() >> 8) & 15U; + return (sc_packed_0() >> 8) & 63U; } uint sc_penumbra_shadow_samples() { - return (sc_packed_0() >> 12) & 15U; + return (sc_packed_0() >> 14) & 63U; } uint sc_directional_soft_shadow_samples() { - return (sc_packed_0() >> 16) & 15U; + return (sc_packed_0() >> 20) & 63U; } uint sc_directional_penumbra_shadow_samples() { - return (sc_packed_0() >> 20) & 15U; + return (sc_packed_0() >> 26) & 63U; +} + +bool sc_multimesh() { + return ((sc_packed_1() >> 0) & 1U) != 0; +} + +bool sc_multimesh_format_2d() { + return ((sc_packed_1() >> 1) & 1U) != 0; +} + +bool sc_multimesh_has_color() { + return ((sc_packed_1() >> 2) & 1U) != 0; +} + +bool sc_multimesh_has_custom_data() { + return ((sc_packed_1() >> 3) & 1U) != 0; } float sc_luminance_multiplier() { @@ -144,10 +169,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #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) -#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15) #define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16 #define INSTANCE_FLAGS_FADE_SHIFT 24 //3 bits of stride 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 2f0e4e0bea..404f658fa6 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 @@ -178,6 +178,13 @@ vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec } #endif +uint multimesh_stride() { + uint stride = sc_multimesh_format_2d() ? 2 : 3; + stride += sc_multimesh_has_color() ? 1 : 0; + stride += sc_multimesh_has_custom_data() ? 1 : 0; + return stride; +} + void main() { vec4 instance_custom = vec4(0.0); #if defined(COLOR_USED) @@ -208,7 +215,7 @@ void main() { mat4 matrix; mat4 read_model_matrix = model_matrix; - if (sc_is_multimesh()) { + if (sc_multimesh()) { //multimesh, instances are for it #ifdef USE_PARTICLE_TRAILS @@ -256,25 +263,10 @@ void main() { #endif #else - uint stride = 0; - { - //TODO implement a small lookup table for the stride - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { - stride += 2; - } else { - stride += 3; - } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { - stride += 1; - } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { - stride += 1; - } - } - + uint stride = multimesh_stride(); uint offset = stride * gl_InstanceIndex; - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_FORMAT_2D)) { + if (sc_multimesh_format_2d()) { matrix = mat4(transforms.data[offset + 0], transforms.data[offset + 1], vec4(0.0, 0.0, 1.0, 0.0), vec4(0.0, 0.0, 0.0, 1.0)); offset += 2; } else { @@ -282,14 +274,14 @@ void main() { offset += 3; } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_COLOR)) { + if (sc_multimesh_has_color()) { #ifdef COLOR_USED color_interp *= transforms.data[offset]; #endif offset += 1; } - if (bool(instances.data[draw_call.instance_index].flags & INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA)) { + if (sc_multimesh_has_custom_data()) { instance_custom = transforms.data[offset]; } @@ -404,7 +396,7 @@ void main() { // Then we combine the translations from the model matrix and the view matrix using emulated doubles. // We add the result to the vertex and ignore the final lost precision. vec3 model_origin = model_matrix[3].xyz; - if (sc_is_multimesh()) { + if (sc_multimesh()) { vertex = mat3(matrix) * vertex; model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision); } @@ -461,50 +453,24 @@ void main() { diffuse_light_interp = vec4(0.0); specular_light_interp = vec4(0.0); - if (!sc_disable_omni_lights()) { - uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].omni_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } - - light_process_omni_vertex(light_index, vertex, view, normal, roughness, - diffuse_light_interp.rgb, specular_light_interp.rgb); - } + uvec2 omni_light_indices = instances.data[draw_call.instance_index].omni_lights; + for (uint i = 0; i < sc_omni_lights(); i++) { + uint light_index = (i > 3) ? ((omni_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_light_indices.x >> (i * 8)) & 0xFF); + light_process_omni_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb); } - if (!sc_disable_spot_lights()) { - uint light_indices = instances.data[draw_call.instance_index].spot_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].spot_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } - - light_process_spot_vertex(light_index, vertex, view, normal, roughness, - diffuse_light_interp.rgb, specular_light_interp.rgb); - } + uvec2 spot_light_indices = instances.data[draw_call.instance_index].spot_lights; + for (uint i = 0; i < sc_spot_lights(); i++) { + uint light_index = (i > 3) ? ((spot_light_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_light_indices.x >> (i * 8)) & 0xFF); + light_process_spot_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb); } - if (!sc_disable_directional_lights()) { + if (sc_directional_lights() > 0) { // We process the first directional light separately as it may have shadows. vec3 directional_diffuse = vec3(0.0); vec3 directional_specular = vec3(0.0); - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; // Not masked, skip. } @@ -823,7 +789,7 @@ vec4 fog_process(vec3 vertex) { float sun_total = 0.0; vec3 view = normalize(vertex); - for (uint i = 0; i < scene_data_block.data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { vec3 light_color = directional_lights.data[i].color * directional_lights.data[i].energy; float light_amount = pow(max(dot(view, directional_lights.data[i].direction), 0.0), 8.0); fog_color += light_color * light_amount * scene_data_block.data.fog_sun_scatter; @@ -1110,97 +1076,83 @@ void main() { vec3 vertex_ddx = dFdx(vertex); vec3 vertex_ddy = dFdy(vertex); - if (!sc_disable_decals()) { //Decals - // must implement - - uint decal_indices = instances.data[draw_call.instance_index].decals.x; - for (uint i = 0; i < 8; i++) { - uint decal_index = decal_indices & 0xFF; - if (i == 3) { - decal_indices = instances.data[draw_call.instance_index].decals.y; - } else { - decal_indices = decal_indices >> 8; - } + uvec2 decal_indices = instances.data[draw_call.instance_index].decals; + for (uint i = 0; i < sc_decals(); i++) { + uint decal_index = (i > 3) ? ((decal_indices.y >> ((i - 4) * 8)) & 0xFF) : ((decal_indices.x >> (i * 8)) & 0xFF); + if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) { + continue; //not masked + } - if (decal_index == 0xFF) { - break; - } + vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; + if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { + continue; //out of decal + } - if (!bool(decals.data[decal_index].mask & instances.data[draw_call.instance_index].layer_mask)) { - continue; //not masked - } + float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); - vec3 uv_local = (decals.data[decal_index].xform * vec4(vertex, 1.0)).xyz; - if (any(lessThan(uv_local, vec3(0.0, -1.0, 0.0))) || any(greaterThan(uv_local, vec3(1.0)))) { - continue; //out of decal - } + if (decals.data[decal_index].normal_fade > 0.0) { + fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + } - float fade = pow(1.0 - (uv_local.y > 0.0 ? uv_local.y : -uv_local.y), uv_local.y > 0.0 ? decals.data[decal_index].upper_fade : decals.data[decal_index].lower_fade); + //we need ddx/ddy for mipmaps, so simulate them + vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; + vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; - if (decals.data[decal_index].normal_fade > 0.0) { - fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(normal_interp, decals.data[decal_index].normal) * 0.5 + 0.5); + if (decals.data[decal_index].albedo_rect != vec4(0.0)) { + //has albedo + vec4 decal_albedo; + if (sc_decal_use_mipmaps()) { + decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + } else { + decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0); } + decal_albedo *= decals.data[decal_index].modulate; + decal_albedo.a *= fade; + albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); - //we need ddx/ddy for mipmaps, so simulate them - vec2 ddx = (decals.data[decal_index].xform * vec4(vertex_ddx, 0.0)).xz; - vec2 ddy = (decals.data[decal_index].xform * vec4(vertex_ddy, 0.0)).xz; - - if (decals.data[decal_index].albedo_rect != vec4(0.0)) { - //has albedo - vec4 decal_albedo; + if (decals.data[decal_index].normal_rect != vec4(0.0)) { + vec3 decal_normal; if (sc_decal_use_mipmaps()) { - decal_albedo = textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, ddx * decals.data[decal_index].albedo_rect.zw, ddy * decals.data[decal_index].albedo_rect.zw); + decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; } else { - decal_albedo = textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].albedo_rect.zw + decals.data[decal_index].albedo_rect.xy, 0.0); - } - decal_albedo *= decals.data[decal_index].modulate; - decal_albedo.a *= fade; - albedo = mix(albedo, decal_albedo.rgb, decal_albedo.a * decals.data[decal_index].albedo_mix); - - if (decals.data[decal_index].normal_rect != vec4(0.0)) { - vec3 decal_normal; - if (sc_decal_use_mipmaps()) { - decal_normal = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, ddx * decals.data[decal_index].normal_rect.zw, ddy * decals.data[decal_index].normal_rect.zw).xyz; - } else { - decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz; - } - decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software - decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); - //convert to view space, use xzy because y is up - decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; - - normal = normalize(mix(normal, decal_normal, decal_albedo.a)); + decal_normal = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].normal_rect.zw + decals.data[decal_index].normal_rect.xy, 0.0).xyz; } + decal_normal.xy = decal_normal.xy * vec2(2.0, -2.0) - vec2(1.0, -1.0); //users prefer flipped y normal maps in most authoring software + decal_normal.z = sqrt(max(0.0, 1.0 - dot(decal_normal.xy, decal_normal.xy))); + //convert to view space, use xzy because y is up + decal_normal = (decals.data[decal_index].normal_xform * decal_normal.xzy).xyz; - if (decals.data[decal_index].orm_rect != vec4(0.0)) { - vec3 decal_orm; - if (sc_decal_use_mipmaps()) { - decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; - } else { - decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz; - } - ao = mix(ao, decal_orm.r, decal_albedo.a); - roughness = mix(roughness, decal_orm.g, decal_albedo.a); - metallic = mix(metallic, decal_orm.b, decal_albedo.a); - } + normal = normalize(mix(normal, decal_normal, decal_albedo.a)); } - if (decals.data[decal_index].emission_rect != vec4(0.0)) { - //emission is additive, so its independent from albedo + if (decals.data[decal_index].orm_rect != vec4(0.0)) { + vec3 decal_orm; if (sc_decal_use_mipmaps()) { - emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + decal_orm = textureGrad(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, ddx * decals.data[decal_index].orm_rect.zw, ddy * decals.data[decal_index].orm_rect.zw).xyz; } else { - emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; + decal_orm = textureLod(sampler2D(decal_atlas, decal_sampler), uv_local.xz * decals.data[decal_index].orm_rect.zw + decals.data[decal_index].orm_rect.xy, 0.0).xyz; } + ao = mix(ao, decal_orm.r, decal_albedo.a); + roughness = mix(roughness, decal_orm.g, decal_albedo.a); + metallic = mix(metallic, decal_orm.b, decal_albedo.a); + } + } + + if (decals.data[decal_index].emission_rect != vec4(0.0)) { + //emission is additive, so its independent from albedo + if (sc_decal_use_mipmaps()) { + emission += textureGrad(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, ddx * decals.data[decal_index].emission_rect.zw, ddy * decals.data[decal_index].emission_rect.zw).xyz * decals.data[decal_index].emission_energy * fade; + } else { + emission += textureLod(sampler2D(decal_atlas_srgb, decal_sampler), uv_local.xz * decals.data[decal_index].emission_rect.zw + decals.data[decal_index].emission_rect.xy, 0.0).xyz * decals.data[decal_index].emission_energy * fade; } } - } //Decals + } #endif //!MODE_RENDER_DEPTH /////////////////////// LIGHTING ////////////////////////////// #ifdef NORMAL_USED - if (scene_data.roughness_limiter_enabled) { + if (sc_scene_roughness_limiter_enabled()) { //https://www.jp.square-enix.com/tech/library/pdf/ImprovedGeometricSpecularAA.pdf float roughness2 = roughness * roughness; vec3 dndu = dFdx(normal), dndv = dFdy(normal); @@ -1225,7 +1177,7 @@ void main() { #ifndef AMBIENT_LIGHT_DISABLED - if (scene_data.use_reflection_cubemap) { + if (sc_scene_use_reflection_cubemap()) { #ifdef LIGHT_ANISOTROPY_USED // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; @@ -1266,7 +1218,7 @@ void main() { if (scene_data.use_ambient_light) { ambient_light = scene_data.ambient_light_color_energy.rgb; - if (scene_data.use_ambient_cubemap) { + if (sc_scene_use_ambient_cubemap()) { vec3 ambient_dir = scene_data.radiance_inverse_xform * normal; #ifdef USE_RADIANCE_CUBEMAP_ARRAY vec3 cubemap_ambient = texture(samplerCubeArray(radiance_cubemap, DEFAULT_SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP), vec4(ambient_dir, MAX_ROUGHNESS_LOD)).rgb; @@ -1285,7 +1237,7 @@ void main() { #endif // CUSTOM_IRRADIANCE_USED #ifdef LIGHT_CLEARCOAT_USED - if (scene_data.use_reflection_cubemap) { + if (sc_scene_use_reflection_cubemap()) { vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map float NoV = max(dot(n, view), 0.0001); vec3 ref_vec = reflect(-view, n); @@ -1393,12 +1345,10 @@ void main() { // skipping ssao, do we remove ssao totally? - if (!sc_disable_reflection_probes()) { //Reflection probes + if (sc_reflection_probes() > 0) { vec4 reflection_accum = vec4(0.0, 0.0, 0.0, 0.0); vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0); - uint reflection_indices = instances.data[draw_call.instance_index].reflection_probes.x; - #ifdef LIGHT_ANISOTROPY_USED // https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent; @@ -1411,18 +1361,9 @@ void main() { vec3 ref_vec = normalize(reflect(-view, bent_normal)); ref_vec = mix(ref_vec, bent_normal, roughness * roughness); - for (uint i = 0; i < 8; i++) { - uint reflection_index = reflection_indices & 0xFF; - if (i == 3) { - reflection_indices = instances.data[draw_call.instance_index].reflection_probes.y; - } else { - reflection_indices = reflection_indices >> 8; - } - - if (reflection_index == 0xFF) { - break; - } - + uvec2 reflection_indices = instances.data[draw_call.instance_index].reflection_probes; + for (uint i = 0; i < sc_reflection_probes(); i++) { + uint reflection_index = (i > 3) ? ((reflection_indices.y >> ((i - 4) * 8)) & 0xFF) : ((reflection_indices.x >> (i * 8)) & 0xFF); reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum); } @@ -1487,7 +1428,7 @@ void main() { specular_light += specular_light_interp.rgb * f0; #endif - if (!sc_disable_directional_lights()) { //directional light + if (sc_directional_lights() > 0) { #ifndef SHADOWS_DISABLED // Do shadow and lighting in two passes to reduce register pressure uint shadow0 = 0; @@ -1497,7 +1438,7 @@ void main() { // Only process the first light's shadow for vertex lighting. for (uint i = 0; i < 1; i++) { #else - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { #endif if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { @@ -1612,7 +1553,7 @@ void main() { #endif // SHADOWS_DISABLED #ifndef USE_VERTEX_LIGHTING - for (uint i = 0; i < scene_data.directional_light_count; i++) { + for (uint i = 0; i < sc_directional_lights(); i++) { if (!bool(directional_lights.data[i].mask & instances.data[draw_call.instance_index].layer_mask)) { continue; //not masked } @@ -1678,95 +1619,72 @@ void main() { } //directional light #ifndef USE_VERTEX_LIGHTING - if (!sc_disable_omni_lights()) { //omni lights - uint light_indices = instances.data[draw_call.instance_index].omni_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].omni_lights.y; - } else { - light_indices = light_indices >> 8; - } - - if (light_index == 0xFF) { - break; - } + uvec2 omni_indices = instances.data[draw_call.instance_index].omni_lights; + for (uint i = 0; i < sc_omni_lights(); i++) { + uint light_index = (i > 3) ? ((omni_indices.y >> ((i - 4) * 8)) & 0xFF) : ((omni_indices.x >> (i * 8)) & 0xFF); - float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); + float shadow = light_process_omni_shadow(light_index, vertex, normal, scene_data.taa_frame_count); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - // Fragment lighting - light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, + // Fragment lighting + light_process_omni(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif /* #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif */ #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_roughness, normalize(normal_interp), + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, - binormal, anisotropy, + tangent, + binormal, anisotropy, #endif - diffuse_light, specular_light); - } - } //omni lights - - if (!sc_disable_spot_lights()) { //spot lights - - uint light_indices = instances.data[draw_call.instance_index].spot_lights.x; - for (uint i = 0; i < 8; i++) { - uint light_index = light_indices & 0xFF; - if (i == 3) { - light_indices = instances.data[draw_call.instance_index].spot_lights.y; - } else { - light_indices = light_indices >> 8; - } + diffuse_light, specular_light); + } - if (light_index == 0xFF) { - break; - } + uvec2 spot_indices = instances.data[draw_call.instance_index].spot_lights; + for (uint i = 0; i < sc_spot_lights(); i++) { + uint light_index = (i > 3) ? ((spot_indices.y >> ((i - 4) * 8)) & 0xFF) : ((spot_indices.x >> (i * 8)) & 0xFF); - float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); + float shadow = light_process_spot_shadow(light_index, vertex, normal, scene_data.taa_frame_count); - shadow = blur_shadow(shadow); + shadow = blur_shadow(shadow); - light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, + light_process_spot(light_index, vertex, view, normal, vertex_ddx, vertex_ddy, f0, orms, shadow, albedo, alpha, #ifdef LIGHT_BACKLIGHT_USED - backlight, + backlight, #endif /* #ifdef LIGHT_TRANSMITTANCE_USED - transmittance_color, - transmittance_depth, - transmittance_boost, + transmittance_color, + transmittance_depth, + transmittance_boost, #endif */ #ifdef LIGHT_RIM_USED - rim, - rim_tint, + rim, + rim_tint, #endif #ifdef LIGHT_CLEARCOAT_USED - clearcoat, clearcoat_roughness, normalize(normal_interp), + clearcoat, clearcoat_roughness, normalize(normal_interp), #endif #ifdef LIGHT_ANISOTROPY_USED - tangent, - binormal, anisotropy, + tangent, + binormal, anisotropy, #endif - diffuse_light, specular_light); - } - } //spot lights + diffuse_light, specular_light); + } #endif // !VERTEX_LIGHTING #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) 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 495e52a29e..2cc86482f6 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 @@ -22,8 +22,8 @@ layout(push_constant, std430) uniform DrawCall { uint pad; #ifdef UBERSHADER uint sc_packed_0; - float sc_packed_1; - uint sc_packed_2; + uint sc_packed_1; + float sc_packed_2; uint uc_packed_0; #endif } @@ -42,10 +42,14 @@ uint sc_packed_0() { return draw_call.sc_packed_0; } -float sc_packed_1() { +uint sc_packed_1() { return draw_call.sc_packed_1; } +float sc_packed_2() { + return draw_call.sc_packed_2; +} + uint uc_cull_mode() { return (draw_call.uc_packed_0 >> 0) & 3U; } @@ -54,16 +58,21 @@ uint uc_cull_mode() { // Pull the constants from the pipeline's specialization constants. layout(constant_id = 0) const uint pso_sc_packed_0 = 0; -layout(constant_id = 1) const float pso_sc_packed_1 = 2.0; +layout(constant_id = 1) const uint pso_sc_packed_1 = 0; +layout(constant_id = 2) const float pso_sc_packed_2 = 2.0; uint sc_packed_0() { return pso_sc_packed_0; } -float sc_packed_1() { +uint sc_packed_1() { return pso_sc_packed_1; } +float sc_packed_2() { + return pso_sc_packed_2; +} + #endif bool sc_use_light_projector() { @@ -86,60 +95,84 @@ bool sc_projector_use_mipmaps() { return ((sc_packed_0() >> 4) & 1U) != 0; } -bool sc_disable_omni_lights() { +bool sc_disable_fog() { return ((sc_packed_0() >> 5) & 1U) != 0; } -bool sc_disable_spot_lights() { +bool sc_use_depth_fog() { return ((sc_packed_0() >> 6) & 1U) != 0; } -bool sc_disable_reflection_probes() { +bool sc_use_lightmap_bicubic_filter() { return ((sc_packed_0() >> 7) & 1U) != 0; } -bool sc_disable_directional_lights() { +bool sc_multimesh() { return ((sc_packed_0() >> 8) & 1U) != 0; } -bool sc_disable_decals() { +bool sc_multimesh_format_2d() { return ((sc_packed_0() >> 9) & 1U) != 0; } -bool sc_disable_fog() { +bool sc_multimesh_has_color() { return ((sc_packed_0() >> 10) & 1U) != 0; } -bool sc_use_depth_fog() { +bool sc_multimesh_has_custom_data() { return ((sc_packed_0() >> 11) & 1U) != 0; } -bool sc_is_multimesh() { +bool sc_scene_use_ambient_cubemap() { return ((sc_packed_0() >> 12) & 1U) != 0; } -bool sc_use_lightmap_bicubic_filter() { +bool sc_scene_use_reflection_cubemap() { return ((sc_packed_0() >> 13) & 1U) != 0; } +bool sc_scene_roughness_limiter_enabled() { + return ((sc_packed_0() >> 14) & 1U) != 0; +} + uint sc_soft_shadow_samples() { - return (sc_packed_0() >> 16) & 15U; + return (sc_packed_0() >> 20) & 63U; } uint sc_penumbra_shadow_samples() { - return (sc_packed_0() >> 20) & 15U; + return (sc_packed_0() >> 26) & 63U; } uint sc_directional_soft_shadow_samples() { - return (sc_packed_0() >> 24) & 15U; + return (sc_packed_1() >> 0) & 63U; } uint sc_directional_penumbra_shadow_samples() { - return (sc_packed_0() >> 28) & 15U; + return (sc_packed_1() >> 6) & 63U; +} + +uint sc_omni_lights() { + return (sc_packed_1() >> 12) & 15U; +} + +uint sc_spot_lights() { + return (sc_packed_1() >> 16) & 15U; +} + +uint sc_reflection_probes() { + return (sc_packed_1() >> 20) & 15U; +} + +uint sc_directional_lights() { + return (sc_packed_1() >> 24) & 15U; +} + +uint sc_decals() { + return (sc_packed_1() >> 28) & 15U; } float sc_luminance_multiplier() { - return sc_packed_1(); + return sc_packed_2(); } /* Set 0: Base Pass (never changes) */ @@ -157,10 +190,6 @@ layout(set = 0, binding = 2) uniform sampler shadow_sampler; #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) -#define INSTANCE_FLAGS_MULTIMESH_HAS_CUSTOM_DATA (1 << 15) #define INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT 16 //3 bits of stride #define INSTANCE_FLAGS_PARTICLE_TRAIL_MASK 0xFF |