Evaluate specular reflections using specular dominant direction instead of assuming mirror reflections
This commit is contained in:
parent
ce6c4ab86a
commit
93c82ab4b9
4 changed files with 38 additions and 23 deletions
|
@ -1049,6 +1049,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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -869,7 +869,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;
|
||||
|
||||
|
@ -877,8 +877,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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue