|
@@ -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;
|
|
|
|
- binormal_interp = binormal;
|
|
|
|
|
|
+ tangent_interp = normalize(tangent);
|
|
|
|
+ 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 tangent = normalize(tangent_interp);
|
|
|
|
|
|
+ vec3 binormal = binormal_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 //NORMAL_USED
|
|
|
|
|
|
+#endif // DO_SIDE_CHECK
|
|
|
|
+ vec3 geo_normal = normalize(normal);
|
|
|
|
+#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));
|
|
-
|
|
|
|
-#endif
|
|
|
|
|
|
+#elif defined(NORMAL_USED)
|
|
|
|
+ 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(tangent, binormal, normal);
|
|
|
|
- //make local to space
|
|
|
|
|
|
+ mat3 rot = mat3(normalize(tangent), normalize(binormal), normal);
|
|
|
|
+ // 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(n, view), 0.0001);
|
|
|
|
- vec3 ref_vec = reflect(-view, n);
|
|
|
|
|
|
+ float NoV = max(dot(geo_normal, view), 0.0001); // We want to use geometric normal, not normal_map
|
|
|
|
+ vec3 ref_vec = reflect(-view, geo_normal);
|
|
|
|
+ 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),
|
|
|
|
-#endif
|
|
|
|
|
|
+ clearcoat, clearcoat_roughness, geo_normal,
|
|
|
|
+#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),
|
|
|
|
-#endif
|
|
|
|
|
|
+ clearcoat, clearcoat_roughness, geo_normal,
|
|
|
|
+#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),
|
|
|
|
-#endif
|
|
|
|
|
|
+ clearcoat, clearcoat_roughness, geo_normal,
|
|
|
|
+#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;
|
|
|
|
|