Skip to content

Commit 65ae1e1

Browse files
committed
ShaderGenerator: support multiple normal maps
Uses Reoriented Normal Mapping to blend additional normal maps. Fixes panda3d#156
1 parent f79fbf2 commit 65ae1e1

File tree

1 file changed

+26
-12
lines changed

1 file changed

+26
-12
lines changed

panda/src/pgraphnodes/shaderGenerator.cxx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ analyze_renderstate(ShaderKey &key, const RenderState *rs) {
472472
* - flat colors
473473
* - vertex colors
474474
* - lighting
475-
* - normal maps, but not multiple
475+
* - normal maps, even multiple
476476
* - gloss maps, but not multiple
477477
* - glow maps, but not multiple
478478
* - materials, but not updates to materials
@@ -569,7 +569,6 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
569569
rs->write(text, 2);
570570
text << "*/\n";
571571

572-
int map_index_normal = -1;
573572
int map_index_glow = -1;
574573
int map_index_gloss = -1;
575574

@@ -620,7 +619,8 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
620619
}
621620
}
622621

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) {
624624
PT(InternalName) tangent_name = InternalName::get_tangent();
625625
PT(InternalName) binormal_name = InternalName::get_binormal();
626626

@@ -629,19 +629,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
629629
tangent_name = tangent_name->append(tex._texcoord_name->get_basename());
630630
binormal_name = binormal_name->append(tex._texcoord_name->get_basename());
631631
}
632+
632633
tangent_input = tangent_name->join("_");
633634
binormal_input = binormal_name->join("_");
634635

635636
text << "\t in float4 vtx_" << tangent_input << " : " << alloc_vreg() << ",\n";
636637
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-
}
645638
}
646639

647640
if (tex._flags & ShaderKey::TF_map_glow) {
@@ -651,6 +644,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
651644
map_index_gloss = i;
652645
}
653646
}
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+
}
654653
if (key._color_type == ColorAttrib::T_vertex) {
655654
text << "\t in float4 vtx_color : " << color_vreg << ",\n";
656655
text << "\t out float4 l_color : COLOR0,\n";
@@ -1000,7 +999,22 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
1000999
}
10011000
if (key._texture_flags & ShaderKey::TF_map_normal) {
10021001
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+
}
10041018
text << "\t l_eye_normal.xyz *= tsnormal.z;\n";
10051019
text << "\t l_eye_normal.xyz += l_tangent * tsnormal.x;\n";
10061020
text << "\t l_eye_normal.xyz += l_binormal * tsnormal.y;\n";

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy