@@ -472,7 +472,7 @@ analyze_renderstate(ShaderKey &key, const RenderState *rs) {
472
472
* - flat colors
473
473
* - vertex colors
474
474
* - lighting
475
- * - normal maps, but not multiple
475
+ * - normal maps, even multiple
476
476
* - gloss maps, but not multiple
477
477
* - glow maps, but not multiple
478
478
* - materials, but not updates to materials
@@ -569,7 +569,6 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
569
569
rs->write (text, 2 );
570
570
text << " */\n " ;
571
571
572
- int map_index_normal = -1 ;
573
572
int map_index_glow = -1 ;
574
573
int map_index_gloss = -1 ;
575
574
@@ -620,7 +619,8 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
620
619
}
621
620
}
622
621
623
- if (tex._flags & (ShaderKey::TF_map_normal | ShaderKey::TF_map_height)) {
622
+ if (tangent_input.empty () &&
623
+ (tex._flags & (ShaderKey::TF_map_normal | ShaderKey::TF_map_height)) != 0 ) {
624
624
PT (InternalName) tangent_name = InternalName::get_tangent ();
625
625
PT (InternalName) binormal_name = InternalName::get_binormal ();
626
626
@@ -629,19 +629,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
629
629
tangent_name = tangent_name->append (tex._texcoord_name ->get_basename ());
630
630
binormal_name = binormal_name->append (tex._texcoord_name ->get_basename ());
631
631
}
632
+
632
633
tangent_input = tangent_name->join (" _" );
633
634
binormal_input = binormal_name->join (" _" );
634
635
635
636
text << " \t in float4 vtx_" << tangent_input << " : " << alloc_vreg () << " ,\n " ;
636
637
text << " \t in float4 vtx_" << binormal_input << " : " << alloc_vreg () << " ,\n " ;
637
-
638
- if (tex._flags & ShaderKey::TF_map_normal) {
639
- map_index_normal = i;
640
- tangent_freg = alloc_freg ();
641
- binormal_freg = alloc_freg ();
642
- text << " \t out float4 l_tangent : " << tangent_freg << " ,\n " ;
643
- text << " \t out float4 l_binormal : " << binormal_freg << " ,\n " ;
644
- }
645
638
}
646
639
647
640
if (tex._flags & ShaderKey::TF_map_glow) {
@@ -651,6 +644,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
651
644
map_index_gloss = i;
652
645
}
653
646
}
647
+ if (key._texture_flags & ShaderKey::TF_map_normal) {
648
+ tangent_freg = alloc_freg ();
649
+ binormal_freg = alloc_freg ();
650
+ text << " \t out float4 l_tangent : " << tangent_freg << " ,\n " ;
651
+ text << " \t out float4 l_binormal : " << binormal_freg << " ,\n " ;
652
+ }
654
653
if (key._color_type == ColorAttrib::T_vertex) {
655
654
text << " \t in float4 vtx_color : " << color_vreg << " ,\n " ;
656
655
text << " \t out float4 l_color : COLOR0,\n " ;
@@ -1000,7 +999,22 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
1000
999
}
1001
1000
if (key._texture_flags & ShaderKey::TF_map_normal) {
1002
1001
text << " \t // Translate tangent-space normal in map to view-space.\n " ;
1003
- text << " \t float3 tsnormal = ((float3)tex" << map_index_normal << " * 2) - 1;\n " ;
1002
+
1003
+ // Use Reoriented Normal Mapping to blend additional normal maps.
1004
+ bool is_first = true ;
1005
+ for (size_t i = 0 ; i < key._textures .size (); ++i) {
1006
+ const ShaderKey::TextureInfo &tex = key._textures [i];
1007
+ if (tex._flags & ShaderKey::TF_map_normal) {
1008
+ if (is_first) {
1009
+ text << " \t float3 tsnormal = (tex" << i << " .xyz * 2) - 1;\n " ;
1010
+ is_first = false ;
1011
+ continue ;
1012
+ }
1013
+ text << " \t tsnormal.z += 1;\n " ;
1014
+ text << " \t float3 tmp" << i << " = tex" << i << " .xyz * float3(-2, -2, 2) + float3(1, 1, -1);\n " ;
1015
+ text << " \t tsnormal = normalize(tsnormal * dot(tsnormal, tmp" << i << " ) - tmp" << i << " * tsnormal.z);\n " ;
1016
+ }
1017
+ }
1004
1018
text << " \t l_eye_normal.xyz *= tsnormal.z;\n " ;
1005
1019
text << " \t l_eye_normal.xyz += l_tangent * tsnormal.x;\n " ;
1006
1020
text << " \t l_eye_normal.xyz += l_binormal * tsnormal.y;\n " ;
0 commit comments