2
0
Эх сурвалжийг харах

Merge pull request #107419 from DarioSamo/adreno-fix-interpolators-round-2

Change all interpolators to FP32 in mobile renderer.
Rémi Verschelde 3 сар өмнө
parent
commit
d35b9e9310

+ 36 - 32
servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl

@@ -104,7 +104,7 @@ layout(location = 1) out vec3 normal_interp;
 #endif
 
 #if defined(COLOR_USED)
-layout(location = 2) out hvec4 color_interp;
+layout(location = 2) out vec4 color_interp;
 #endif
 
 #ifdef UV_USED
@@ -120,8 +120,8 @@ layout(location = 5) out vec3 tangent_interp;
 layout(location = 6) out vec3 binormal_interp;
 #endif
 #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
-layout(location = 7) out hvec4 diffuse_light_interp;
-layout(location = 8) out hvec4 specular_light_interp;
+layout(location = 7) out vec4 diffuse_light_interp;
+layout(location = 8) out vec4 specular_light_interp;
 
 #include "../scene_forward_vertex_lights_inc.glsl"
 #endif // !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
@@ -496,12 +496,12 @@ void vertex_shader(in vec3 vertex,
 	// Normalize TBN vectors before interpolation, per MikkTSpace.
 	// See: http://www.mikktspace.com/
 #ifdef NORMAL_USED
-	normal_interp = normalize(normal_highp);
+	normal_interp = hvec3(normalize(normal_highp));
 #endif
 
 #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED) || defined(BENT_NORMAL_MAP_USED)
-	tangent_interp = normalize(tangent_highp);
-	binormal_interp = normalize(binormal_highp);
+	tangent_interp = hvec3(normalize(tangent_highp));
+	binormal_interp = hvec3(normalize(binormal_highp));
 #endif
 
 // VERTEX LIGHTING
@@ -514,8 +514,8 @@ void vertex_shader(in vec3 vertex,
 	hvec3 view = hvec3(-normalize(vertex_interp));
 #endif
 
-	diffuse_light_interp = hvec4(0.0);
-	specular_light_interp = hvec4(0.0);
+	hvec4 diffuse_light = hvec4(0.0);
+	hvec4 specular_light = hvec4(0.0);
 
 	uint omni_light_count = sc_omni_lights(8);
 	uvec2 omni_light_indices = instances.data[instance_index].omni_lights;
@@ -525,7 +525,7 @@ void vertex_shader(in vec3 vertex,
 			break;
 		}
 
-		light_process_omni_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
+		light_process_omni_vertex(light_index, vertex, view, normal, roughness, diffuse_light.rgb, specular_light.rgb);
 	}
 
 	uint spot_light_count = sc_spot_lights(8);
@@ -536,7 +536,7 @@ void vertex_shader(in vec3 vertex,
 			break;
 		}
 
-		light_process_spot_vertex(light_index, vertex, view, normal, roughness, diffuse_light_interp.rgb, specular_light_interp.rgb);
+		light_process_spot_vertex(light_index, vertex, view, normal, roughness, diffuse_light.rgb, specular_light.rgb);
 	}
 
 	uint directional_lights_count = sc_directional_lights(scene_directional_light_count);
@@ -563,33 +563,36 @@ void vertex_shader(in vec3 vertex,
 				light_compute_vertex(normal, hvec3(directional_lights.data[i].direction), view,
 						hvec3(directional_lights.data[i].color * directional_lights.data[i].energy),
 						true, roughness,
-						diffuse_light_interp.rgb,
-						specular_light_interp.rgb);
+						diffuse_light.rgb,
+						specular_light.rgb);
 			}
 		}
 
 		// Calculate the contribution from the shadowed light so we can scale the shadows accordingly.
-		half diff_avg = dot(diffuse_light_interp.rgb, hvec3(0.33333));
+		half diff_avg = dot(diffuse_light.rgb, hvec3(0.33333));
 		half diff_dir_avg = dot(directional_diffuse, hvec3(0.33333));
 		if (diff_avg > half(0.0)) {
-			diffuse_light_interp.a = diff_dir_avg / (diff_avg + diff_dir_avg);
+			diffuse_light.a = diff_dir_avg / (diff_avg + diff_dir_avg);
 		} else {
-			diffuse_light_interp.a = half(1.0);
+			diffuse_light.a = half(1.0);
 		}
 
-		diffuse_light_interp.rgb += directional_diffuse;
+		diffuse_light.rgb += directional_diffuse;
 
-		half spec_avg = dot(specular_light_interp.rgb, hvec3(0.33333));
+		half spec_avg = dot(specular_light.rgb, hvec3(0.33333));
 		half spec_dir_avg = dot(directional_specular, hvec3(0.33333));
 		if (spec_avg > half(0.0)) {
-			specular_light_interp.a = spec_dir_avg / (spec_avg + spec_dir_avg);
+			specular_light.a = spec_dir_avg / (spec_avg + spec_dir_avg);
 		} else {
-			specular_light_interp.a = half(1.0);
+			specular_light.a = half(1.0);
 		}
 
-		specular_light_interp.rgb += directional_specular;
+		specular_light.rgb += directional_specular;
 	}
 
+	diffuse_light_interp = hvec4(diffuse_light);
+	specular_light_interp = hvec4(specular_light);
+
 #endif //!defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
 
 #ifdef MODE_RENDER_DEPTH
@@ -787,15 +790,17 @@ void main() {
 
 /* Varyings */
 
+// All interpolators are intentionally kept at full precision as storageInputOutput16 is not
+// checked for support. Devices with Adreno GPUs don't usually support this capability.
+
 layout(location = 0) in vec3 vertex_interp;
 
 #ifdef NORMAL_USED
-// Intentionally kept at full precision to avoid visible corruption on Adreno (See #107364).
 layout(location = 1) in vec3 normal_interp;
 #endif
 
 #if defined(COLOR_USED)
-layout(location = 2) in hvec4 color_interp;
+layout(location = 2) in vec4 color_interp;
 #endif
 
 #ifdef UV_USED
@@ -807,14 +812,13 @@ layout(location = 4) in vec2 uv2_interp;
 #endif
 
 #if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(BENT_NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
-// Intentionally kept at full precision to avoid visible corruption on Adreno (See #107364).
 layout(location = 5) in vec3 tangent_interp;
 layout(location = 6) in vec3 binormal_interp;
 #endif
 
 #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED) && defined(USE_VERTEX_LIGHTING)
-layout(location = 7) in hvec4 diffuse_light_interp;
-layout(location = 8) in hvec4 specular_light_interp;
+layout(location = 7) in vec4 diffuse_light_interp;
+layout(location = 8) in vec4 specular_light_interp;
 #endif
 
 #ifdef MODE_DUAL_PARABOLOID
@@ -1122,7 +1126,7 @@ void main() {
 #endif
 
 #if defined(COLOR_USED)
-	vec4 color_highp = vec4(color_interp);
+	vec4 color_highp = color_interp;
 #endif
 
 #if defined(NORMAL_MAP_USED)
@@ -1785,8 +1789,8 @@ void main() {
 // LIGHTING
 #if !defined(MODE_RENDER_DEPTH) && !defined(MODE_UNSHADED)
 #ifdef USE_VERTEX_LIGHTING
-	diffuse_light += diffuse_light_interp.rgb;
-	direct_specular_light += specular_light_interp.rgb * f0;
+	diffuse_light += hvec3(diffuse_light_interp.rgb);
+	direct_specular_light += hvec3(specular_light_interp.rgb) * f0;
 #endif
 
 	uint directional_lights_count = sc_directional_lights(scene_data.directional_light_count);
@@ -1938,8 +1942,8 @@ void main() {
 #endif
 
 #ifdef USE_VERTEX_LIGHTING
-					diffuse_light *= mix(half(1.0), shadow, diffuse_light_interp.a);
-					direct_specular_light *= mix(half(1.0), shadow, specular_light_interp.a);
+					diffuse_light *= mix(half(1.0), shadow, half(diffuse_light_interp.a));
+					direct_specular_light *= mix(half(1.0), shadow, half(specular_light_interp.a));
 #endif
 #undef BIAS_FUNC
 				}
@@ -1951,8 +1955,8 @@ void main() {
 		} else { // shadowmask_mode == LIGHTMAP_SHADOWMASK_MODE_ONLY
 
 #ifdef USE_VERTEX_LIGHTING
-			diffuse_light *= mix(half(1.0), half(shadowmask), diffuse_light_interp.a);
-			direct_specular_light *= mix(half(1.0), half(shadowmask), specular_light_interp.a);
+			diffuse_light *= mix(half(1.0), shadowmask, half(diffuse_light_interp.a));
+			direct_specular_light *= mix(half(1.0), shadowmask, half(specular_light_interp.a));
 #endif
 
 			shadows[0] = shadowmask;