Browse Source

Improvements to shader generation

Josh Yelon 18 years ago
parent
commit
a9dc480500

+ 20 - 19
direct/src/filter/CommonFilters.py

@@ -19,23 +19,23 @@ from FilterManager import FilterManager
 from pandac.PandaModules import Point3, Vec3, Vec4
 from pandac.PandaModules import Point3, Vec3, Vec4
 from pandac.PandaModules import NodePath, PandaNode
 from pandac.PandaModules import NodePath, PandaNode
 from pandac.PandaModules import Filename
 from pandac.PandaModules import Filename
+from pandac.PandaModules import AuxBitplaneAttrib
 from pandac.PandaModules import RenderState, Texture, Shader
 from pandac.PandaModules import RenderState, Texture, Shader
 import sys,os
 import sys,os
 
 
 CARTOON_BODY="""
 CARTOON_BODY="""
-float4 cartoondelta = k_cartoonseparation * texpix_txnormal.xwyw;
+float4 cartoondelta = k_cartoonseparation * texpix_txaux.xwyw;
 float4 cartoon_p0 = l_texcoordN + cartoondelta.xyzw;
 float4 cartoon_p0 = l_texcoordN + cartoondelta.xyzw;
-float4 cartoon_c0 = tex2D(k_txnormal, cartoon_p0.xy);
+float4 cartoon_c0 = tex2D(k_txaux, cartoon_p0.xy);
 float4 cartoon_p1 = l_texcoordN - cartoondelta.xyzw;
 float4 cartoon_p1 = l_texcoordN - cartoondelta.xyzw;
-float4 cartoon_c1 = tex2D(k_txnormal, cartoon_p1.xy);
+float4 cartoon_c1 = tex2D(k_txaux, cartoon_p1.xy);
 float4 cartoon_p2 = l_texcoordN + cartoondelta.wzyx;
 float4 cartoon_p2 = l_texcoordN + cartoondelta.wzyx;
-float4 cartoon_c2 = tex2D(k_txnormal, cartoon_p2.xy);
+float4 cartoon_c2 = tex2D(k_txaux, cartoon_p2.xy);
 float4 cartoon_p3 = l_texcoordN - cartoondelta.wzyx;
 float4 cartoon_p3 = l_texcoordN - cartoondelta.wzyx;
-float4 cartoon_c3 = tex2D(k_txnormal, cartoon_p3.xy);
+float4 cartoon_c3 = tex2D(k_txaux, cartoon_p3.xy);
 float4 cartoon_mx = max(cartoon_c0,max(cartoon_c1,max(cartoon_c2,cartoon_c3)));
 float4 cartoon_mx = max(cartoon_c0,max(cartoon_c1,max(cartoon_c2,cartoon_c3)));
 float4 cartoon_mn = min(cartoon_c0,min(cartoon_c1,min(cartoon_c2,cartoon_c3)));
 float4 cartoon_mn = min(cartoon_c0,min(cartoon_c1,min(cartoon_c2,cartoon_c3)));
-float4 cartoon_trigger = saturate(((cartoon_mx-cartoon_mn) * 3) - k_cartooncutoff.x);
-float  cartoon_thresh = dot(cartoon_trigger.xyz,float3(1,1,1));
+float cartoon_thresh = saturate(dot(cartoon_mx - cartoon_mn, float4(3,3,0,0)) - 0.5);
 o_color = lerp(o_color, float4(0,0,0,1), cartoon_thresh);
 o_color = lerp(o_color, float4(0,0,0,1), cartoon_thresh);
 """
 """
 
 
@@ -76,20 +76,23 @@ class CommonFilters:
             if (len(configuration) == 0):
             if (len(configuration) == 0):
                 return
                 return
 
 
+            auxbits = 0
             needtex = {}
             needtex = {}
             needtex["color"] = True
             needtex["color"] = True
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
-                needtex["normal"] = True
+                needtex["aux"] = True
+                auxbits |= AuxBitplaneAttrib.ABOAuxNormal
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
                 needtex["bloom0"] = True
                 needtex["bloom0"] = True
                 needtex["bloom1"] = True
                 needtex["bloom1"] = True
                 needtex["bloom2"] = True
                 needtex["bloom2"] = True
                 needtex["bloom3"] = True
                 needtex["bloom3"] = True
+                auxbits |= AuxBitplaneAttrib.ABOGlow
             for tex in needtex:
             for tex in needtex:
                 self.textures[tex] = Texture("scene-"+tex)
                 self.textures[tex] = Texture("scene-"+tex)
                 needtexpix = True
                 needtexpix = True
 
 
-            self.finalQuad = self.manager.renderSceneInto(textures = self.textures)
+            self.finalQuad = self.manager.renderSceneInto(textures = self.textures, auxbits=auxbits)
     
     
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
                 bloomconf = configuration["Bloom"]
                 bloomconf = configuration["Bloom"]
@@ -126,8 +129,8 @@ class CommonFilters:
             text += " uniform float4 texpix_txcolor,\n"
             text += " uniform float4 texpix_txcolor,\n"
             text += " out float4 l_texcoordC : TEXCOORD0,\n"
             text += " out float4 l_texcoordC : TEXCOORD0,\n"
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
-                text += " uniform float4 texpad_txnormal,\n"
-                text += " uniform float4 texpix_txnormal,\n"
+                text += " uniform float4 texpad_txaux,\n"
+                text += " uniform float4 texpix_txaux,\n"
                 text += " out float4 l_texcoordN : TEXCOORD1,\n"
                 text += " out float4 l_texcoordN : TEXCOORD1,\n"
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
                 text += " uniform float4 texpad_txbloom3,\n"
                 text += " uniform float4 texpad_txbloom3,\n"
@@ -137,13 +140,13 @@ class CommonFilters:
             text += " l_position=mul(mat_modelproj, vtx_position);\n"
             text += " l_position=mul(mat_modelproj, vtx_position);\n"
             text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n"
             text += " l_texcoordC=(vtx_position.xzxz * texpad_txcolor) + texpad_txcolor;\n"
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
-                text += " l_texcoordN=(vtx_position.xzxz * texpad_txnormal) + texpad_txnormal;\n"
+                text += " l_texcoordN=(vtx_position.xzxz * texpad_txaux) + texpad_txaux;\n"
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
                 text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n"
                 text += " l_texcoordB=(vtx_position.xzxz * texpad_txbloom3) + texpad_txbloom3;\n"
             if (configuration.has_key("HalfPixelShift")):
             if (configuration.has_key("HalfPixelShift")):
                 text += " l_texcoordC+=texpix_txcolor*0.5;\n"
                 text += " l_texcoordC+=texpix_txcolor*0.5;\n"
                 if (configuration.has_key("CartoonInk")):
                 if (configuration.has_key("CartoonInk")):
-                    text += " l_texcoordN+=texpix_txnormal*0.5;\n"
+                    text += " l_texcoordN+=texpix_txaux*0.5;\n"
             text += "}\n"
             text += "}\n"
 
 
             text += "void fshader(\n"
             text += "void fshader(\n"
@@ -151,14 +154,13 @@ class CommonFilters:
             text += "uniform float4 texpix_txcolor,\n"
             text += "uniform float4 texpix_txcolor,\n"
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
                 text += "float4 l_texcoordN : TEXCOORD1,\n"
                 text += "float4 l_texcoordN : TEXCOORD1,\n"
-                text += "uniform float4 texpix_txnormal,\n"
+                text += "uniform float4 texpix_txaux,\n"
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
                 text += "float4 l_texcoordB : TEXCOORD2,\n"
                 text += "float4 l_texcoordB : TEXCOORD2,\n"
             for key in self.textures:
             for key in self.textures:
                 text += "uniform sampler2D k_tx" + key + ",\n"
                 text += "uniform sampler2D k_tx" + key + ",\n"
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
                 text += "uniform float4 k_cartoonseparation,\n"
                 text += "uniform float4 k_cartoonseparation,\n"
-                text += "uniform float4 k_cartooncutoff,\n"
             text += "out float4 o_color : COLOR)\n"
             text += "out float4 o_color : COLOR)\n"
             text += "{\n"
             text += "{\n"
             text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n"
             text += " o_color = tex2D(k_txcolor, l_texcoordC.xy);\n"
@@ -177,9 +179,8 @@ class CommonFilters:
 
 
         if (changed == "CartoonInk") or fullrebuild:
         if (changed == "CartoonInk") or fullrebuild:
             if (configuration.has_key("CartoonInk")):
             if (configuration.has_key("CartoonInk")):
-                (separation, cutoff) = configuration["CartoonInk"]
+                separation = configuration["CartoonInk"]
                 self.finalQuad.setShaderInput("cartoonseparation", Vec4(separation,0,separation,0))
                 self.finalQuad.setShaderInput("cartoonseparation", Vec4(separation,0,separation,0))
-                self.finalQuad.setShaderInput("cartooncutoff", Vec4(cutoff,cutoff,cutoff,cutoff))
 
 
         if (changed == "Bloom") or fullrebuild:
         if (changed == "Bloom") or fullrebuild:
             if (configuration.has_key("Bloom")):
             if (configuration.has_key("Bloom")):
@@ -190,9 +191,9 @@ class CommonFilters:
                 self.bloom[0].setShaderInput("desat", bloomconf.desat)
                 self.bloom[0].setShaderInput("desat", bloomconf.desat)
                 self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity)
                 self.bloom[3].setShaderInput("intensity", intensity, intensity, intensity, intensity)
 
 
-    def setCartoonInk(self, separation=1, cutoff=0.3):
+    def setCartoonInk(self, separation=1):
         fullrebuild = (self.configuration.has_key("CartoonInk") == False)
         fullrebuild = (self.configuration.has_key("CartoonInk") == False)
-        self.configuration["CartoonInk"] = (separation, cutoff)
+        self.configuration["CartoonInk"] = separation
         self.reconfigure(fullrebuild, "CartoonInk")
         self.reconfigure(fullrebuild, "CartoonInk")
 
 
     def delCartoonInk(self):
     def delCartoonInk(self):

+ 7 - 10
direct/src/filter/FilterManager.py

@@ -119,7 +119,7 @@ class FilterManager:
 
 
         return winx,winy
         return winx,winy
 
 
-    def renderSceneInto(self, depthtex=False, colortex=False, normaltex=False, textures=None):
+    def renderSceneInto(self, depthtex=False, colortex=False, auxtex=False, auxbits=0, textures=None):
 
 
         """ Causes the scene to be rendered into the supplied textures
         """ Causes the scene to be rendered into the supplied textures
         instead of into the original window.  Puts a fullscreen quad
         instead of into the original window.  Puts a fullscreen quad
@@ -163,11 +163,11 @@ class FilterManager:
         if (textures):
         if (textures):
             colortex = textures.get("color", None)
             colortex = textures.get("color", None)
             depthtex = textures.get("depth", None)
             depthtex = textures.get("depth", None)
-            normaltex = textures.get("normal", None)
+            auxtex = textures.get("aux", None)
 
 
         if (colortex == None): colortex = Texture("filter-base-color")
         if (colortex == None): colortex = Texture("filter-base-color")
 
 
-        texgroup = (depthtex, colortex, normaltex, None)
+        texgroup = (depthtex, colortex, auxtex, None)
 
 
         # Choose the size of the offscreen buffer.
         # Choose the size of the offscreen buffer.
 
 
@@ -186,14 +186,11 @@ class FilterManager:
         quad.setTexture(colortex)
         quad.setTexture(colortex)
         quad.setColor(Vec4(1,0.5,0.5,1))
         quad.setColor(Vec4(1,0.5,0.5,1))
 
 
-        auxbits = AuxBitplaneAttrib.ABOColor;
-        if (normaltex != None):
-            auxbits += AuxBitplaneAttrib.ABOCsnormal;
-        
         cs = NodePath("dummy")
         cs = NodePath("dummy")
         cs.setState(self.caminit)
         cs.setState(self.caminit)
         cs.setShaderAuto();
         cs.setShaderAuto();
-        cs.setAttrib(AuxBitplaneAttrib.make(auxbits))
+        if (auxbits):
+            cs.setAttrib(AuxBitplaneAttrib.make(auxbits))
         self.camera.node().setInitialState(cs.getState())
         self.camera.node().setInitialState(cs.getState())
 
 
         quadcamnode = Camera("filter-quad-cam")
         quadcamnode = Camera("filter-quad-cam")
@@ -208,9 +205,9 @@ class FilterManager:
 
 
         dr = buffer.getDisplayRegion(0)
         dr = buffer.getDisplayRegion(0)
         self.setStackedClears(dr, self.rclears, self.wclears)
         self.setStackedClears(dr, self.rclears, self.wclears)
-        if (normaltex):
+        if (auxtex):
             dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1)
             dr.setClearActive(GraphicsOutput.RTPAuxRgba0, 1)
-            dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.0,0.0,0.0,0.0))
+            dr.setClearValue(GraphicsOutput.RTPAuxRgba0, Vec4(0.5,0.5,1.0,0.0))
         self.region.disableClears()
         self.region.disableClears()
         if (self.isFullscreen()):
         if (self.isFullscreen()):
             self.win.disableClears()
             self.win.disableClears()

+ 2 - 2
panda/src/pgraph/auxBitplaneAttrib.cxx

@@ -36,7 +36,7 @@ CPT(RenderAttrib) AuxBitplaneAttrib::_default;
 CPT(RenderAttrib) AuxBitplaneAttrib::
 CPT(RenderAttrib) AuxBitplaneAttrib::
 make() {
 make() {
   if (_default == 0) {
   if (_default == 0) {
-    AuxBitplaneAttrib *attrib = new AuxBitplaneAttrib(ABO_color);
+    AuxBitplaneAttrib *attrib = new AuxBitplaneAttrib(0);
     _default = return_new(attrib);
     _default = return_new(attrib);
   }
   }
   return _default;
   return _default;
@@ -102,7 +102,7 @@ compare_to_impl(const RenderAttrib *other) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 RenderAttrib *AuxBitplaneAttrib::
 RenderAttrib *AuxBitplaneAttrib::
 make_default_impl() const {
 make_default_impl() const {
-  return new AuxBitplaneAttrib(ABO_color);
+  return new AuxBitplaneAttrib(0);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 29 - 5
panda/src/pgraph/auxBitplaneAttrib.h

@@ -29,8 +29,30 @@ class FactoryParams;
 // Description : Modern frame buffers can have 'aux' bitplanes, which
 // Description : Modern frame buffers can have 'aux' bitplanes, which
 //               are additional bitplanes above and beyond the
 //               are additional bitplanes above and beyond the
 //               standard depth and color.  This attrib controls what
 //               standard depth and color.  This attrib controls what
-//               gets rendered into those additional bitplanes when
-//               using the standard shader generator.
+//               gets rendered into those additional bitplanes.  It
+//               can also affect what goes into the alpha channel
+//               of the primary color buffer.
+//
+//               ABO_glow: copy the glow map into the alpha channel
+//               of the primary frame buffer.  If there is no glow
+//               map, set it to zero.  Caveat: it is not
+//               possible to write glow or depth values to the
+//               framebuffer alpha channel at the same time as using
+//               alpha blending or alpha testing.  Any attempt to use
+//               transparency, blending, or alpha testing will cause
+//               this flag to be overridden.
+//
+//               ABO_aux_normal: put the camera-space normal into
+//               the into the R,G components of the first auxiliary
+//               bitplane.
+//
+//               ABO_aux_modelz: put the clip-space Z coordinate of
+//               the center of the model (after perspective divide)
+//               into the B channel of the first auxiliary bitplane.
+//
+//               ABO_aux_glow: put a copy of the glow map into the
+//               alpha channel of the first auxiliary bitplane.
+//               If there is no glow map, set it to zero.
 //
 //
 //               AuxBitplaneAttrib is relevant only when shader
 //               AuxBitplaneAttrib is relevant only when shader
 //               generation is enabled. Otherwise, it has no effect.
 //               generation is enabled. Otherwise, it has no effect.
@@ -42,9 +64,11 @@ private:
 
 
 PUBLISHED:
 PUBLISHED:
   enum AuxBitplaneOutput {
   enum AuxBitplaneOutput {
-    ABO_color = 1,     // Render an ordinary scene into the ordinary color buffer.
-    ABO_csnormal = 2,  // Render a camera-space normal into an aux bitplane.
-    ABO_glowalpha = 4, // Render all glow maps into the color buffer alpha channel.
+    ABO_glow = 1,
+    
+    ABO_aux_normal = 2,
+    ABO_aux_modelz = 4,
+    ABO_aux_glow = 8,
   };
   };
   static CPT(RenderAttrib) make();
   static CPT(RenderAttrib) make();
   static CPT(RenderAttrib) make(int outputs);
   static CPT(RenderAttrib) make(int outputs);

+ 87 - 38
panda/src/pgraph/shaderGenerator.cxx

@@ -146,15 +146,30 @@ analyze_renderstate(const RenderState *rs) {
 
 
   rs->store_into_slots(&_attribs);
   rs->store_into_slots(&_attribs);
 
 
-  // Figure out which bitplane should hold which output.
-  
-  int next = 0;
-  if (_attribs._aux_bitplane->get_outputs() & AuxBitplaneAttrib::ABO_color) {
-    _bitplane_color = next++;
+  // Check if there's an alpha test, color blend, or transparency.
+
+  if ((_attribs._alpha_test->get_mode() != RenderAttrib::M_none)&&
+      (_attribs._alpha_test->get_mode() != RenderAttrib::M_always)) {
+    _have_alpha_test = true;
+  }
+  if (_attribs._color_blend->get_mode() != ColorBlendAttrib::M_none) {
+    _have_color_blend = true;
+  }
+  if (_attribs._transparency->get_mode() != TransparencyAttrib::M_none) {
+    _have_transparency = true;
   }
   }
-  if (_attribs._aux_bitplane->get_outputs() & AuxBitplaneAttrib::ABO_csnormal) {
-    _bitplane_normal = next++;
+  
+  // Determine what output values are desired.
+  
+  int outputs = _attribs._aux_bitplane->get_outputs();
+  if (_have_alpha_test || _have_color_blend || _have_transparency) {
+    _out_primary_alpha = true;
+  } else {
+    _out_primary_glow = (outputs & AuxBitplaneAttrib::ABO_glow) ? true:false;
   }
   }
+  _out_aux_normal = (outputs & AuxBitplaneAttrib::ABO_aux_normal) ? true:false;
+  _out_aux_glow = (outputs & AuxBitplaneAttrib::ABO_aux_glow) ? true:false;
+  _out_aux_any = (_out_aux_normal || _out_aux_glow);
 
 
   // Count number of textures.
   // Count number of textures.
 
 
@@ -165,12 +180,10 @@ analyze_renderstate(const RenderState *rs) {
   
   
   // Determine whether or not vertex colors or flat colors are present.
   // Determine whether or not vertex colors or flat colors are present.
 
 
-  if ((_bitplane_color >= 0)&&(_attribs._color != 0)) {
-    if (_attribs._color->get_color_type() == ColorAttrib::T_vertex) {
-      _vertex_colors = true;
-    } else if (_attribs._color->get_color_type() == ColorAttrib::T_flat) {
-      _flat_colors = true;
-    }
+  if (_attribs._color->get_color_type() == ColorAttrib::T_vertex) {
+    _vertex_colors = true;
+  } else if (_attribs._color->get_color_type() == ColorAttrib::T_flat) {
+    _flat_colors = true;
   }
   }
 
 
   // Break out the lights by type.
   // Break out the lights by type.
@@ -221,8 +234,7 @@ analyze_renderstate(const RenderState *rs) {
   
   
   // Determine whether lighting is needed.
   // Determine whether lighting is needed.
 
 
-  if ((_bitplane_color >= 0) &&
-      (_attribs._light->get_num_on_lights() > 0)) {
+  if (_attribs._light->get_num_on_lights() > 0) {
     _lighting = true;
     _lighting = true;
   }
   }
   
   
@@ -331,11 +343,18 @@ clear_analysis() {
   _map_index_height = -1;
   _map_index_height = -1;
   _map_index_glow = -1;
   _map_index_glow = -1;
   _map_index_gloss = -1;
   _map_index_gloss = -1;
-  _bitplane_color = -1;
-  _bitplane_normal = -1;
+  _have_alpha_test = false;
+  _have_color_blend = false;
+  _have_transparency = false;
+  _out_primary_alpha = false;
+  _out_primary_glow  = false;
+  _out_aux_normal = false;
+  _out_aux_glow   = false;
+  _out_aux_any    = false;
   _attribs.clear_to_defaults();
   _attribs.clear_to_defaults();
   _material = (Material*)NULL;
   _material = (Material*)NULL;
   _need_material_props = false;
   _need_material_props = false;
+  _need_clipspace_pos = false;
   _alights.clear();
   _alights.clear();
   _dlights.clear();
   _dlights.clear();
   _plights.clear();
   _plights.clear();
@@ -387,21 +406,20 @@ create_shader_attrib(const string &txt) {
 //               - lighting
 //               - lighting
 //               - normal maps
 //               - normal maps
 //               - gloss maps
 //               - gloss maps
+//               - glow maps
 //               - materials, but not updates to materials
 //               - materials, but not updates to materials
-//               - modulated 2D textures
+//               - 2D textures
 //               - texture stage modes: modulate, decal, add
 //               - texture stage modes: modulate, decal, add
 //               - light ramps (for cartoon shading)
 //               - light ramps (for cartoon shading)
 //
 //
 //               Not yet supported:
 //               Not yet supported:
-//               - 3D textures
-//               - cube textures
+//               - 3D textures, cube textures
 //               - texture stage modes: replace, blend
 //               - texture stage modes: replace, blend
 //               - color scale attrib
 //               - color scale attrib
 //               - texgen
 //               - texgen
 //               - texmatrix
 //               - texmatrix
-//               - glow maps (not yet sure what these should do)
+//               - fog
 //               - other TextureStage::Modes
 //               - other TextureStage::Modes
-//               - cartoon thresholding and other special effects
 //
 //
 //               Potential optimizations
 //               Potential optimizations
 //               - omit attenuation calculations if attenuation off
 //               - omit attenuation calculations if attenuation off
@@ -422,6 +440,7 @@ synthesize_shader(const RenderState *rs) {
   char *binormal_vreg = 0;
   char *binormal_vreg = 0;
   char *binormal_freg = 0;
   char *binormal_freg = 0;
   char *csnormal_freg = 0;
   char *csnormal_freg = 0;
+  char *clip_freg = 0;
   pvector<char *> texcoord_vreg;
   pvector<char *> texcoord_vreg;
   pvector<char *> texcoord_freg;
   pvector<char *> texcoord_freg;
   pvector<char *> tslightvec_freg;
   pvector<char *> tslightvec_freg;
@@ -466,7 +485,11 @@ synthesize_shader(const RenderState *rs) {
       text << "\t out float4 l_binormal : " << binormal_freg << ",\n";
       text << "\t out float4 l_binormal : " << binormal_freg << ",\n";
     }
     }
   }
   }
-  if (_bitplane_normal >= 0) {
+  if (_need_clipspace_pos) {
+    clip_freg = alloc_freg();
+    text << "\t out float4 l_clip : " << clip_freg << ",\n";
+  }
+  if (_out_aux_normal) {
     if (normal_vreg == 0) {
     if (normal_vreg == 0) {
       normal_vreg = alloc_vreg();
       normal_vreg = alloc_vreg();
       text << "\t in float4 vtx_normal : " << normal_vreg << ",\n";
       text << "\t in float4 vtx_normal : " << normal_vreg << ",\n";
@@ -482,7 +505,9 @@ synthesize_shader(const RenderState *rs) {
   text << ") {\n";
   text << ") {\n";
   
   
   text << "\t l_position = mul(mat_modelproj, vtx_position);\n";
   text << "\t l_position = mul(mat_modelproj, vtx_position);\n";
-
+  if (_need_clipspace_pos) {
+    text << "\t l_clip = l_position;\n";
+  }
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
     text << "\t l_texcoord" << i << " = vtx_texcoord" << i << ";\n";
     text << "\t l_texcoord" << i << " = vtx_texcoord" << i << ";\n";
   }
   }
@@ -497,7 +522,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t l_binormal = -vtx_binormal" << _map_index_normal << ";\n";
       text << "\t l_binormal = -vtx_binormal" << _map_index_normal << ";\n";
     }
     }
   }
   }
-  if (_bitplane_normal >= 0) {
+  if (_out_aux_normal) {
     text << "\t l_csnormal.xyz = mul(itp_modelview, vtx_normal);\n";
     text << "\t l_csnormal.xyz = mul(itp_modelview, vtx_normal);\n";
     text << "\t l_csnormal.w = 0;\n";
     text << "\t l_csnormal.w = 0;\n";
   }
   }
@@ -542,13 +567,16 @@ synthesize_shader(const RenderState *rs) {
       }
       }
     }
     }
   }
   }
-  if (_bitplane_normal >= 0) {
+  if (_out_aux_normal) {
     text << "\t in float4 l_csnormal : " << csnormal_freg << ",\n";
     text << "\t in float4 l_csnormal : " << csnormal_freg << ",\n";
-    text << "\t out float4 o_csnormal : COLOR" << _bitplane_normal << ",\n";
   }
   }
-  if (_bitplane_color >= 0) {
-    text << "\t out float4 o_color : COLOR" << _bitplane_color << ",\n";
+  if (_need_clipspace_pos) {
+    text << "\t in float4 l_clip : " << clip_freg << ",\n";
+  }
+  if (_out_aux_any) {
+    text << "\t out float4 o_aux : COLOR1,\n";
   }
   }
+  text << "\t out float4 o_color : COLOR0,\n";
   if (_vertex_colors) {
   if (_vertex_colors) {
     text << "\t in float4 l_color : COLOR\n";
     text << "\t in float4 l_color : COLOR\n";
   } else {
   } else {
@@ -556,6 +584,9 @@ synthesize_shader(const RenderState *rs) {
   }
   }
   text << ") {\n";
   text << ") {\n";
   text << "\t float4 result;\n";
   text << "\t float4 result;\n";
+  if (_out_aux_any) {
+    text << "\t o_aux = float4(0,0,0,0);\n";
+  }
   text << "\t // Fetch all textures.\n";
   text << "\t // Fetch all textures.\n";
   for (int i=0; i<_num_textures; i++) {
   for (int i=0; i<_num_textures; i++) {
     text << "\t float4 tex" << i << " = tex2D(tex_" << i << ", float2(l_texcoord" << i << "));\n";
     text << "\t float4 tex" << i << " = tex2D(tex_" << i << ", float2(l_texcoord" << i << "));\n";
@@ -573,9 +604,9 @@ synthesize_shader(const RenderState *rs) {
       text << "\t l_normal = normalize(l_normal);\n";
       text << "\t l_normal = normalize(l_normal);\n";
     }
     }
   }
   }
-  if (_bitplane_normal >= 0) {
+  if (_out_aux_normal) {
     text << "\t // Output the camera-space surface normal\n";
     text << "\t // Output the camera-space surface normal\n";
-    text << "\t o_csnormal = (normalize(l_csnormal)*0.5) + float4(0.5,0.5,0.5,0);\n";
+    text << "\t o_aux.rg = ((normalize(l_csnormal)*0.5) + float4(0.5,0.5,0.5,0)).rg;\n";
   }
   }
   if (_lighting) {
   if (_lighting) {
     text << "\t // Begin model-space light calculations\n";
     text << "\t // Begin model-space light calculations\n";
@@ -747,7 +778,7 @@ synthesize_shader(const RenderState *rs) {
 
 
     // Combine in alpha, which bypasses lighting calculations.
     // Combine in alpha, which bypasses lighting calculations.
     // Use of lerp here is a workaround for a radeon driver bug.
     // Use of lerp here is a workaround for a radeon driver bug.
-    if (_map_index_glow < 0) {
+    if (_out_primary_alpha) {
       if (_vertex_colors) {
       if (_vertex_colors) {
         text << "\t result.a = l_color.a;\n";
         text << "\t result.a = l_color.a;\n";
       } else if (_flat_colors) {
       } else if (_flat_colors) {
@@ -785,7 +816,9 @@ synthesize_shader(const RenderState *rs) {
       break;
       break;
     case TextureStage::M_add:
     case TextureStage::M_add:
       text << "\t result.rbg = result.rgb + tex" << i << ".rgb;\n";
       text << "\t result.rbg = result.rgb + tex" << i << ".rgb;\n";
-      text << "\t result.a   = result.a * tex" << i << ".a;\n";
+      if (_out_primary_alpha) {
+        text << "\t result.a   = result.a * tex" << i << ".a;\n";
+      }
       break;
       break;
     case TextureStage::M_combine:
     case TextureStage::M_combine:
       pgraph_cat.error() << "TextureStage::Mode COMBINE not yet supported in per-pixel mode.\n";
       pgraph_cat.error() << "TextureStage::Mode COMBINE not yet supported in per-pixel mode.\n";
@@ -797,6 +830,22 @@ synthesize_shader(const RenderState *rs) {
       break;
       break;
     }
     }
   }
   }
+
+  if (_out_primary_glow) {
+    if (_map_index_glow >= 0) {
+      text << "\t result.a = tex" << _map_index_glow << ".a;\n";
+    } else {
+      text << "\t result.a = 0;\n";
+    }
+  }
+  if (_out_aux_glow) {
+    if (_map_index_glow >= 0) {
+      text << "\t o_aux.a = tex" << _map_index_glow << ".a;\n";
+    } else {
+      text << "\t o_aux.a = 0;\n";
+    }
+  }
+  
   if (_lighting) {
   if (_lighting) {
     if (_have_specular) {
     if (_have_specular) {
       if (_material->has_specular()) {
       if (_material->has_specular()) {
@@ -808,6 +857,7 @@ synthesize_shader(const RenderState *rs) {
       text << "\t result.rgb = result.rgb + tot_specular.rgb;\n";
       text << "\t result.rgb = result.rgb + tot_specular.rgb;\n";
     }
     }
   }
   }
+  
   switch (_attribs._light_ramp->get_mode()) {
   switch (_attribs._light_ramp->get_mode()) {
   case LightRampAttrib::LRT_hdr0:
   case LightRampAttrib::LRT_hdr0:
     text << "\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n";
     text << "\t result.rgb = (result*result*result + result*result + result) / (result*result*result + result*result + result + 1);\n";
@@ -820,11 +870,10 @@ synthesize_shader(const RenderState *rs) {
     break;
     break;
   default: break;
   default: break;
   }
   }
-  if (_bitplane_color >= 0) {
-    // The multiply is a workaround for a radeon driver bug.
-    // It's annoying as heck, since it produces an extra instruction.
-    text << "\t o_color = result * 1.000001;\n"; 
-  }
+  
+  // The multiply is a workaround for a radeon driver bug.
+  // It's annoying as heck, since it produces an extra instruction.
+  text << "\t o_color = result * 1.000001;\n"; 
   text << "}\n";
   text << "}\n";
   
   
   // Insert the shader into the shader attrib.
   // Insert the shader into the shader attrib.

+ 11 - 3
panda/src/pgraph/shaderGenerator.h

@@ -117,10 +117,18 @@ protected:
   int _map_index_height;
   int _map_index_height;
   int _map_index_glow;
   int _map_index_glow;
   int _map_index_gloss;
   int _map_index_gloss;
+
+  bool _out_primary_alpha;
+  bool _out_primary_glow;
+  bool _out_aux_normal;
+  bool _out_aux_glow;
+  bool _out_aux_any;
+
+  bool _have_alpha_test;
+  bool _have_color_blend;
+  bool _have_transparency;
   
   
-  int _bitplane_color;
-  int _bitplane_normal;
-  
+  bool _need_clipspace_pos;
   bool _need_material_props;
   bool _need_material_props;
   
   
   void analyze_renderstate(const RenderState *rs);
   void analyze_renderstate(const RenderState *rs);