summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
-rw-r--r--servers/rendering/renderer_rd/shaders/canvas.glsl40
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl34
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/tonemap.glsl28
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/volumetric_fog_process.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered.glsl81
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_clustered/scene_forward_clustered_inc.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/SCsub2
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl80
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile_inc.glsl15
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl2
13 files changed, 233 insertions, 72 deletions
diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl
index 459d798a80..8593e6b265 100644
--- a/servers/rendering/renderer_rd/shaders/canvas.glsl
+++ b/servers/rendering/renderer_rd/shaders/canvas.glsl
@@ -313,6 +313,14 @@ vec4 light_compute(
vec2 uv,
vec4 color, bool is_directional) {
vec4 light = vec4(0.0);
+ vec3 light_direction = vec3(0.0);
+
+ if (is_directional) {
+ light_direction = normalize(mix(vec3(light_position.xy, 0.0), vec3(0, 0, 1), light_position.z));
+ light_position = vec3(0.0);
+ } else {
+ light_direction = normalize(light_position - light_vertex);
+ }
#CODE : LIGHT
@@ -590,14 +598,14 @@ 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
}
#ifdef MODE_LIGHT_ONLY
color = vec4(0.0);
-#else
+#elif !defined(MODE_UNSHADED)
color *= canvas_data.canvas_modulation;
#endif
@@ -614,12 +622,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
@@ -645,20 +655,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;
@@ -673,7 +670,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;
@@ -682,9 +679,10 @@ void main() {
vec3 light_pos = vec3(light_array.data[light_base].position, light_array.data[light_base].height);
vec3 pos = light_vertex;
vec3 light_vec = normalize(light_pos - pos);
- float cNdotL = max(0.0, dot(normal, light_vec));
- 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)))) {
diff --git a/servers/rendering/renderer_rd/shaders/effects/SCsub b/servers/rendering/renderer_rd/shaders/effects/SCsub
index 741da8fe69..f06a2d86e2 100644
--- a/servers/rendering/renderer_rd/shaders/effects/SCsub
+++ b/servers/rendering/renderer_rd/shaders/effects/SCsub
@@ -4,7 +4,7 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
- gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+ gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
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..9d8294a7da 100644
--- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
@@ -121,7 +121,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 +139,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 +157,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 +169,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;
diff --git a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
index e459756c6a..52aee8b648 100644
--- a/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/tonemap.glsl
@@ -360,15 +360,15 @@ vec3 do_fxaa(vec3 color, float exposure, vec2 uv_interp) {
const float FXAA_SPAN_MAX = 8.0;
#ifdef MULTIVIEW
- vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(1.0, -1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(1.0, 1.0) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbNW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbNE = textureLod(source_color, vec3(uv_interp + vec2(0.5, -0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbSW = textureLod(source_color, vec3(uv_interp + vec2(-0.5, 0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbSE = textureLod(source_color, vec3(uv_interp + vec2(0.5, 0.5) * params.pixel_size, ViewIndex), 0.0).xyz * exposure * params.luminance_multiplier;
#else
- vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbNE = textureLod(source_color, uv_interp + vec2(1.0, -1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
- vec3 rgbSE = textureLod(source_color, uv_interp + vec2(1.0, 1.0) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbNW = textureLod(source_color, uv_interp + vec2(-0.5, -0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbNE = textureLod(source_color, uv_interp + vec2(0.5, -0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbSW = textureLod(source_color, uv_interp + vec2(-0.5, 0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
+ vec3 rgbSE = textureLod(source_color, uv_interp + vec2(0.5, 0.5) * params.pixel_size, 0.0).xyz * exposure * params.luminance_multiplier;
#endif
vec3 rgbM = color;
vec3 luma = vec3(0.299, 0.587, 0.114);
@@ -462,12 +462,6 @@ void main() {
}
#endif
- if (params.use_debanding) {
- // For best results, debanding should be done before tonemapping.
- // Otherwise, we're adding noise to an already-quantized image.
- color.rgb += screen_space_dither(gl_FragCoord.xy);
- }
-
color.rgb = apply_tonemapping(color.rgb, params.white);
color.rgb = linear_to_srgb(color.rgb); // regular linear -> SRGB conversion
@@ -498,5 +492,11 @@ void main() {
color.rgb = apply_color_correction(color.rgb);
}
+ if (params.use_debanding) {
+ // Debanding should be done at the end of tonemapping, but before writing to the LDR buffer.
+ // Otherwise, we're adding noise to an already-quantized image.
+ color.rgb += screen_space_dither(gl_FragCoord.xy);
+ }
+
frag_color = color;
}
diff --git a/servers/rendering/renderer_rd/shaders/environment/SCsub b/servers/rendering/renderer_rd/shaders/environment/SCsub
index 741da8fe69..f06a2d86e2 100644
--- a/servers/rendering/renderer_rd/shaders/environment/SCsub
+++ b/servers/rendering/renderer_rd/shaders/environment/SCsub
@@ -4,7 +4,7 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
- gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+ gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
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/SCsub b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub
index 741da8fe69..f06a2d86e2 100644
--- a/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub
+++ b/servers/rendering/renderer_rd/shaders/forward_clustered/SCsub
@@ -4,7 +4,7 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
- gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+ gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
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 a330fd5497..77ae97e621 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
@@ -129,12 +129,52 @@ invariant gl_Position;
#GLOBALS
+#ifdef USE_DOUBLE_PRECISION
+// Helper functions for emulating double precision when adding floats.
+vec3 quick_two_sum(vec3 a, vec3 b, out vec3 out_p) {
+ vec3 s = a + b;
+ out_p = b - (s - a);
+ return s;
+}
+
+vec3 two_sum(vec3 a, vec3 b, out vec3 out_p) {
+ vec3 s = a + b;
+ vec3 v = s - a;
+ out_p = (a - (s - v)) + (b - v);
+ return s;
+}
+
+vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec3 out_precision) {
+ vec3 s, t, se, te;
+ s = two_sum(base_a, base_b, se);
+ t = two_sum(prec_a, prec_b, te);
+ se += t;
+ s = quick_two_sum(s, se, se);
+ se += te;
+ s = quick_two_sum(s, se, out_precision);
+ return s;
+}
+#endif
+
void vertex_shader(in uint instance_index, in bool is_multimesh, 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;
#endif
+ mat4 inv_view_matrix = scene_data.inv_view_matrix;
+
+#ifdef USE_DOUBLE_PRECISION
+ vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]);
+ model_matrix[0][3] = 0.0;
+ model_matrix[1][3] = 0.0;
+ model_matrix[2][3] = 0.0;
+ vec3 view_precision = vec3(inv_view_matrix[0][3], inv_view_matrix[1][3], inv_view_matrix[2][3]);
+ inv_view_matrix[0][3] = 0.0;
+ inv_view_matrix[1][3] = 0.0;
+ inv_view_matrix[2][3] = 0.0;
+#endif
+
mat3 model_normal_matrix;
if (bool(instances.data[instance_index].flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
model_normal_matrix = transpose(inverse(mat3(model_matrix)));
@@ -142,11 +182,12 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
model_normal_matrix = mat3(model_matrix);
}
+ mat4 matrix;
+ mat4 read_model_matrix = model_matrix;
+
if (is_multimesh) {
//multimesh, instances are for it
- mat4 matrix;
-
#ifdef USE_PARTICLE_TRAILS
uint trail_size = (instances.data[instance_index].flags >> INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT) & INSTANCE_FLAGS_PARTICLE_TRAIL_MASK;
uint stride = 3 + 1 + 1; //particles always uses this format
@@ -232,7 +273,14 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
#endif
//transpose
matrix = transpose(matrix);
- model_matrix = model_matrix * matrix;
+#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED)
+ // Normally we can bake the multimesh transform into the model matrix, but when using double precision
+ // we avoid baking it in so we can emulate high precision.
+ read_model_matrix = model_matrix * matrix;
+#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED)
+ model_matrix = read_model_matrix;
+#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED)
+#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED)
model_normal_matrix = model_normal_matrix * mat3(matrix);
}
@@ -297,7 +345,22 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
// using local coordinates (default)
#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED)
+#ifdef USE_DOUBLE_PRECISION
+ // We separate the basis from the origin because the basis is fine with single point precision.
+ // 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) {
+ vertex = mat3(matrix) * vertex;
+ model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision);
+ }
+ vertex = mat3(model_matrix) * vertex;
+ vec3 temp_precision; // Will be ignored.
+ vertex += double_add_vec3(model_origin, model_precision, scene_data.inv_view_matrix[3].xyz, view_precision, temp_precision);
+ vertex = mat3(scene_data.view_matrix) * vertex;
+#else
vertex = (modelview * vec4(vertex, 1.0)).xyz;
+#endif
#ifdef NORMAL_USED
normal = modelview_normal * normal;
#endif
@@ -490,7 +553,6 @@ layout(location = 10) in flat uint instance_index_interp;
//defines to keep compatibility with vertex
-#define model_matrix instances.data[draw_call.instance_index].transform
#ifdef USE_MULTIVIEW
#define projection_matrix scene_data.projection_matrix_view[ViewIndex]
#define inv_projection_matrix scene_data.inv_projection_matrix_view[ViewIndex]
@@ -737,6 +799,17 @@ void fragment_shader(in SceneData scene_data) {
vec2 alpha_texture_coordinate = vec2(0.0, 0.0);
#endif // ALPHA_ANTIALIASING_EDGE_USED
+ mat4 inv_view_matrix = scene_data.inv_view_matrix;
+ mat4 read_model_matrix = instances.data[instance_index].transform;
+#ifdef USE_DOUBLE_PRECISION
+ read_model_matrix[0][3] = 0.0;
+ read_model_matrix[1][3] = 0.0;
+ read_model_matrix[2][3] = 0.0;
+ inv_view_matrix[0][3] = 0.0;
+ inv_view_matrix[1][3] = 0.0;
+ inv_view_matrix[2][3] = 0.0;
+#endif
+
{
#CODE : 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 e8e2dce990..0d36b98645 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
@@ -62,13 +62,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)
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub
index 741da8fe69..f06a2d86e2 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/SCsub
@@ -4,7 +4,7 @@ Import("env")
if "RD_GLSL" in env["BUILDERS"]:
# find all include files
- gl_include_files = [str(f) for f in Glob("*_inc.glsl")]
+ gl_include_files = [str(f) for f in Glob("*_inc.glsl")] + [str(f) for f in Glob("../*_inc.glsl")]
# find all shader code(all glsl files excluding our include files)
glsl_files = [str(f) for f in Glob("*.glsl") if str(f) not in gl_include_files]
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 d42fdc8746..9aeaa6d978 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
@@ -123,6 +123,33 @@ invariant gl_Position;
#define scene_data scene_data_block.data
+#ifdef USE_DOUBLE_PRECISION
+// Helper functions for emulating double precision when adding floats.
+vec3 quick_two_sum(vec3 a, vec3 b, out vec3 out_p) {
+ vec3 s = a + b;
+ out_p = b - (s - a);
+ return s;
+}
+
+vec3 two_sum(vec3 a, vec3 b, out vec3 out_p) {
+ vec3 s = a + b;
+ vec3 v = s - a;
+ out_p = (a - (s - v)) + (b - v);
+ return s;
+}
+
+vec3 double_add_vec3(vec3 base_a, vec3 prec_a, vec3 base_b, vec3 prec_b, out vec3 out_precision) {
+ vec3 s, t, se, te;
+ s = two_sum(base_a, base_b, se);
+ t = two_sum(prec_a, prec_b, te);
+ se += t;
+ s = quick_two_sum(s, se, se);
+ se += te;
+ s = quick_two_sum(s, se, out_precision);
+ return s;
+}
+#endif
+
void main() {
vec4 instance_custom = vec4(0.0);
#if defined(COLOR_USED)
@@ -132,6 +159,17 @@ void main() {
bool is_multimesh = bool(draw_call.flags & INSTANCE_FLAGS_MULTIMESH);
mat4 model_matrix = draw_call.transform;
+ mat4 inv_view_matrix = scene_data.inv_view_matrix;
+#ifdef USE_DOUBLE_PRECISION
+ vec3 model_precision = vec3(model_matrix[0][3], model_matrix[1][3], model_matrix[2][3]);
+ model_matrix[0][3] = 0.0;
+ model_matrix[1][3] = 0.0;
+ model_matrix[2][3] = 0.0;
+ vec3 view_precision = vec3(inv_view_matrix[0][3], inv_view_matrix[1][3], inv_view_matrix[2][3]);
+ inv_view_matrix[0][3] = 0.0;
+ inv_view_matrix[1][3] = 0.0;
+ inv_view_matrix[2][3] = 0.0;
+#endif
mat3 model_normal_matrix;
if (bool(draw_call.flags & INSTANCE_FLAGS_NON_UNIFORM_SCALE)) {
@@ -140,11 +178,12 @@ void main() {
model_normal_matrix = mat3(model_matrix);
}
+ mat4 matrix;
+ mat4 read_model_matrix = model_matrix;
+
if (is_multimesh) {
//multimesh, instances are for it
- mat4 matrix;
-
#ifdef USE_PARTICLE_TRAILS
uint trail_size = (draw_call.flags >> INSTANCE_FLAGS_PARTICLE_TRAIL_SHIFT) & INSTANCE_FLAGS_PARTICLE_TRAIL_MASK;
uint stride = 3 + 1 + 1; //particles always uses this format
@@ -230,7 +269,15 @@ void main() {
#endif
//transpose
matrix = transpose(matrix);
- model_matrix = model_matrix * matrix;
+
+#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED)
+ // Normally we can bake the multimesh transform into the model matrix, but when using double precision
+ // we avoid baking it in so we can emulate high precision.
+ read_model_matrix = model_matrix * matrix;
+#if !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED)
+ model_matrix = read_model_matrix;
+#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED)
+#endif // !defined(USE_DOUBLE_PRECISION) || defined(SKIP_TRANSFORM_USED) || defined(VERTEX_WORLD_COORDS_USED) || defined(MODEL_MATRIX_USED)
model_normal_matrix = model_normal_matrix * mat3(matrix);
}
@@ -297,7 +344,22 @@ void main() {
// using local coordinates (default)
#if !defined(SKIP_TRANSFORM_USED) && !defined(VERTEX_WORLD_COORDS_USED)
+#ifdef USE_DOUBLE_PRECISION
+ // We separate the basis from the origin because the basis is fine with single point precision.
+ // 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) {
+ vertex = mat3(matrix) * vertex;
+ model_origin = double_add_vec3(model_origin, model_precision, matrix[3].xyz, vec3(0.0), model_precision);
+ }
+ vertex = mat3(model_matrix) * vertex;
+ vec3 temp_precision;
+ vertex += double_add_vec3(model_origin, model_precision, scene_data.inv_view_matrix[3].xyz, view_precision, temp_precision);
+ vertex = mat3(scene_data.view_matrix) * vertex;
+#else
vertex = (modelview * vec4(vertex, 1.0)).xyz;
+#endif
#ifdef NORMAL_USED
normal = modelview_normal * normal;
#endif
@@ -468,7 +530,6 @@ layout(location = 9) highp in float dp_clip;
//defines to keep compatibility with vertex
-#define model_matrix draw_call.transform
#ifdef USE_MULTIVIEW
#define projection_matrix scene_data.projection_matrix_view[ViewIndex]
#define inv_projection_matrix scene_data.inv_projection_matrix_view[ViewIndex]
@@ -685,6 +746,17 @@ void main() {
vec2 alpha_texture_coordinate = vec2(0.0, 0.0);
#endif // ALPHA_ANTIALIASING_EDGE_USED
+ mat4 inv_view_matrix = scene_data.inv_view_matrix;
+ mat4 read_model_matrix = draw_call.transform;
+#ifdef USE_DOUBLE_PRECISION
+ read_model_matrix[0][3] = 0.0;
+ read_model_matrix[1][3] = 0.0;
+ read_model_matrix[2][3] = 0.0;
+ inv_view_matrix[0][3] = 0.0;
+ inv_view_matrix[1][3] = 0.0;
+ inv_view_matrix[2][3] = 0.0;
+#endif
+
{
#CODE : FRAGMENT
}
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..631ff0575b 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)
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index fb5759bc17..3a6dd579b9 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -475,7 +475,7 @@ void main() {
float particle_size = FRAME.particle_size;
-#ifdef USE_COLLISON_SCALE
+#ifdef USE_COLLISION_SCALE
particle_size *= dot(vec3(length(PARTICLE.xform[0].xyz), length(PARTICLE.xform[1].xyz), length(PARTICLE.xform[2].xyz)), vec3(0.33333333333));