You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-12 13:20:55 +00:00
Scene Shaders - TBN Fixes
Fixes two errors related to the normal, tangent, and bitangent vectors, namely normals not always being inverted on backfaces, and normalization being reversed from what MikkTSpace expects.
This commit is contained in:
@@ -650,13 +650,16 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
vertex_interp = vertex;
|
vertex_interp = vertex;
|
||||||
|
|
||||||
|
// Normalize TBN vectors before interpolation, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
normal_interp = normal;
|
normal_interp = normalize(normal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||||
tangent_interp = tangent;
|
tangent_interp = normalize(tangent);
|
||||||
binormal_interp = binormal;
|
binormal_interp = normalize(binormal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Calculate shadows.
|
// Calculate shadows.
|
||||||
@@ -1799,23 +1802,22 @@ void main() {
|
|||||||
float alpha = 1.0;
|
float alpha = 1.0;
|
||||||
|
|
||||||
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||||
vec3 binormal = normalize(binormal_interp);
|
vec3 binormal = binormal_interp;
|
||||||
vec3 tangent = normalize(tangent_interp);
|
vec3 tangent = tangent_interp;
|
||||||
#else
|
#else
|
||||||
vec3 binormal = vec3(0.0);
|
vec3 binormal = vec3(0.0);
|
||||||
vec3 tangent = vec3(0.0);
|
vec3 tangent = vec3(0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
vec3 normal = normalize(normal_interp);
|
vec3 normal = normal_interp;
|
||||||
|
|
||||||
#if defined(DO_SIDE_CHECK)
|
#if defined(DO_SIDE_CHECK)
|
||||||
if (!gl_FrontFacing) {
|
if (!gl_FrontFacing) {
|
||||||
normal = -normal;
|
normal = -normal;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // DO_SIDE_CHECK
|
||||||
|
vec3 geo_normal = normalize(normal);
|
||||||
#endif //NORMAL_USED
|
#endif // NORMAL_USED
|
||||||
|
|
||||||
#ifdef UV_USED
|
#ifdef UV_USED
|
||||||
vec2 uv = uv_interp;
|
vec2 uv = uv_interp;
|
||||||
@@ -1900,21 +1902,22 @@ void main() {
|
|||||||
|
|
||||||
#endif // !USE_SHADOW_TO_OPACITY
|
#endif // !USE_SHADOW_TO_OPACITY
|
||||||
|
|
||||||
#ifdef NORMAL_MAP_USED
|
#if defined(NORMAL_MAP_USED)
|
||||||
|
|
||||||
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
||||||
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
||||||
|
|
||||||
|
// Tangent-space transformation is performed using unnormalized TBN vectors, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
||||||
|
#elif defined(NORMAL_USED)
|
||||||
#endif
|
normal = geo_normal;
|
||||||
|
#endif // NORMAL_MAP_USED
|
||||||
|
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
|
|
||||||
if (anisotropy > 0.01) {
|
if (anisotropy > 0.01) {
|
||||||
//rotation matrix
|
mat3 rot = mat3(normalize(tangent), normalize(binormal), normal);
|
||||||
mat3 rot = mat3(tangent, binormal, normal);
|
// Make local to space.
|
||||||
//make local to space
|
|
||||||
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
||||||
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
||||||
}
|
}
|
||||||
@@ -2146,8 +2149,8 @@ void main() {
|
|||||||
rim, rim_tint,
|
rim, rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal,
|
binormal,
|
||||||
tangent, anisotropy,
|
tangent, anisotropy,
|
||||||
@@ -2172,8 +2175,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal, tangent, anisotropy,
|
binormal, tangent, anisotropy,
|
||||||
#endif
|
#endif
|
||||||
@@ -2196,8 +2199,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent,
|
tangent,
|
||||||
binormal, anisotropy,
|
binormal, anisotropy,
|
||||||
@@ -2448,8 +2451,8 @@ void main() {
|
|||||||
rim, rim_tint,
|
rim, rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal,
|
binormal,
|
||||||
tangent, anisotropy,
|
tangent, anisotropy,
|
||||||
@@ -2481,8 +2484,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal, tangent, anisotropy,
|
binormal, tangent, anisotropy,
|
||||||
#endif
|
#endif
|
||||||
@@ -2511,8 +2514,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_RIM_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent,
|
tangent,
|
||||||
binormal, anisotropy,
|
binormal, anisotropy,
|
||||||
|
|||||||
@@ -457,13 +457,15 @@ void vertex_shader(vec3 vertex_input,
|
|||||||
|
|
||||||
vertex_interp = vertex;
|
vertex_interp = vertex;
|
||||||
|
|
||||||
|
// Normalize TBN vectors before interpolation, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
normal_interp = normal;
|
normal_interp = normalize(normal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TANGENT_USED
|
#ifdef TANGENT_USED
|
||||||
tangent_interp = tangent;
|
tangent_interp = normalize(tangent);
|
||||||
binormal_interp = binormal;
|
binormal_interp = normalize(binormal);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MODE_RENDER_DEPTH
|
#ifdef MODE_RENDER_DEPTH
|
||||||
@@ -1158,23 +1160,22 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
float alpha = float(instances.data[instance_index].flags >> INSTANCE_FLAGS_FADE_SHIFT) / float(255.0);
|
float alpha = float(instances.data[instance_index].flags >> INSTANCE_FLAGS_FADE_SHIFT) / float(255.0);
|
||||||
|
|
||||||
#ifdef TANGENT_USED
|
#ifdef TANGENT_USED
|
||||||
vec3 binormal = normalize(binormal_interp);
|
vec3 binormal = binormal_interp;
|
||||||
vec3 tangent = normalize(tangent_interp);
|
vec3 tangent = tangent_interp;
|
||||||
#else
|
#else
|
||||||
vec3 binormal = vec3(0.0);
|
vec3 binormal = vec3(0.0);
|
||||||
vec3 tangent = vec3(0.0);
|
vec3 tangent = vec3(0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
vec3 normal = normalize(normal_interp);
|
vec3 normal = normal_interp;
|
||||||
|
|
||||||
#if defined(DO_SIDE_CHECK)
|
#if defined(DO_SIDE_CHECK)
|
||||||
if (!gl_FrontFacing) {
|
if (!gl_FrontFacing) {
|
||||||
normal = -normal;
|
normal = -normal;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // DO_SIDE_CHECK
|
||||||
|
vec3 geo_normal = normalize(normal);
|
||||||
#endif //NORMAL_USED
|
#endif // NORMAL_USED
|
||||||
|
|
||||||
#ifdef UV_USED
|
#ifdef UV_USED
|
||||||
vec2 uv = uv_interp;
|
vec2 uv = uv_interp;
|
||||||
@@ -1292,21 +1293,22 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
|
|
||||||
#endif // !USE_SHADOW_TO_OPACITY
|
#endif // !USE_SHADOW_TO_OPACITY
|
||||||
|
|
||||||
#ifdef NORMAL_MAP_USED
|
#if defined(NORMAL_MAP_USED)
|
||||||
|
|
||||||
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
||||||
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
||||||
|
|
||||||
|
// Tangent-space transformation is performed using unnormalized TBN vectors, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
||||||
|
#elif defined(NORMAL_USED)
|
||||||
#endif
|
normal = geo_normal;
|
||||||
|
#endif // NORMAL_MAP_USED
|
||||||
|
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
|
|
||||||
if (anisotropy > 0.01) {
|
if (anisotropy > 0.01) {
|
||||||
//rotation matrix
|
mat3 rot = mat3(normalize(tangent), normalize(binormal), normal);
|
||||||
mat3 rot = mat3(tangent, binormal, normal);
|
// Make local to space.
|
||||||
//make local to space
|
|
||||||
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
||||||
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
||||||
}
|
}
|
||||||
@@ -1426,7 +1428,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
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);
|
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);
|
||||||
|
|
||||||
if (decals.data[decal_index].normal_fade > 0.0) {
|
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);
|
fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(geo_normal, decals.data[decal_index].normal) * 0.5 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
//we need ddx/ddy for mipmaps, so simulate them
|
//we need ddx/ddy for mipmaps, so simulate them
|
||||||
@@ -1576,16 +1578,15 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
|
|
||||||
if (scene_data.use_reflection_cubemap) {
|
if (scene_data.use_reflection_cubemap) {
|
||||||
vec3 n = normalize(normal_interp); // We want to use geometric normal, not normal_map
|
float NoV = max(dot(geo_normal, view), 0.0001); // We want to use geometric normal, not normal_map
|
||||||
float NoV = max(dot(n, view), 0.0001);
|
vec3 ref_vec = reflect(-view, geo_normal);
|
||||||
vec3 ref_vec = reflect(-view, n);
|
ref_vec = mix(ref_vec, geo_normal, clearcoat_roughness * clearcoat_roughness);
|
||||||
// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
|
// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
|
||||||
float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
|
float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
|
||||||
float attenuation = 1.0 - Fc;
|
float attenuation = 1.0 - Fc;
|
||||||
ambient_light *= attenuation;
|
ambient_light *= attenuation;
|
||||||
specular_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);
|
float horizon = min(1.0 + dot(ref_vec, normal), 1.0);
|
||||||
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
|
ref_vec = scene_data.radiance_inverse_xform * ref_vec;
|
||||||
float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
|
float roughness_lod = mix(0.001, 0.1, sqrt(clearcoat_roughness)) * MAX_ROUGHNESS_LOD;
|
||||||
@@ -2026,7 +2027,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
if (directional_lights.data[i].shadow_opacity > 0.001) {
|
if (directional_lights.data[i].shadow_opacity > 0.001) {
|
||||||
float depth_z = -vertex.z;
|
float depth_z = -vertex.z;
|
||||||
vec3 light_dir = directional_lights.data[i].direction;
|
vec3 light_dir = directional_lights.data[i].direction;
|
||||||
vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp))));
|
vec3 base_normal_bias = geo_normal * (1.0 - max(0.0, dot(light_dir, -geo_normal)));
|
||||||
|
|
||||||
#define BIAS_FUNC(m_var, m_idx) \
|
#define BIAS_FUNC(m_var, m_idx) \
|
||||||
m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
|
m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
|
||||||
@@ -2270,7 +2271,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
float depth_z = -vertex.z;
|
float depth_z = -vertex.z;
|
||||||
|
|
||||||
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
|
if (depth_z < directional_lights.data[i].shadow_split_offsets.x) {
|
||||||
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
|
vec4 trans_vertex = vec4(vertex - geo_normal * directional_lights.data[i].shadow_transmittance_bias.x, 1.0);
|
||||||
vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
|
vec4 trans_coord = directional_lights.data[i].shadow_matrix1 * trans_vertex;
|
||||||
trans_coord /= trans_coord.w;
|
trans_coord /= trans_coord.w;
|
||||||
|
|
||||||
@@ -2280,7 +2281,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
|
|
||||||
transmittance_z = z - shadow_z;
|
transmittance_z = z - shadow_z;
|
||||||
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
|
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.y) {
|
||||||
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
|
vec4 trans_vertex = vec4(vertex - geo_normal * directional_lights.data[i].shadow_transmittance_bias.y, 1.0);
|
||||||
vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
|
vec4 trans_coord = directional_lights.data[i].shadow_matrix2 * trans_vertex;
|
||||||
trans_coord /= trans_coord.w;
|
trans_coord /= trans_coord.w;
|
||||||
|
|
||||||
@@ -2290,7 +2291,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
|
|
||||||
transmittance_z = z - shadow_z;
|
transmittance_z = z - shadow_z;
|
||||||
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
|
} else if (depth_z < directional_lights.data[i].shadow_split_offsets.z) {
|
||||||
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
|
vec4 trans_vertex = vec4(vertex - geo_normal * directional_lights.data[i].shadow_transmittance_bias.z, 1.0);
|
||||||
vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
|
vec4 trans_coord = directional_lights.data[i].shadow_matrix3 * trans_vertex;
|
||||||
trans_coord /= trans_coord.w;
|
trans_coord /= trans_coord.w;
|
||||||
|
|
||||||
@@ -2299,9 +2300,8 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
|
float z = trans_coord.z * directional_lights.data[i].shadow_z_range.z;
|
||||||
|
|
||||||
transmittance_z = z - shadow_z;
|
transmittance_z = z - shadow_z;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
vec4 trans_vertex = vec4(vertex - normalize(normal_interp) * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
|
vec4 trans_vertex = vec4(vertex - geo_normal * directional_lights.data[i].shadow_transmittance_bias.w, 1.0);
|
||||||
vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
|
vec4 trans_coord = directional_lights.data[i].shadow_matrix4 * trans_vertex;
|
||||||
trans_coord /= trans_coord.w;
|
trans_coord /= trans_coord.w;
|
||||||
|
|
||||||
@@ -2365,8 +2365,8 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
rim, rim_tint,
|
rim, rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal,
|
binormal,
|
||||||
tangent, anisotropy,
|
tangent, anisotropy,
|
||||||
@@ -2435,8 +2435,8 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent, binormal, anisotropy,
|
tangent, binormal, anisotropy,
|
||||||
#endif
|
#endif
|
||||||
@@ -2503,8 +2503,8 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent,
|
tangent,
|
||||||
binormal, anisotropy,
|
binormal, anisotropy,
|
||||||
@@ -2553,7 +2553,7 @@ void fragment_shader(in SceneData scene_data) {
|
|||||||
vec3(0, -1, 0),
|
vec3(0, -1, 0),
|
||||||
vec3(0, 0, -1));
|
vec3(0, 0, -1));
|
||||||
|
|
||||||
vec3 cam_normal = mat3(scene_data.inv_view_matrix) * normalize(normal_interp);
|
vec3 cam_normal = mat3(scene_data.inv_view_matrix) * geo_normal;
|
||||||
|
|
||||||
float closest_dist = -1e20;
|
float closest_dist = -1e20;
|
||||||
|
|
||||||
|
|||||||
@@ -433,6 +433,9 @@ void main() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
vertex_interp = vertex;
|
vertex_interp = vertex;
|
||||||
|
|
||||||
|
// Normalize TBN vectors before interpolation, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
normal_interp = normalize(normal);
|
normal_interp = normalize(normal);
|
||||||
#endif
|
#endif
|
||||||
@@ -881,23 +884,22 @@ void main() {
|
|||||||
float alpha = 1.0;
|
float alpha = 1.0;
|
||||||
|
|
||||||
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
#if defined(TANGENT_USED) || defined(NORMAL_MAP_USED) || defined(LIGHT_ANISOTROPY_USED)
|
||||||
vec3 binormal = normalize(binormal_interp);
|
vec3 binormal = binormal_interp;
|
||||||
vec3 tangent = normalize(tangent_interp);
|
vec3 tangent = tangent_interp;
|
||||||
#else
|
#else // TANGENT_USED || NORMAL_MAP_USED || LIGHT_ANISOTROPY_USED
|
||||||
vec3 binormal = vec3(0.0);
|
vec3 binormal = vec3(0.0);
|
||||||
vec3 tangent = vec3(0.0);
|
vec3 tangent = vec3(0.0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NORMAL_USED
|
#ifdef NORMAL_USED
|
||||||
vec3 normal = normalize(normal_interp);
|
vec3 normal = normal_interp;
|
||||||
|
|
||||||
#if defined(DO_SIDE_CHECK)
|
#if defined(DO_SIDE_CHECK)
|
||||||
if (!gl_FrontFacing) {
|
if (!gl_FrontFacing) {
|
||||||
normal = -normal;
|
normal = -normal;
|
||||||
}
|
}
|
||||||
#endif
|
#endif // DO_SIDE_CHECK
|
||||||
|
vec3 geo_normal = normalize(normal);
|
||||||
#endif //NORMAL_USED
|
#endif // NORMAL_USED
|
||||||
|
|
||||||
#ifdef UV_USED
|
#ifdef UV_USED
|
||||||
vec2 uv = uv_interp;
|
vec2 uv = uv_interp;
|
||||||
@@ -1020,21 +1022,22 @@ void main() {
|
|||||||
|
|
||||||
#endif // !USE_SHADOW_TO_OPACITY
|
#endif // !USE_SHADOW_TO_OPACITY
|
||||||
|
|
||||||
#ifdef NORMAL_MAP_USED
|
#if defined(NORMAL_MAP_USED)
|
||||||
|
|
||||||
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
normal_map.xy = normal_map.xy * 2.0 - 1.0;
|
||||||
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
normal_map.z = sqrt(max(0.0, 1.0 - dot(normal_map.xy, normal_map.xy))); //always ignore Z, as it can be RG packed, Z may be pos/neg, etc.
|
||||||
|
|
||||||
|
// Tangent-space transformation is performed using unnormalized TBN vectors, per MikkTSpace.
|
||||||
|
// See: http://www.mikktspace.com/
|
||||||
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
normal = normalize(mix(normal, tangent * normal_map.x + binormal * normal_map.y + normal * normal_map.z, normal_map_depth));
|
||||||
|
#elif defined(NORMAL_USED)
|
||||||
#endif
|
normal = geo_normal;
|
||||||
|
#endif // NORMAL_MAP_USED
|
||||||
|
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
|
|
||||||
if (anisotropy > 0.01) {
|
if (anisotropy > 0.01) {
|
||||||
//rotation matrix
|
mat3 rot = mat3(normalize(tangent), normalize(binormal), normal);
|
||||||
mat3 rot = mat3(tangent, binormal, normal);
|
// Make local to space.
|
||||||
//make local to space
|
|
||||||
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
tangent = normalize(rot * vec3(anisotropy_flow.x, anisotropy_flow.y, 0.0));
|
||||||
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
binormal = normalize(rot * vec3(-anisotropy_flow.y, anisotropy_flow.x, 0.0));
|
||||||
}
|
}
|
||||||
@@ -1091,7 +1094,7 @@ void main() {
|
|||||||
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);
|
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);
|
||||||
|
|
||||||
if (decals.data[decal_index].normal_fade > 0.0) {
|
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);
|
fade *= smoothstep(decals.data[decal_index].normal_fade, 1.0, dot(geo_normal, decals.data[decal_index].normal) * 0.5 + 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
//we need ddx/ddy for mipmaps, so simulate them
|
//we need ddx/ddy for mipmaps, so simulate them
|
||||||
@@ -1238,10 +1241,9 @@ void main() {
|
|||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
|
|
||||||
if (sc_scene_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(geo_normal, view), 0.0001); // We want to use geometric normal, not normal_map
|
||||||
float NoV = max(dot(n, view), 0.0001);
|
vec3 ref_vec = reflect(-view, geo_normal);
|
||||||
vec3 ref_vec = reflect(-view, n);
|
ref_vec = mix(ref_vec, geo_normal, clearcoat_roughness * clearcoat_roughness);
|
||||||
ref_vec = mix(ref_vec, n, clearcoat_roughness * clearcoat_roughness);
|
|
||||||
// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
|
// The clear coat layer assumes an IOR of 1.5 (4% reflectance)
|
||||||
float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
|
float Fc = clearcoat * (0.04 + 0.96 * SchlickFresnel(NoV));
|
||||||
float attenuation = 1.0 - Fc;
|
float attenuation = 1.0 - Fc;
|
||||||
@@ -1481,7 +1483,7 @@ void main() {
|
|||||||
vec4 pssm_coord;
|
vec4 pssm_coord;
|
||||||
float blur_factor;
|
float blur_factor;
|
||||||
vec3 light_dir = directional_lights.data[i].direction;
|
vec3 light_dir = directional_lights.data[i].direction;
|
||||||
vec3 base_normal_bias = normalize(normal_interp) * (1.0 - max(0.0, dot(light_dir, -normalize(normal_interp))));
|
vec3 base_normal_bias = geo_normal * (1.0 - max(0.0, dot(light_dir, -geo_normal)));
|
||||||
|
|
||||||
#define BIAS_FUNC(m_var, m_idx) \
|
#define BIAS_FUNC(m_var, m_idx) \
|
||||||
m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
|
m_var.xyz += light_dir * directional_lights.data[i].shadow_bias[m_idx]; \
|
||||||
@@ -1663,8 +1665,8 @@ void main() {
|
|||||||
rim, rim_tint,
|
rim, rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
binormal, tangent, anisotropy,
|
binormal, tangent, anisotropy,
|
||||||
#endif
|
#endif
|
||||||
@@ -1694,8 +1696,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent,
|
tangent,
|
||||||
binormal, anisotropy,
|
binormal, anisotropy,
|
||||||
@@ -1722,8 +1724,8 @@ void main() {
|
|||||||
rim_tint,
|
rim_tint,
|
||||||
#endif
|
#endif
|
||||||
#ifdef LIGHT_CLEARCOAT_USED
|
#ifdef LIGHT_CLEARCOAT_USED
|
||||||
clearcoat, clearcoat_roughness, normalize(normal_interp),
|
clearcoat, clearcoat_roughness, geo_normal,
|
||||||
#endif
|
#endif // LIGHT_CLEARCOAT_USED
|
||||||
#ifdef LIGHT_ANISOTROPY_USED
|
#ifdef LIGHT_ANISOTROPY_USED
|
||||||
tangent,
|
tangent,
|
||||||
binormal, anisotropy,
|
binormal, anisotropy,
|
||||||
|
|||||||
Reference in New Issue
Block a user