ShaderGenerator: normalize tangent/binormal/normal after interpolation

Also changes l_eye_normal interpolant from float4 to float3.
This commit is contained in:
rdb 2018-11-08 15:53:34 +01:00
parent e5f398a861
commit 6051e6f305

View File

@ -850,7 +850,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
if (need_eye_normal) { if (need_eye_normal) {
eye_normal_freg = alloc_freg(); eye_normal_freg = alloc_freg();
text << "\t uniform float4x4 tpose_view_to_model,\n"; text << "\t uniform float4x4 tpose_view_to_model,\n";
text << "\t out float4 l_eye_normal : " << eye_normal_freg << ",\n"; text << "\t out float3 l_eye_normal : " << eye_normal_freg << ",\n";
} }
if ((key._texture_flags & ShaderKey::TF_map_height) != 0 || need_world_normal || need_eye_normal) { if ((key._texture_flags & ShaderKey::TF_map_height) != 0 || need_world_normal || need_eye_normal) {
text << "\t in float3 vtx_normal : " << normal_vreg << ",\n"; text << "\t in float3 vtx_normal : " << normal_vreg << ",\n";
@ -937,8 +937,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t l_eye_position = mul(trans_model_to_view, vtx_position);\n"; text << "\t l_eye_position = mul(trans_model_to_view, vtx_position);\n";
} }
if (need_eye_normal) { if (need_eye_normal) {
text << "\t l_eye_normal.xyz = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n"; text << "\t l_eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n";
text << "\t l_eye_normal.w = 0;\n";
} }
pmap<const InternalName *, const char *>::const_iterator it; pmap<const InternalName *, const char *>::const_iterator it;
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) { for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
@ -987,7 +986,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t in float4 l_eye_position : " << eye_position_freg << ",\n"; text << "\t in float4 l_eye_position : " << eye_position_freg << ",\n";
} }
if (need_eye_normal) { if (need_eye_normal) {
text << "\t in float4 l_eye_normal : " << eye_normal_freg << ",\n"; text << "\t in float3 l_eye_normal : " << eye_normal_freg << ",\n";
} }
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) { for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
text << "\t in float4 l_" << it->first->join("_") << " : " << it->second << ",\n"; text << "\t in float4 l_" << it->first->join("_") << " : " << it->second << ",\n";
@ -1096,8 +1095,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t float4 texcoord" << i << " = l_eye_position;\n"; text << "\t float4 texcoord" << i << " = l_eye_position;\n";
break; break;
case TexGenAttrib::M_eye_normal: case TexGenAttrib::M_eye_normal:
text << "\t float4 texcoord" << i << " = l_eye_normal;\n"; text << "\t float4 texcoord" << i << " = float4(l_eye_normal, 1.0f);\n";
text << "\t texcoord" << i << ".w = 1.0f;\n";
break; break;
default: default:
text << "\t float4 texcoord" << i << " = float4(0, 0, 0, 0);\n"; text << "\t float4 texcoord" << i << " = float4(0, 0, 0, 0);\n";
@ -1187,6 +1185,10 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << ");\n"; text << ");\n";
} }
} }
if (need_eye_normal) {
text << "\t // Correct the surface normal for interpolation effects\n";
text << "\t l_eye_normal = normalize(l_eye_normal);\n";
}
if (key._texture_flags & ShaderKey::TF_map_normal) { if (key._texture_flags & ShaderKey::TF_map_normal) {
text << "\t // Translate tangent-space normal in map to view-space.\n"; text << "\t // Translate tangent-space normal in map to view-space.\n";
@ -1196,7 +1198,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
const ShaderKey::TextureInfo &tex = key._textures[i]; const ShaderKey::TextureInfo &tex = key._textures[i];
if (tex._flags & ShaderKey::TF_map_normal) { if (tex._flags & ShaderKey::TF_map_normal) {
if (is_first) { if (is_first) {
text << "\t float3 tsnormal = (tex" << i << ".xyz * 2) - 1;\n"; text << "\t float3 tsnormal = normalize((tex" << i << ".xyz * 2) - 1);\n";
is_first = false; is_first = false;
continue; continue;
} }
@ -1205,17 +1207,14 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t tsnormal = normalize(tsnormal * dot(tsnormal, tmp" << i << ") - tmp" << i << " * tsnormal.z);\n"; text << "\t tsnormal = normalize(tsnormal * dot(tsnormal, tmp" << i << ") - tmp" << i << " * tsnormal.z);\n";
} }
} }
text << "\t l_eye_normal.xyz *= tsnormal.z;\n"; text << "\t l_eye_normal *= tsnormal.z;\n";
text << "\t l_eye_normal.xyz += l_tangent * tsnormal.x;\n"; text << "\t l_eye_normal += normalize(l_tangent) * tsnormal.x;\n";
text << "\t l_eye_normal.xyz += l_binormal * tsnormal.y;\n"; text << "\t l_eye_normal += normalize(l_binormal) * tsnormal.y;\n";
} text << "\t l_eye_normal = normalize(l_eye_normal);\n";
if (need_eye_normal) {
text << "\t // Correct the surface normal for interpolation effects\n";
text << "\t l_eye_normal.xyz = normalize(l_eye_normal.xyz);\n";
} }
if (key._outputs & AuxBitplaneAttrib::ABO_aux_normal) { if (key._outputs & AuxBitplaneAttrib::ABO_aux_normal) {
text << "\t // Output the camera-space surface normal\n"; text << "\t // Output the camera-space surface normal\n";
text << "\t o_aux.rgb = (l_eye_normal.xyz*0.5) + float3(0.5,0.5,0.5);\n"; text << "\t o_aux.rgb = (l_eye_normal*0.5) + float3(0.5,0.5,0.5);\n";
} }
if (key._lighting) { if (key._lighting) {
text << "\t // Begin view-space light calculations\n"; text << "\t // Begin view-space light calculations\n";
@ -1251,7 +1250,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t lspec = lcolor;\n"; text << "\t lspec = lcolor;\n";
} }
text << "\t lvec = attr_light" << i << "[3].xyz;\n"; text << "\t lvec = attr_light" << i << "[3].xyz;\n";
text << "\t lcolor *= saturate(dot(l_eye_normal.xyz, lvec.xyz));\n"; text << "\t lcolor *= saturate(dot(l_eye_normal, lvec.xyz));\n";
if (light._flags & ShaderKey::LF_has_shadows) { if (light._flags & ShaderKey::LF_has_shadows) {
if (_use_shadow_filter) { if (_use_shadow_filter) {
text << "\t lshad = shadow2DProj(shadow_" << i << ", l_lightcoord" << i << ").r;\n"; text << "\t lshad = shadow2DProj(shadow_" << i << ", l_lightcoord" << i << ").r;\n";
@ -1268,7 +1267,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
} else { } else {
text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n"; text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n";
} }
text << "\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf)), shininess);\n"; text << "\t lspec *= pow(saturate(dot(l_eye_normal, lhalf)), shininess);\n";
text << "\t tot_specular += lspec;\n"; text << "\t tot_specular += lspec;\n";
} }
} else if (light._type.is_derived_from(PointLight::get_class_type())) { } else if (light._type.is_derived_from(PointLight::get_class_type())) {
@ -1288,7 +1287,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t ldist = max(ldist, attr_light" << i << "[2].w);\n"; text << "\t ldist = max(ldist, attr_light" << i << "[2].w);\n";
} }
text << "\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n"; text << "\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n";
text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec));\n"; text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal, lvec));\n";
if (light._flags & ShaderKey::LF_has_shadows) { if (light._flags & ShaderKey::LF_has_shadows) {
text << "\t ldist = max(abs(l_lightcoord" << i << ".x), max(abs(l_lightcoord" << i << ".y), abs(l_lightcoord" << i << ".z)));\n"; text << "\t ldist = max(abs(l_lightcoord" << i << ".x), max(abs(l_lightcoord" << i << ".y), abs(l_lightcoord" << i << ".z)));\n";
text << "\t ldist = ((latten.w+lpoint.w)/(latten.w-lpoint.w))+((-2*latten.w*lpoint.w)/(ldist * (latten.w-lpoint.w)));\n"; text << "\t ldist = ((latten.w+lpoint.w)/(latten.w-lpoint.w))+((-2*latten.w*lpoint.w)/(ldist * (latten.w-lpoint.w)));\n";
@ -1304,7 +1303,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n"; text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\n";
} }
text << "\t lspec *= lattenv;\n"; text << "\t lspec *= lattenv;\n";
text << "\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf)), shininess);\n"; text << "\t lspec *= pow(saturate(dot(l_eye_normal, lhalf)), shininess);\n";
text << "\t tot_specular += lspec;\n"; text << "\t tot_specular += lspec;\n";
} }
} else if (light._type.is_derived_from(Spotlight::get_class_type())) { } else if (light._type.is_derived_from(Spotlight::get_class_type())) {
@ -1325,7 +1324,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n"; text << "\t lattenv = 1/(latten.x + latten.y*ldist + latten.z*ldist*ldist);\n";
text << "\t lattenv *= pow(langle, latten.w);\n"; text << "\t lattenv *= pow(langle, latten.w);\n";
text << "\t if (langle < ldir.w) lattenv = 0;\n"; text << "\t if (langle < ldir.w) lattenv = 0;\n";
text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal.xyz, lvec));\n"; text << "\t lcolor *= lattenv * saturate(dot(l_eye_normal, lvec));\n";
if (light._flags & ShaderKey::LF_has_shadows) { if (light._flags & ShaderKey::LF_has_shadows) {
if (_use_shadow_filter) { if (_use_shadow_filter) {
text << "\t lshad = shadow2DProj(shadow_" << i << ", l_lightcoord" << i << ").r;\n"; text << "\t lshad = shadow2DProj(shadow_" << i << ", l_lightcoord" << i << ").r;\n";
@ -1344,7 +1343,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
text << "\t lhalf = normalize(lvec - float3(0,1,0));\n"; text << "\t lhalf = normalize(lvec - float3(0,1,0));\n";
} }
text << "\t lspec *= lattenv;\n"; text << "\t lspec *= lattenv;\n";
text << "\t lspec *= pow(saturate(dot(l_eye_normal.xyz, lhalf)), shininess);\n"; text << "\t lspec *= pow(saturate(dot(l_eye_normal, lhalf)), shininess);\n";
text << "\t tot_specular += lspec;\n"; text << "\t tot_specular += lspec;\n";
} }
} }