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

Merge pull request #62547 from clayjohn/ref_vec_pbr

Rémi Verschelde 3 жил өмнө
parent
commit
8734ef1f7a

+ 1 - 0
drivers/gles3/shaders/scene.glsl

@@ -1052,6 +1052,7 @@ void main() {
 #else
 		vec3 ref_vec = reflect(-view, normal);
 #endif
+		ref_vec = mix(ref_vec, normal, roughness * roughness);
 		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
 		ref_vec = scene_data.radiance_inverse_xform * ref_vec;
 		specular_light = textureLod(radiance_map, ref_vec, roughness * RADIANCE_MAX_LOD).rgb;

+ 18 - 10
servers/rendering/renderer_rd/shaders/scene_forward_clustered.glsl

@@ -988,8 +988,10 @@ void fragment_shader(in SceneData scene_data) {
 		vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
 		vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
 		vec3 ref_vec = reflect(-view, bent_normal);
+		ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
 #else
 		vec3 ref_vec = reflect(-view, normal);
+		ref_vec = mix(ref_vec, normal, roughness * roughness);
 #endif
 
 		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
@@ -1046,6 +1048,7 @@ void fragment_shader(in SceneData scene_data) {
 		ambient_light *= attenuation;
 		specular_light *= attenuation;
 
+		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;
@@ -1203,6 +1206,7 @@ void fragment_shader(in SceneData scene_data) {
 
 		uint index1 = instances.data[instance_index].gi_offset & 0xFFFF;
 		vec3 ref_vec = normalize(reflect(-view, normal));
+		ref_vec = mix(ref_vec, normal, roughness * roughness);
 		//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));
@@ -1302,6 +1306,18 @@ void fragment_shader(in SceneData scene_data) {
 		item_to = subgroupBroadcastFirst(subgroupMax(item_to));
 #endif
 
+#ifdef LIGHT_ANISOTROPY_USED
+		// https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
+		vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
+		vec3 anisotropic_tangent = cross(anisotropic_direction, view);
+		vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
+		vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
+#else
+		vec3 bent_normal = normal;
+#endif
+		vec3 ref_vec = normalize(reflect(-view, bent_normal));
+		ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
+
 		for (uint i = item_from; i < item_to; i++) {
 			uint mask = cluster_buffer.data[cluster_reflection_offset + i];
 			mask &= cluster_get_range_clip_mask(i, item_min, item_max);
@@ -1324,16 +1340,8 @@ void fragment_shader(in SceneData scene_data) {
 				if (!bool(reflections.data[reflection_index].mask & instances.data[instance_index].layer_mask)) {
 					continue; //not masked
 				}
-#ifdef LIGHT_ANISOTROPY_USED
-				// https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
-				vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
-				vec3 anisotropic_tangent = cross(anisotropic_direction, view);
-				vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
-				vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
-#else
-				vec3 bent_normal = normal;
-#endif
-				reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+
+				reflection_process(reflection_index, vertex, ref_vec, normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
 			}
 		}
 

+ 1 - 3
servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl

@@ -874,7 +874,7 @@ void light_process_spot(uint idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 v
 			diffuse_light, specular_light);
 }
 
-void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) {
+void reflection_process(uint ref_index, vec3 vertex, vec3 ref_vec, vec3 normal, float roughness, vec3 ambient_light, vec3 specular_light, inout vec4 ambient_accum, inout vec4 reflection_accum) {
 	vec3 box_extents = reflections.data[ref_index].box_extents;
 	vec3 local_pos = (reflections.data[ref_index].local_matrix * vec4(vertex, 1.0)).xyz;
 
@@ -882,8 +882,6 @@ void reflection_process(uint ref_index, vec3 view, vec3 vertex, vec3 normal, flo
 		return;
 	}
 
-	vec3 ref_vec = normalize(reflect(-view, normal));
-
 	vec3 inner_pos = abs(local_pos / box_extents);
 	float blend = max(inner_pos.x, max(inner_pos.y, inner_pos.z));
 	//make blend more rounded

+ 18 - 10
servers/rendering/renderer_rd/shaders/scene_forward_mobile.glsl

@@ -889,8 +889,10 @@ void main() {
 		vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
 		vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
 		vec3 ref_vec = reflect(-view, bent_normal);
+		ref_vec = mix(ref_vec, bent_normal, roughness * roughness);
 #else
 		vec3 ref_vec = reflect(-view, normal);
+		ref_vec = mix(ref_vec, normal, roughness * roughness);
 #endif
 		float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
 		ref_vec = scene_data.radiance_inverse_xform * ref_vec;
@@ -940,6 +942,7 @@ void main() {
 		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);
+		ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
 		// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
 		float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
 		float attenuation = 1.0 - Fc;
@@ -1036,6 +1039,19 @@ void main() {
 		vec4 ambient_accum = vec4(0.0, 0.0, 0.0, 0.0);
 
 		uint reflection_indices = draw_call.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;
+		vec3 anisotropic_tangent = cross(anisotropic_direction, view);
+		vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
+		vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
+#else
+		vec3 bent_normal = normal;
+#endif
+		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 == 4) {
@@ -1047,16 +1063,8 @@ void main() {
 			if (reflection_index == 0xFF) {
 				break;
 			}
-#ifdef LIGHT_ANISOTROPY_USED
-			// https://google.github.io/filament/Filament.html#lighting/imagebasedlights/anisotropy
-			vec3 anisotropic_direction = anisotropy >= 0.0 ? binormal : tangent;
-			vec3 anisotropic_tangent = cross(anisotropic_direction, view);
-			vec3 anisotropic_normal = cross(anisotropic_tangent, anisotropic_direction);
-			vec3 bent_normal = normalize(mix(normal, anisotropic_normal, abs(anisotropy) * clamp(5.0 * roughness, 0.0, 1.0)));
-#else
-			vec3 bent_normal = normal;
-#endif
-			reflection_process(reflection_index, view, vertex, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
+
+			reflection_process(reflection_index, vertex, ref_vec, bent_normal, roughness, ambient_light, specular_light, ambient_accum, reflection_accum);
 		}
 
 		if (reflection_accum.a > 0.0) {