mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-01 01:07:51 -04:00
ShaderGenerator: pack eye-space normal to save one varying
Only when normal mapping is enabled.
This commit is contained in:
parent
376cef51c4
commit
dc8f01df8a
@ -749,6 +749,11 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
bool need_world_normal = false;
|
||||
bool need_eye_position = key._lighting;
|
||||
bool need_eye_normal = !key._lights.empty() || ((key._outputs & AuxBitplaneAttrib::ABO_aux_normal) != 0);
|
||||
bool need_tangents = ((key._texture_flags & ShaderKey::TF_map_normal) != 0);
|
||||
|
||||
// If we have binormal/tangent and eye position, we can pack eye normal in
|
||||
// the w channels of the others.
|
||||
bool pack_eye_normal = need_eye_normal && need_tangents && need_eye_position;
|
||||
|
||||
bool have_specular = false;
|
||||
if (key._lighting) {
|
||||
@ -829,7 +834,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
map_index_gloss = i;
|
||||
}
|
||||
}
|
||||
if (key._texture_flags & ShaderKey::TF_map_normal) {
|
||||
if (need_tangents) {
|
||||
tangent_freg = alloc_freg();
|
||||
binormal_freg = alloc_freg();
|
||||
text << "\t out float4 l_tangent : " << tangent_freg << ",\n";
|
||||
@ -854,14 +859,16 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t uniform float4x4 trans_model_to_view,\n";
|
||||
eye_position_freg = alloc_freg();
|
||||
text << "\t out float4 l_eye_position : " << eye_position_freg << ",\n";
|
||||
} else if (key._texture_flags & ShaderKey::TF_map_normal) {
|
||||
} else if (need_tangents) {
|
||||
text << "\t uniform float4x4 trans_model_to_view,\n";
|
||||
}
|
||||
if (need_eye_normal) {
|
||||
eye_normal_freg = alloc_freg();
|
||||
text << "\t uniform float4x4 tpose_view_to_model,\n";
|
||||
if (!pack_eye_normal) {
|
||||
eye_normal_freg = alloc_freg();
|
||||
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) {
|
||||
text << "\t in float3 vtx_normal : " << normal_vreg << ",\n";
|
||||
}
|
||||
@ -946,9 +953,6 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
if (need_eye_position) {
|
||||
text << "\t l_eye_position = mul(trans_model_to_view, vtx_position);\n";
|
||||
}
|
||||
if (need_eye_normal) {
|
||||
text << "\t l_eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n";
|
||||
}
|
||||
pmap<const InternalName *, const char *>::const_iterator it;
|
||||
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
||||
// Pass through all texcoord inputs as-is.
|
||||
@ -958,7 +962,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
if (need_color && key._color_type == ColorAttrib::T_vertex) {
|
||||
text << "\t l_color = vtx_color;\n";
|
||||
}
|
||||
if (key._texture_flags & ShaderKey::TF_map_normal) {
|
||||
if (need_tangents) {
|
||||
text << "\t l_tangent.xyz = normalize(mul((float3x3)trans_model_to_view, vtx_" << tangent_input << ".xyz));\n";
|
||||
text << "\t l_tangent.w = 0;\n";
|
||||
text << "\t l_binormal.xyz = normalize(mul((float3x3)trans_model_to_view, -vtx_" << binormal_input << ".xyz));\n";
|
||||
@ -976,6 +980,17 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t l_eyevec.z = dot(vtx_normal, eyedir);\n";
|
||||
text << "\t l_eyevec = normalize(l_eyevec);\n";
|
||||
}
|
||||
if (need_eye_normal) {
|
||||
if (pack_eye_normal) {
|
||||
// We can pack the normal into the w channels of these unused varyings.
|
||||
text << "\t float3 eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n";
|
||||
text << "\t l_tangent.w = eye_normal.x;\n";
|
||||
text << "\t l_binormal.w = eye_normal.y;\n";
|
||||
text << "\t l_eye_position.w = eye_normal.z;\n";
|
||||
} else {
|
||||
text << "\t l_eye_normal = normalize(mul((float3x3)tpose_view_to_model, vtx_normal));\n";
|
||||
}
|
||||
}
|
||||
text << "}\n\n";
|
||||
|
||||
// Fragment shader
|
||||
@ -995,7 +1010,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
if (need_eye_position) {
|
||||
text << "\t in float4 l_eye_position : " << eye_position_freg << ",\n";
|
||||
}
|
||||
if (need_eye_normal) {
|
||||
if (need_eye_normal && !pack_eye_normal) {
|
||||
text << "\t in float3 l_eye_normal : " << eye_normal_freg << ",\n";
|
||||
}
|
||||
for (it = texcoord_fregs.begin(); it != texcoord_fregs.end(); ++it) {
|
||||
@ -1020,9 +1035,9 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t uniform float4 texcolor_" << i << ",\n";
|
||||
}
|
||||
}
|
||||
if (key._texture_flags & ShaderKey::TF_map_normal) {
|
||||
text << "\t in float3 l_tangent : " << tangent_freg << ",\n";
|
||||
text << "\t in float3 l_binormal : " << binormal_freg << ",\n";
|
||||
if (need_tangents) {
|
||||
text << "\t in float4 l_tangent : " << tangent_freg << ",\n";
|
||||
text << "\t in float4 l_binormal : " << binormal_freg << ",\n";
|
||||
}
|
||||
for (size_t i = 0; i < key._lights.size(); ++i) {
|
||||
text << "\t uniform float4x4 attr_light" << i << ",\n";
|
||||
@ -1078,6 +1093,12 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t discard;\n";
|
||||
text << "\t }\n";
|
||||
}
|
||||
|
||||
// Reconstruct a packed normal vector.
|
||||
if (need_eye_normal && pack_eye_normal) {
|
||||
text << "\t float3 l_eye_normal = float3(l_tangent.w, l_binormal.w, l_eye_position.w);\n";
|
||||
}
|
||||
|
||||
text << "\t float4 result;\n";
|
||||
if (key._outputs & (AuxBitplaneAttrib::ABO_aux_normal | AuxBitplaneAttrib::ABO_aux_glow)) {
|
||||
text << "\t o_aux = float4(0, 0, 0, 0);\n";
|
||||
@ -1102,7 +1123,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
text << "\t float4 texcoord" << i << " = l_world_normal;\n";
|
||||
break;
|
||||
case TexGenAttrib::M_eye_position:
|
||||
text << "\t float4 texcoord" << i << " = l_eye_position;\n";
|
||||
text << "\t float4 texcoord" << i << " = float4(l_eye_position.xyz, 1.0f);\n";
|
||||
break;
|
||||
case TexGenAttrib::M_eye_normal:
|
||||
text << "\t float4 texcoord" << i << " = float4(l_eye_normal, 1.0f);\n";
|
||||
@ -1199,7 +1220,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
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 (need_tangents) {
|
||||
text << "\t // Translate tangent-space normal in map to view-space.\n";
|
||||
|
||||
// Use Reoriented Normal Mapping to blend additional normal maps.
|
||||
@ -1218,8 +1239,8 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
|
||||
}
|
||||
}
|
||||
text << "\t l_eye_normal *= tsnormal.z;\n";
|
||||
text << "\t l_eye_normal += normalize(l_tangent) * tsnormal.x;\n";
|
||||
text << "\t l_eye_normal += normalize(l_binormal) * tsnormal.y;\n";
|
||||
text << "\t l_eye_normal += normalize(l_tangent.xyz) * tsnormal.x;\n";
|
||||
text << "\t l_eye_normal += normalize(l_binormal.xyz) * tsnormal.y;\n";
|
||||
text << "\t l_eye_normal = normalize(l_eye_normal);\n";
|
||||
}
|
||||
if (key._outputs & AuxBitplaneAttrib::ABO_aux_normal) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user