瀏覽代碼

ShaderGenerator: normalize tangent/binormal/normal after interpolation

Also changes l_eye_normal interpolant from float4 to float3.
rdb 7 年之前
父節點
當前提交
6051e6f305
共有 1 個文件被更改,包括 20 次插入21 次删除
  1. 20 21
      panda/src/pgraphnodes/shaderGenerator.cxx

+ 20 - 21
panda/src/pgraphnodes/shaderGenerator.cxx

@@ -850,7 +850,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
   if (need_eye_normal) {
     eye_normal_freg = alloc_freg();
     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) {
     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";
   }
   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.w = 0;\n";
+    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) {
@@ -987,7 +986,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
     text << "\t in float4 l_eye_position : " << eye_position_freg << ",\n";
   }
   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) {
     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";
       break;
     case TexGenAttrib::M_eye_normal:
-      text << "\t float4 texcoord" << i << " = l_eye_normal;\n";
-      text << "\t texcoord" << i << ".w = 1.0f;\n";
+      text << "\t float4 texcoord" << i << " = float4(l_eye_normal, 1.0f);\n";
       break;
     default:
       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";
     }
   }
+  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) {
     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];
       if (tex._flags & ShaderKey::TF_map_normal) {
         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;
           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 l_eye_normal.xyz *= tsnormal.z;\n";
-    text << "\t l_eye_normal.xyz += l_tangent * tsnormal.x;\n";
-    text << "\t l_eye_normal.xyz += l_binormal * tsnormal.y;\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";
+    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_eye_normal);\n";
   }
   if (key._outputs & AuxBitplaneAttrib::ABO_aux_normal) {
     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) {
     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 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 (_use_shadow_filter) {
           text << "\t lshad = shadow2DProj(shadow_" << i << ", l_lightcoord" << i << ").r;\n";
@@ -1268,7 +1267,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
         } else {
           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";
       }
     } 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 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) {
         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";
@@ -1304,7 +1303,7 @@ synthesize_shader(const RenderState *rs, const GeomVertexAnimationSpec &anim) {
           text << "\t lhalf = normalize(lvec - float3(0, 1, 0));\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";
       }
     } 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 *= pow(langle, latten.w);\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 (_use_shadow_filter) {
           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 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";
       }
     }