File vegastrike-data-0.5.1.r1-r13368.patch of Package vegastrike-data

Index: techniques/1_ps1.2/fireglass.technique
===================================================================
--- techniques/1_ps1.2/fireglass.technique	(revision 0)
+++ techniques/1_ps1.2/fireglass.technique	(revision 13369)
@@ -0,0 +1,113 @@
+<?xml version="1.0"?>
+<technique fallback="../0_fixed_gl/fireglass">
+    <!-- Fallback technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+	 constant (nD) of about 1.47 to 1.48.).
+
+         It deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back".
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass_simple"/>
+        <fragment_program src="fireglass_simple"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass_simple"/>
+        <fragment_program src="fireglass_simple"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/4_ps2.0/fireglass.technique
===================================================================
--- techniques/4_ps2.0/fireglass.technique	(revision 0)
+++ techniques/4_ps2.0/fireglass.technique	(revision 13369)
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<technique fallback="../2_ps1.4/fireglass">
+    <!-- Full-blown shader technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+         constant (nD) of about 1.47 to 1.48.) Beware that this shader is not for
+         solid glass objects or chrystals... It does NOT perturb the background
+         refractively.
+         What it does do is compute precise, physics-based Fresnel reflectivity, and
+         with multiple internal reflections between the two sides of the glass sheet.
+
+         Furthermore, it deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_damg.png (4x4) is identical to bubble_diff.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Future work:
+         The reason for having a glow texture, (besides the fact that its alpha
+         channel carries the ambient occlusion); and a specular texture (beside
+         the fact of its carrying shininess in alpha), is to, in the future,
+         implement a couple of little hacks...
+         First, if we assume a tiny bit of diffuse reflectivity for glass, we could do
+         a radio bake of inner world light sources onto the glass. Thus, a glass dome
+         over a citadel, like those on the mining base, could get light from indoor
+         lights, with shadows projected by the buildings. This would be put straight
+         into the RGB channels of bubble_glow.png.
+         Second, the RGB channels of bubble_spec.png could contain some kind of
+         rendering of the inside of the cockpit or whatever is housed by the glass
+         dome. A special texture mapping algorithm used only for the first pass
+         (far-side glass) only, would reflect view vectors in some quirky way onto
+         the glow map, to make it appear that the far side of the cockpit or dome
+         is reflecting what's inside.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back". Furthermore, the passes are nowhere nearly as complex
+         as those of the UberShader, and therefore we might be able to allow four
+         lights, instead of just two, which is important because reflections on
+         something as glossy as glass would be hard not to miss 'em BAD, if absent.
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/4_ps2.0/default.technique
===================================================================
--- techniques/4_ps2.0/default.technique	(revision 13368)
+++ techniques/4_ps2.0/default.technique	(revision 13369)
@@ -1,33 +1,28 @@
 <?xml version="1.0"?>
-<technique fallback="fixed">
+<technique fallback="../4_ps2.0/default">
     <!-- Full-blown shader technique, with Z-write prepass to avoid
          shading overhead for occluded fragments.
          
-         This is a slight simplification of the highend version, simplifying
-         environment filtering, light attenuation and some other minor stuff 
-         to get a lighter version of the same effects. The quality decreases 
-         a bit, but it is far more compatible with older hardware.
-         
          This technique implements normal-mapping, specmaps with intensity-derived
          shininess modulation, variable-kernel filtered environmental reflections
          (based on shininess), specularity normalization, fading damage maps with
-         specmap perturbation, and supports up to 8 lights.
+         specmap perturbation, and supports up to 12 lights.
          
-         This is a one-pass technique, so only the first 2 lights are done 
+         This is a multi-pass technique, handles 2 lights per pass
          per-pixel, the remaining ones use per-vertex lighting.
     -->
 
     <!-- Z-write prepasses go at sequence 10 -->
-    <pass type="shader" sequence="10" cwrite="false">
+    <pass type="shader" sequence="10" cull="back" cwrite="false">
         <vertex_program src="zwrite"/>
         <fragment_program src="zwrite"/>
         <texture_unit src="decal:0" default="file:white.bmp" name="diffuseMap"/>
     </pass>
     
     <!-- first and only lighting pass -->
-    <pass type="shader" sequence="15" zwrite="false">
-        <vertex_program src="default"/>
-        <fragment_program src="default"/>
+    <pass type="shader" sequence="15" cull="back" zwrite="false">
+        <vertex_program src="highend"/>
+        <fragment_program src="highend"/>
         
         <texture_unit src="decal:0" default="file:white.bmp" name="diffuseMap"/>
         <texture_unit src="environment" name="envMap"/>
@@ -47,5 +42,6 @@
         <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
         <auto_param name="damage" semantic="Damage4" optional="true"/>
         <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
     </pass>
 </technique>
Index: techniques/2_ps1.4/fireglass.technique
===================================================================
--- techniques/2_ps1.4/fireglass.technique	(revision 0)
+++ techniques/2_ps1.4/fireglass.technique	(revision 13369)
@@ -0,0 +1,113 @@
+<?xml version="1.0"?>
+<technique fallback="../0_fixed_gl/fireglass">
+    <!-- Fallback technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+	 constant (nD) of about 1.47 to 1.48.).
+
+         It deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back".
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass_simple"/>
+        <fragment_program src="fireglass_simple"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass_simple"/>
+        <fragment_program src="fireglass_simple"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/5_ps3.0/fireglass.technique
===================================================================
--- techniques/5_ps3.0/fireglass.technique	(revision 0)
+++ techniques/5_ps3.0/fireglass.technique	(revision 13369)
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<technique fallback="../2_ps1.4/fireglass">
+    <!-- Full-blown shader technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+         constant (nD) of about 1.47 to 1.48.) Beware that this shader is not for
+         solid glass objects or chrystals... It does NOT perturb the background
+         refractively.
+         What it does do is compute precise, physics-based Fresnel reflectivity, and
+         with multiple internal reflections between the two sides of the glass sheet.
+
+         Furthermore, it deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_damg.png (4x4) is identical to bubble_diff.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Future work:
+         The reason for having a glow texture, (besides the fact that its alpha
+         channel carries the ambient occlusion); and a specular texture (beside
+         the fact of its carrying shininess in alpha), is to, in the future,
+         implement a couple of little hacks...
+         First, if we assume a tiny bit of diffuse reflectivity for glass, we could do
+         a radio bake of inner world light sources onto the glass. Thus, a glass dome
+         over a citadel, like those on the mining base, could get light from indoor
+         lights, with shadows projected by the buildings. This would be put straight
+         into the RGB channels of bubble_glow.png.
+         Second, the RGB channels of bubble_spec.png could contain some kind of
+         rendering of the inside of the cockpit or whatever is housed by the glass
+         dome. A special texture mapping algorithm used only for the first pass
+         (far-side glass) only, would reflect view vectors in some quirky way onto
+         the glow map, to make it appear that the far side of the cockpit or dome
+         is reflecting what's inside.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back". Furthermore, the passes are nowhere nearly as complex
+         as those of the UberShader, and therefore we might be able to allow four
+         lights, instead of just two, which is important because reflections on
+         something as glossy as glass would be hard not to miss 'em BAD, if absent.
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/6_ps4.0/fireglass.technique
===================================================================
--- techniques/6_ps4.0/fireglass.technique	(revision 0)
+++ techniques/6_ps4.0/fireglass.technique	(revision 13369)
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<technique fallback="../2_ps1.4/fireglass">
+    <!-- Full-blown shader technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+         constant (nD) of about 1.47 to 1.48.) Beware that this shader is not for
+         solid glass objects or chrystals... It does NOT perturb the background
+         refractively.
+         What it does do is compute precise, physics-based Fresnel reflectivity, and
+         with multiple internal reflections between the two sides of the glass sheet.
+
+         Furthermore, it deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_damg.png (4x4) is identical to bubble_diff.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Future work:
+         The reason for having a glow texture, (besides the fact that its alpha
+         channel carries the ambient occlusion); and a specular texture (beside
+         the fact of its carrying shininess in alpha), is to, in the future,
+         implement a couple of little hacks...
+         First, if we assume a tiny bit of diffuse reflectivity for glass, we could do
+         a radio bake of inner world light sources onto the glass. Thus, a glass dome
+         over a citadel, like those on the mining base, could get light from indoor
+         lights, with shadows projected by the buildings. This would be put straight
+         into the RGB channels of bubble_glow.png.
+         Second, the RGB channels of bubble_spec.png could contain some kind of
+         rendering of the inside of the cockpit or whatever is housed by the glass
+         dome. A special texture mapping algorithm used only for the first pass
+         (far-side glass) only, would reflect view vectors in some quirky way onto
+         the glow map, to make it appear that the far side of the cockpit or dome
+         is reflecting what's inside.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back". Furthermore, the passes are nowhere nearly as complex
+         as those of the UberShader, and therefore we might be able to allow four
+         lights, instead of just two, which is important because reflections on
+         something as glossy as glass would be hard not to miss 'em BAD, if absent.
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/0_fixed_gl/fireglass.technique
===================================================================
--- techniques/0_fixed_gl/fireglass.technique	(revision 0)
+++ techniques/0_fixed_gl/fireglass.technique	(revision 13369)
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<technique>
+    <!-- Fixed-function fallback for fireglass technique.
+         Uses the built-in fixed function technique set (adaptive)
+         to render enabled effects in two passes: back (inner) glass, front (outer) glass.
+    -->
+
+    <pass type="fixed" sequence="15" blend="default" cull="front">
+        <texture_unit src="decal:0" target="0" default="file:bubble_diff.texture" name="diffuseMap"/>
+    </pass>
+    <pass type="fixed" sequence="15" blend="default" cull="back">
+        <texture_unit src="decal:0" target="0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="decal:1" target="2" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:2" target="3" default="decal:0" name="damageMap"/>
+    </pass>
+</technique>
Index: techniques/3_arbfp/fireglass.technique
===================================================================
--- techniques/3_arbfp/fireglass.technique	(revision 0)
+++ techniques/3_arbfp/fireglass.technique	(revision 13369)
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<technique fallback="../2_ps1.4/fireglass">
+    <!-- Full-blown shader technique for representing sheet glass, lucite, acrylic
+         or plexiglass. (All look the same, really; almost exactly the same refractive
+         constant (nD) of about 1.47 to 1.48.) Beware that this shader is not for
+         solid glass objects or chrystals... It does NOT perturb the background
+         refractively.
+         What it does do is compute precise, physics-based Fresnel reflectivity, and
+         with multiple internal reflections between the two sides of the glass sheet.
+
+         Furthermore, it deals with a very old problem:
+         
+         Traditionally, in Vegastrike, sheet glass has been represented with blending
+         mode of "ONE ONE" and cull mode of "none". The former, for performance; and
+         the latter for correctness. The problem is that the former is incorrect, and
+         the latter, in spite of being correct, it looks terrible. The reason it does
+         is that the back-facing glass you see in a cockpit or glass dome would NOT
+         reflect the sky; it would reflect the inside of the cockpit or whatever the
+         dome covers. But due to lack of specular occlusion, what it does reflec is
+         sky, as if the cockpit had no pilot and no floor.
+         One solution I've found works better is to simply use cull="back"; i.e. only
+         show the glass facing you (the camera), and ignore the other side.
+         While better, this neglects the fact that the far side of the cockpit also
+         blocks light coming through, as a function of angle, by Fresnel rules.
+         
+         The sheet_glass technique deals with these problems by,
+         a) Using blending mode of "ONE ONEMINUSSRCALPHA".
+         b) Doing a first rendering pass with cull="front", to render the far side;
+         and applying fresnel to its apparent transparency; but it does NOT apply
+         specular light reflections or environment mapping.
+         c) Doing a second rendering pass with cull="back", to render the near side,
+         with full specularity and with normal-mapping.
+         
+         More details:
+         Five textures are supplied under the /textures game folder, and used for
+         glass by default.
+           * bubble_diff.png (4x4) is black, with alpha of 0.1 to play well with
+           non-shader-capable gpu's. 10% blending for glass looks okay, when it
+           isn't possible to compute angle-based reflectivity and transparency.
+           * bubble_spec.png (4x4) is white, with alpha 1.0, for maximum gloss.
+           * bubble_damg.png (4x4) is identical to bubble_diff.
+           * bubble_glow.png (128x128) has a bit of yellow light, and a generic
+           ambient occlusion (for a hemisphere on a plane) in the alpha channel.
+           This AO allows a rough computation of specular occlusion on outer
+           reflections. But you may want to supply your own "bubble_glow.png",
+           with a custom-baked AO for more accurate specular occlusion.
+           * bubble_norm.png (256x256) has generic, tileable bumpiness, which the
+           shader scales down considerably before applying to the outside for
+           perturbing the environmental reflections. (Glass is a high viscosity
+           liquid, rather than a solid. Over the years, windows become wobbly as
+           they "drip down".)
+         Note that clean glass doesn't have much of diffuse reflectivity, ergo
+         the default black diffuse texture. However, if you want to depict dirty
+         or dusty glass, you might want to supply a local "bubble_diff.png" with
+         a very dark, but not totally black color.
+         
+         Future work:
+         The reason for having a glow texture, (besides the fact that its alpha
+         channel carries the ambient occlusion); and a specular texture (beside
+         the fact of its carrying shininess in alpha), is to, in the future,
+         implement a couple of little hacks...
+         First, if we assume a tiny bit of diffuse reflectivity for glass, we could do
+         a radio bake of inner world light sources onto the glass. Thus, a glass dome
+         over a citadel, like those on the mining base, could get light from indoor
+         lights, with shadows projected by the buildings. This would be put straight
+         into the RGB channels of bubble_glow.png.
+         Second, the RGB channels of bubble_spec.png could contain some kind of
+         rendering of the inside of the cockpit or whatever is housed by the glass
+         dome. A special texture mapping algorithm used only for the first pass
+         (far-side glass) only, would reflect view vectors in some quirky way onto
+         the glow map, to make it appear that the far side of the cockpit or dome
+         is reflecting what's inside.
+         
+         Number of lights:
+         This is a two-pass algorithm, but NOT two passes over the same geometry,
+         but rather two complementary passes: One with cull="front"; and the other
+         with cull="back". Furthermore, the passes are nowhere nearly as complex
+         as those of the UberShader, and therefore we might be able to allow four
+         lights, instead of just two, which is important because reflections on
+         something as glossy as glass would be hard not to miss 'em BAD, if absent.
+         
+         No Z pass necessary:
+         The performance advantage of a Z pre-pass is proportional to overdraw
+         resulting from self-coverage by a mesh. Glass domes and cockpits are
+         very rarely too far from their convex hulls, giving a Z pass less value.
+    -->
+
+    <!-- First pass: Far side of glass cockpits and domes -->
+    
+    <pass type="shader" sequence="15" blend="default" cull="front" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="0.0" optional="true"/>
+    </pass>
+   
+    <!-- Second pass: Near side of glass cockpits and domes -->
+    <pass type="shader" sequence="15" blend="default" cull="back" srgb_aware="true">
+        <vertex_program src="fireglass"/>
+        <fragment_program src="fireglass"/>
+       
+        <texture_unit src="decal:0" default="file:bubble_diff.texture" name="diffuseMap"/>
+        <texture_unit src="environment" name="envMap"/>
+        <texture_unit src="decal:1" default="file:bubble_spec.texture" name="specMap"/>
+        <texture_unit src="decal:3" default="file:bubble_glow.texture" name="glowMap"/>
+        <texture_unit src="decal:4" default="file:bubble_norm.texture" name="normalMap"/>
+        <texture_unit src="decal:2" default="file:bubble_damg.texture" name="damageMap"/>
+        <texture_unit src="file:grey_metal.png" name="detail0Map"/>
+        <texture_unit src="file:grey_metal.png" name="detail1Map"/>
+       
+        <auto_param name="envColor" semantic="EnvColor" optional="true"/>
+        <auto_param name="light_enabled" semantic="ActiveLightsArray" optional="true"/>
+        <auto_param name="light_size" semantic="ApparentLightSizeArray" optional="true"/>
+        <auto_param name="max_light_enabled" semantic="NumLights" optional="true"/>
+        <auto_param name="detail0plane" semantic="DetailPlane0" optional="true"/>
+        <auto_param name="detail1plane" semantic="DetailPlane1" optional="true"/>
+        <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
+        <auto_param name="damage" semantic="Damage4" optional="true"/>
+        <auto_param name="gameTime" semantic="GameTime" optional="true"/>
+        
+        <param name="pass_num" value="1.0" optional="true"/>
+    </pass>
+</technique>
Index: techniques/3_arbfp/default.technique
===================================================================
--- techniques/3_arbfp/default.technique	(revision 13368)
+++ techniques/3_arbfp/default.technique	(revision 13369)
@@ -1,28 +1,33 @@
 <?xml version="1.0"?>
-<technique fallback="../4_ps2.0/default">
+<technique fallback="fixed">
     <!-- Full-blown shader technique, with Z-write prepass to avoid
          shading overhead for occluded fragments.
          
+         This is a slight simplification of the highend version, simplifying
+         environment filtering, light attenuation and some other minor stuff 
+         to get a lighter version of the same effects. The quality decreases 
+         a bit, but it is far more compatible with older hardware.
+         
          This technique implements normal-mapping, specmaps with intensity-derived
          shininess modulation, variable-kernel filtered environmental reflections
          (based on shininess), specularity normalization, fading damage maps with
-         specmap perturbation, and supports up to 12 lights.
+         specmap perturbation, and supports up to 8 lights.
          
-         This is a multi-pass technique, handles 2 lights per pass
+         This is a one-pass technique, so only the first 2 lights are done 
          per-pixel, the remaining ones use per-vertex lighting.
     -->
 
     <!-- Z-write prepasses go at sequence 10 -->
-    <pass type="shader" sequence="10" cull="back" cwrite="false">
+    <pass type="shader" sequence="10" cwrite="false">
         <vertex_program src="zwrite"/>
         <fragment_program src="zwrite"/>
         <texture_unit src="decal:0" default="file:white.bmp" name="diffuseMap"/>
     </pass>
     
     <!-- first and only lighting pass -->
-    <pass type="shader" sequence="15" cull="back" zwrite="false">
-        <vertex_program src="highend"/>
-        <fragment_program src="highend"/>
+    <pass type="shader" sequence="15" zwrite="false">
+        <vertex_program src="default"/>
+        <fragment_program src="default"/>
         
         <texture_unit src="decal:0" default="file:white.bmp" name="diffuseMap"/>
         <texture_unit src="environment" name="envMap"/>
@@ -42,6 +47,5 @@
         <auto_param name="cloaking" semantic="CloakingPhase" optional="true"/>
         <auto_param name="damage" semantic="Damage4" optional="true"/>
         <auto_param name="gameTime" semantic="GameTime" optional="true"/>
-        
     </pass>
 </technique>
Index: programs/highend.fp
===================================================================
--- programs/highend.fp	(revision 13368)
+++ programs/highend.fp	(revision 13369)
@@ -41,7 +41,7 @@
 {
   // shininess = ( 0.5 * pi / SolidAngle ) - 0.810660172
   const float MAGIC_TERM = 0.810660172;
-  return ( HALF_PI / (mat_gloss_sa + light_solid_angle) ) - MAGIC_TERM;
+  return ( HALF_PI / (mat_gloss_sa + light_solid_angle + 0.0005) ) - MAGIC_TERM;
 }
 //public:
 #if (SUPRESS_ENVIRONMENT == 0)
@@ -255,7 +255,7 @@
   
   //Light in a lot of systems is just too dark.
   //Until the universe generator gets fixed, this hack fixes that:
-  vec3 crank_factor = 3.0*normalize(light_acc)/light_acc;
+  float crank_factor = 2.0;
   diffuse_acc *= crank_factor;
   specular_acc *= crank_factor;
 
Index: programs/fireglass.fp
===================================================================
--- programs/fireglass.fp	(revision 13368)
+++ programs/fireglass.fp	(revision 13369)
@@ -19,11 +19,6 @@
 uniform vec4 envColor;
 uniform vec4 pass_num;
 
-/**********************************/
-//  DEBUGGING SWITCHES (EDITABLE) (all should be zero for normal operation)
-/**********************************/
-#undef SUPRESS_GLOWMAP
-#define SUPRESS_GLOWMAP      1
 
 //UTILS
 vec3 matmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
@@ -77,28 +72,22 @@
 {
   // shininess = ( 0.5 * pi / SolidAngle ) - 0.810660172
   const float MAGIC_TERM = 0.810660172;
-  return ( HALF_PI / (mat_gloss_sa + light_solid_angle) ) - MAGIC_TERM;
+  return max(0, ( HALF_PI / (mat_gloss_sa + light_solid_angle + 0.0005) ) - MAGIC_TERM);
 }
 //public:
-#if (SUPRESS_ENVIRONMENT == 0)
 vec3 GLOSS_env_reflection( in vec4 mat_gloss, in vec3 direction ) //const
 {
   //ENV MAP FETCH:
   vec3 result = textureCubeLod( envMap, direction, mat_gloss.y ).rgb;
-#if (DEGAMMA_ENVIRONMENT != 0)
-  return result * result;
-#else
-  return result;
-#endif
+  return degamma_env(result);
 }
-#endif
 float GLOSS_phong_reflection( in float mat_gloss_sa, in float RdotL, in float light_solid_angle ) //const
 {
   float shininess = GLOSS_power( mat_gloss_sa, light_solid_angle );
   //Below, multiplying by 3.621 would be correct; but the brightness is ridiculous in practice...
   //Well, no; correct only if we assume a chalk sphere and a chrome sphere throw the same total
   //ammount of light into your eye...
-  return max( 0.0, pow( RdotL, shininess ) * shininess );
+  return max( 0.0, pow( RdotL, shininess ) * 0.27 * shininess );
 }
 
 
@@ -109,7 +98,6 @@
     return (NdotL + normalized_sa) / (1.0 + normalized_sa);
 }
 
-#if (SUPRESS_LIGHTS == 0)
 //PER-LIGHT STUFF
 void lightingLight(
    in vec4 lightinfo, in vec3 normal, in vec3 vnormal, in vec3 reflection, 
@@ -119,11 +107,7 @@
 {
    vec3  light_pos = normalize(lightinfo.xyz);
    float light_sa = lightinfo.w;
-#if (DEGAMMA_LIGHTS != 0)
-   vec3 light_col = raw_light_col.rgb * raw_light_col.rgb;
-#else
-   vec3 light_col = raw_light_col.rgb;
-#endif
+   vec3  light_col = degamma_light(raw_light_col.rgb);
    float VNdotLx4= saturatef( 4.0 * diffuse_soft_dot(vnormal,light_pos,light_sa) );
    float RdotL = clamp( dot(reflection,light_pos), 0.0, VNdotLx4 );
    light_acc += light_col;
@@ -143,7 +127,6 @@
 }
 lighting(lighting0, 0, 5)
 lighting(lighting1, 1, 6)
-#endif
 
 
 //REFLECTION
@@ -175,17 +158,12 @@
   vec3 iBinormal=gl_TexCoord[3].xyz;
   vec3 position = gl_TexCoord[7].xyz;
   vec3 face_normal = normalize( cross( dFdx(position), dFdy(position) ) );
-#if (SUPRESS_HI_Q_VNORM == 0)
+
   //supplement the vnormal with face normal before normalizing
   float supplemental_fraction=(1.0-length(iNormal));
   vec3 vnormal = normalize( iNormal + supplemental_fraction*face_normal );
-#else
-  vec3 vnormal = normalize( iNormal );
-#endif
+
   vec3 normal=imatmul(iTangent,iBinormal,iNormal,normalmap_decode(texture2D(normalMap,nm_tex_coord)));
-#if (SUPRESS_NORMALMAP != 0)
-  normal = vnormal;
-#endif
 
   // Other vectors
   vec3 eye = gl_TexCoord[4].xyz;
@@ -195,80 +173,62 @@
   float PSalpha = outline_smoothing_alpha( eye, iNormal, is_perimeter );
   
   // Sample textures
-  vec4 damagecolor = texture2D(damageMap , tex_coord);
-  vec4 diffcolor   = texture2D(diffuseMap, tex_coord);
-  vec4 speccolor   = texture2D(specMap   , tex_coord);
-  vec4 glowcolor   = texture2D(glowMap   , tex_coord);
+  vec4 damagecolor = degamma_tex (texture2D(damageMap , tex_coord));
+  vec4 diffcolor   = degamma_tex (texture2D(diffuseMap, tex_coord));
+  vec4 speccolor   = degamma_spec(texture2D(specMap   , tex_coord));
+  vec4 glowcolor   = degamma_glow(texture2D(glowMap   , tex_coord));
   
   //better apply damage lerps before de-gamma-ing
   //COMMENTED OUT because I don't think anyone would bother to create a damage texture
   //for transparent parts, and it would look like crap, anyways.
-//  diffcolor.rgb  = lerp(damage.x, diffcolor, damagecolor).rgb;
-//  speccolor  *= (1.0-damage.x);
-//  glowcolor.rgb  *= (1.0-damage.x);
+  //  diffcolor.rgb  = lerp(damage.x, diffcolor, damagecolor).rgb;
+  //  speccolor  *= (1.0-damage.x);
+  //  glowcolor.rgb  *= (1.0-damage.x);
   
   //materials
   vec4 mtl_gloss;
-//  vec3 diff_col, glow_col;
   float alpha, nD, UAO;
-#if (SHOW_SPECIAL == SHOW_NO_SPECIAL)
+
   const float GLASS_REFRACTIVE_CONSTANT = 1.48567;
   nD = GLASS_REFRACTIVE_CONSTANT;
   //grab alpha channels  
   alpha = diffcolor.a;
   UAO = glowcolor.a;
   GLOSS_init( mtl_gloss, speccolor.a );
-//#if (DEGAMMA_GLOW_MAP != 0)
-//  glow_col = (glowcolor*glowcolor).rgb;
-//#else
-// glow_col = glowcolor.rgb;
-//#endif
 
   vec3 reflection;
-#if (SHOW_FLAT_SHADED != 0)
-  normal = face_normal;
-#endif
+
   //GAR( eye, normal, mtl_gloss.z, reflection );
   reflection = -reflect( eye, normal );
   
   //DIELECTRIC REFLECTION
-#if (SUPRESS_DIELECTRIC == 0)
-  float fresnel_refl = full_fresnel( dot( reflection, normal), nD );
-#else
-  float fresnel_refl = 0.0;
-#endif
+  float fresnel_refl = saturatef(full_fresnel( dot( reflection, normal), nD ));
   float fresnel_refr = 1.0 - fresnel_refl;
 
   // Init lighting accumulators
   vec3 light_acc    = vec3(0.0);
   vec3 specular_acc = vec3(0.0);
-#if (SUPRESS_LIGHTS == 0)
+
   // Do lighting for every active light
   float mtl_gloss_sa = mtl_gloss.w;
   if (light_enabled[0] != 0)
      lighting0(normal, vnormal, reflection, mtl_gloss_sa, nD, light_acc, specular_acc);
   if (light_enabled[1] != 0)
      lighting1(normal, vnormal, reflection, mtl_gloss_sa, nD, light_acc, specular_acc);
-#endif
-   
+
   //Light in a lot of systems is just too dark.
   //Until the universe generator gets fixed, this hack fixes that:
-  vec3 crank_factor = 3.0*normalize(light_acc)/light_acc;
+  float crank_factor = 2.0;
   specular_acc *= crank_factor;
-
+  
   //Gather all incoming light:
   //NOTE: "Incoming" is a misnomer, really; what it means is that of all incoming light, these are the
   //portions expected to reflect specularly and/or diffusely, as per angle and shininess; --but not yet
   //modulated as per fresnel reflectivity or material colors. So I put them in quotes in the comments.
   //"Incoming specular":
-#if (SUPRESS_ENVIRONMENT == 0)
   vec3 incoming_specular_light = GLOSS_env_reflection(mtl_gloss,reflection);
-#else
-  vec3 incoming_specular_light = vec3(0.0);
-#endif
-#if (SUPRESS_LIGHTS == 0)
+
   incoming_specular_light += specular_acc;
-#endif
   
   //Gather the reflectivities:
   vec3 dielectric_specularity = vec3(1.0);
@@ -281,157 +241,13 @@
   
   //FINAL PIXEL WRITE:
   //Restore gamma, add alpha, and Commit:
-  float final_alpha = sqrt(fresnel_refl);
-#if (FORCE_FULL_REFLECT != 0)
-  final_alpha = 1.0;
-#endif
+  float final_alpha = fresnel_refl;
+
   //trim the corners around the outline
   final_alpha *= PSalpha;
   //final_reflected = vec3(0.0,1.5,0.0);
-  gl_FragColor = vec4( sqrt(final_reflected)*final_alpha, final_alpha );// * cloaking.rrrg;
+  gl_FragColor = vec4( regamma(final_reflected*final_alpha), final_alpha );// * cloaking.rrrg;
   //Finitto!
-#endif
-#if (SHOW_SPECIAL == SHOW_MAT)
-  //  * material AI detections (red = matte; green = metal; blue = dielectric )
-  gl_FragColor = vec4( mattype.rgb, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_NORMAL)
-  //  * RGB = normal.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( vnormal.xyz * 0.5 + vec3(0.5), 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TANGENTX)
-  //  * RGB = tangent.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( normalize(iTangent.x) * 0.5 + 0.5, 0.5, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TANGENTY)
-  //  * RGB = tangent.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( 0.5, normalize(iTangent.y) * 0.5 + 0.5, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TANGENTZ)
-  //  * RGB = tangent.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( 0.5, 0.5, normalize(iTangent.z) * 0.5 + 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BINORMX)
-  //  * RGB = binormal.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( normalize(iBinormal.x) * 0.5 + 0.5, 0.5, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BINORMY)
-  //  * RGB = binormal.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( 0.5, normalize(iBinormal.y) * 0.5 + 0.5, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BINORMZ)
-  //  * RGB = binormal.xyz * 0.5 + 0.5
-  gl_FragColor = vec4( 0.5, 0.5, normalize(iBinormal.z) * 0.5 + 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_NOR_DOT_VIEW)
-  //  * R = dot(normal, view)
-  vec3 eyevec = normalize( eye );
-  vec3 temp;
-  temp.r = dot( vnormal, eyevec ) * 0.5 + 0.5;
-  temp.g = 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TAN_DOT_VIEW)
-  //  * G = dot(tangent, view)
-  vec3 eyevec = normalize( eye );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = dot( normalize(iTangent.xyz), eyevec ) * 0.5 + 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BIN_DOT_VIEW)
-  //  * B = dot(binormal, view)
-  vec3 eyevec = normalize( eye );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = 0.5;
-  temp.b = dot( normalize(iBinormal.xyz), eyevec ) * 0.5 + 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_NOR_DOT_LIGHT0)
-  //  * R = dot(normal, light)
-  vec3 lightvec = normalize( gl_TexCoord[5].xyz );
-  vec3 temp;
-  temp.r = dot( vnormal, lightvec ) * 0.5 + 0.5;
-  temp.g = 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TAN_DOT_LIGHT0)
-  //  * G = dot(tangent, light)
-  vec3 lightvec = normalize( gl_TexCoord[5].xyz );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = dot( normalize(iTangent.xyz), lightvec ) * 0.5 + 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BIN_DOT_LIGHT0)
-  //  * B = dot(binormal, light)
-  vec3 lightvec = normalize( gl_TexCoord[5].xyz );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = 0.5;
-  temp.b = dot( normalize(iBinormal.xyz), lightvec ) * 0.5 + 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_NOR_DOT_LIGHT1)
-  //  * R = dot(normal, light)
-  vec3 lightvec = normalize( gl_TexCoord[6].xyz );
-  vec3 temp;
-  temp.r = dot( vnormal, lightvec ) * 0.5 + 0.5;
-  temp.g = 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_TAN_DOT_LIGHT1)
-  //  * G = dot(tangent, light)
-  vec3 lightvec = normalize( gl_TexCoord[6].xyz );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = dot( normalize(iTangent.xyz), lightvec ) * 0.5 + 0.5;
-  temp.b = 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_BIN_DOT_LIGHT1)
-  //  * B = dot(binormal, light)
-  vec3 lightvec = normalize( gl_TexCoord[6].xyz );
-  vec3 temp;
-  temp.r = 0.5;
-  temp.g = 0.5;
-  temp.b = dot( normalize(iBinormal.xyz), lightvec ) * 0.5 + 0.5;
-  gl_FragColor = vec4( temp, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_NOR_DOT_VNORM)
-  float shade = dot(normal,vnormal) * 0.5 + 0.5;
-  gl_FragColor = vec4( shade, shade, shade, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_IS_PERIPHERY)
-//float is_periphery( in vec3 view, in vec3 rawvnorm, in float is_perimeter )
-  float temp = pow( is_periphery( eye, iNormal, is_perimeter ), CORNER_TRIMMING_POW );
-  gl_FragColor = vec4( temp, temp, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_IS_NEAR_VERT)
-  float temp = pow( is_near_vert( iNormal ), CORNER_TRIMMING_POW );
-  gl_FragColor = vec4( temp, temp, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_IS_UGLY_CORNER)
-  float temp = is_near_vert_on_periphery( eye, iNormal, is_perimeter );
-  gl_FragColor = vec4( temp, temp, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_MA_NO_CORNERS)
-  float temp = outline_smoothing_alpha( eye, iNormal, is_perimeter );
-  gl_FragColor = vec4( temp, temp, 0.5, 1.0 );
-#endif
-#if (SHOW_SPECIAL == SHOW_VNOR_DOT_FNOR)
-  float temp = dot(face_normal,normalize(iNormal.xyz) * 0.5 + 0.5;
-  //must exaggerate it greatly to be able to see...
-  temp = 1.0-temp;
-  temp = 1.0-177.7*temp;
-  gl_FragColor = vec4( temp, temp, 0.5, 1.0 );
-#endif
 }
 
 
Index: programs/fireglass_simple.fp
===================================================================
--- programs/fireglass_simple.fp	(revision 0)
+++ programs/fireglass_simple.fp	(revision 13369)
@@ -0,0 +1,167 @@
+#include "config.h"
+#include "stdlib.h"
+#include "normalmap.h"
+
+uniform int light_enabled[gl_MaxLights];
+uniform int max_light_enabled;
+uniform sampler2D diffuseMap;
+uniform samplerCube envMap;
+uniform sampler2D specMap;
+uniform sampler2D glowMap;
+uniform sampler2D normalMap;
+uniform sampler2D detail0Map;
+uniform sampler2D detail1Map;
+uniform vec4 cloaking;
+uniform vec4 envColor;
+uniform vec4 pass_num;
+
+
+//UTILS
+vec3 matmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
+  return vec3(dot(lightVec,tangent),dot(lightVec,binormal),dot(lightVec,normal));
+}
+vec3 imatmul(vec3 tangent, vec3 binormal, vec3 normal,vec3 lightVec) {
+  return normalize(lightVec.xxx*tangent+lightVec.yyy*binormal+lightVec.zzz*normal);
+}
+
+
+
+//public:
+vec3 GLOSS_env_reflection( in float shininess, in vec3 direction ) //const
+{
+  //ENV MAP FETCH:
+  return degamma_env(textureCube( envMap, direction, 8.0 - shininess/8.0 ).rgb);
+}
+
+float GLOSS_phong_reflection( in float shininess, in float RdotL, in float light_solid_angle ) //const
+{
+  //Below, multiplying by 3.621 would be correct; but the brightness is ridiculous in practice...
+  //Well, no; correct only if we assume a chalk sphere and a chrome sphere throw the same total
+  //ammount of light into your eye...
+  return max( 0.0, pow( RdotL, shininess ) * sqrt(shininess) );
+}
+
+
+float diffuse_soft_dot(in vec3 normal, in vec3 light, in float light_sa)
+{
+    float NdotL = dot(normal, light);
+    float normalized_sa = light_sa / TWO_PI;
+    return (NdotL + normalized_sa) / (1.0 + normalized_sa);
+}
+
+//PER-LIGHT STUFF
+void lightingLight(
+   in vec4 lightinfo, in vec3 normal, in vec3 vnormal, in vec3 reflection, 
+   in vec4 raw_light_col,
+   in float shininess, in float nD,
+   inout vec3 light_acc, inout vec3 specular_acc)
+{
+   vec3  light_pos = normalize(lightinfo.xyz);
+   float light_sa = lightinfo.w;
+
+   vec3 light_col = degamma_light(raw_light_col.rgb);
+
+   float VNdotLx4= saturatef( 4.0 * diffuse_soft_dot(vnormal,light_pos,light_sa) );
+   float RdotL = clamp( dot(reflection,light_pos), 0.0, VNdotLx4 );
+   light_acc += light_col;
+   specular_acc += ( GLOSS_phong_reflection(shininess,RdotL,light_sa) * light_col );
+}
+#define lighting(name, lightno_gl, lightno_tex) \
+void name( \
+   in vec3 normal, in vec3 vnormal, in  vec3 reflection, \
+   in float shininess, in float nD, \
+   inout vec3 light_acc, inout vec3 specular_acc) \
+{ \
+   lightingLight( \
+      gl_TexCoord[lightno_tex], normal, vnormal, reflection, \
+      gl_LightSource[lightno_gl].diffuse, \
+      shininess, nD, \
+      light_acc, specular_acc); \
+}
+lighting(lighting0, 0, 5)
+
+
+
+//FINALLY... MAIN()
+void main() 
+{
+  // Retreive texture coordinates
+  vec2 tex_coord = gl_TexCoord[0].xy;
+  vec2 nm_tex_coord = NM_FREQ_SCALING * tex_coord;
+  
+  // Retrieve vectors
+  vec3 iNormal=gl_TexCoord[1].xyz;
+  vec3 iTangent=gl_TexCoord[2].xyz;
+  vec3 iBinormal=gl_TexCoord[3].xyz;
+  vec3 position = gl_TexCoord[7].xyz;
+  vec3 face_normal = normalize( cross( dFdx(position), dFdy(position) ) );
+
+  vec3 vnormal = normalize( iNormal );
+
+  vec3 normal=imatmul(iTangent,iBinormal,iNormal,normalmap_decode(texture2D(normalMap,nm_tex_coord)));
+
+  // Other vectors
+  vec3 eye = gl_TexCoord[4].xyz;
+  float is_perimeter = gl_TexCoord[4].w;
+  
+  //compute a periphery smoothing alpha
+  float PSalpha = sqr(is_perimeter);
+  
+  // Sample textures
+  vec4 diffcolor = degamma_tex (texture2D(diffuseMap, tex_coord));
+  vec4 speccolor = degamma_spec(texture2D(specMap   , tex_coord));
+  vec4 glowcolor = degamma_glow(texture2D(glowMap   , tex_coord));
+  
+//  vec3 diff_col, glow_col;
+  float alpha, nD, UAO;
+
+  const float GLASS_REFRACTIVE_CONSTANT = 1.48567;
+  nD = GLASS_REFRACTIVE_CONSTANT;
+  //grab alpha channels  
+  alpha = diffcolor.a;
+  UAO = glowcolor.a;
+
+  vec3 reflection = -reflect( eye, normal );
+  
+  //DIELECTRIC REFLECTION
+  float fresnel_refl = saturatef(fresnel( dot(eye, normal), nD ));
+  float fresnel_refr = 1.0 - fresnel_refl;
+
+  // Init lighting accumulators
+  vec3 light_acc    = vec3(0.0);
+  vec3 specular_acc = vec3(0.0);
+
+  // Do lighting for every active light
+  float shininess = sqr(speccolor.a) * 128.0;
+  if (light_enabled[0] != 0)
+     lighting0(normal, vnormal, reflection, shininess, nD, light_acc, specular_acc);
+   
+  //Gather all incoming light:
+  //NOTE: "Incoming" is a misnomer, really; what it means is that of all incoming light, these are the
+  //portions expected to reflect specularly and/or diffusely, as per angle and shininess; --but not yet
+  //modulated as per fresnel reflectivity or material colors. So I put them in quotes in the comments.
+  //"Incoming specular":
+  vec3 incoming_specular_light = GLOSS_env_reflection(shininess,reflection);
+  incoming_specular_light += specular_acc;
+  
+  //Gather the reflectivities:
+  vec3 dielectric_specularity = vec3(1.0);
+  vec3 total_specularity = dielectric_specularity; // + metallic_specularity;
+ 
+  //Multiply and Add:
+  //we multiply by pass_num so that in pass 0 there's no env mapping or specular lights; but in
+  // pass 1 there are; so that the far side appears to reflect only the (presumably) darker interior
+  vec3 final_reflected = UAO * UAO * pass_num.x * incoming_specular_light * total_specularity;
+  
+  //FINAL PIXEL WRITE:
+  //Restore gamma, add alpha, and Commit:
+  float final_alpha = fresnel_refl;
+
+  //trim the corners around the outline
+  final_alpha *= PSalpha;
+  //final_reflected = vec3(0.0,1.5,0.0);
+  gl_FragColor = vec4( regamma(final_reflected*final_alpha), final_alpha );// * cloaking.rrrg;
+  //Finitto!
+}
+
+
Index: programs/fireglass_simple.vp
===================================================================
--- programs/fireglass_simple.vp	(revision 0)
+++ programs/fireglass_simple.vp	(revision 13369)
@@ -0,0 +1,232 @@
+uniform int light_enabled[gl_MaxLights];
+uniform vec4 light_size[gl_MaxLights];
+uniform int max_light_enabled;
+uniform vec4 detail0Plane;
+uniform vec4 detail1Plane;
+
+/* varyings:
+ *   gl_TexCoord[...]
+ *    0 - tex coord
+ *    1 - ws normal
+ *    2 - ws tangent
+ *    3 - ws binormal
+ *    4 - vertex-to-eye direction, plus "is_perimeter" for corner-cutting
+ *    5 - vertex-to-light0@xyz, light_size@z
+ *    6 - vertex-to-light1@xyz, light_size@z
+ *    7 - un-normalized vertex position
+ **/
+
+//float selfshadowStep(float VNdotL) { return step(0.0,VNdotL); } // fast but hard selfshadow function
+float selfshadowStep(float VNdotL) { return smoothstep(0.0,0.25,VNdotL); } // costly but soft and nice selfshadow function
+
+vec4 lightPosAndSize0(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[0].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  rv.w      = light_size[0].z;
+  return rv;
+}
+vec4 lightPosAndAttenuation1(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[1].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[1].constantAttenuation,
+                              gl_LightSource[1].linearAttenuation,
+                              gl_LightSource[1].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation2(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[2].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[2].constantAttenuation,
+                              gl_LightSource[2].linearAttenuation,
+                              gl_LightSource[2].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation3(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[3].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[3].constantAttenuation,
+                              gl_LightSource[3].linearAttenuation,
+                              gl_LightSource[3].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation4(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[4].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[4].constantAttenuation,
+                              gl_LightSource[4].linearAttenuation,
+                              gl_LightSource[4].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation5(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[5].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[5].constantAttenuation,
+                              gl_LightSource[5].linearAttenuation,
+                              gl_LightSource[5].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation6(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[6].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[6].constantAttenuation,
+                              gl_LightSource[6].linearAttenuation,
+                              gl_LightSource[6].quadraticAttenuation) );
+  return rv;
+}
+vec4 lightPosAndAttenuation7(in vec4 vertex)
+{
+  vec4 lpos = gl_LightSource[7].position;
+  vec4 rv;
+  rv.xyz    = lpos.xyz - vertex.xyz*lpos.w;
+  float t   = length(rv.xyz);
+  rv.xyz   *= (1.0/t);
+  rv.w      = 1.0 / dot( vec3(1,t,t*t),
+                         vec3(gl_LightSource[7].constantAttenuation,
+                              gl_LightSource[7].linearAttenuation,
+                              gl_LightSource[7].quadraticAttenuation) );
+  return rv;
+}
+
+void lighting1(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation1(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[1].ambient
+                 + max(0.0, NdotL) * gl_LightSource[1].diffuse * gl_FrontMaterial.diffuse );
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[1].specular * gl_FrontMaterial.specular );
+}
+void lighting2(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation2(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[2].ambient
+                 + max(0.0, NdotL) * gl_LightSource[2].diffuse * gl_FrontMaterial.diffuse );
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[2].specular * gl_FrontMaterial.specular );
+}
+void lighting3(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation3(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[3].ambient
+                 + max(0.0, NdotL) * gl_LightSource[3].diffuse * gl_FrontMaterial.diffuse );
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[3].specular * gl_FrontMaterial.specular );
+}
+void lighting4(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation4(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[4].ambient
+                 + max(0.0, NdotL) * gl_LightSource[4].diffuse * gl_FrontMaterial.diffuse );
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[4].specular * gl_FrontMaterial.specular );
+}
+void lighting5(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation5(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[5].ambient
+                 + max(0.0, NdotL) * gl_LightSource[5].diffuse * gl_FrontMaterial.diffuse );
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[5].specular * gl_FrontMaterial.specular );
+}
+void lighting6(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation6(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[6].ambient
+                 + max(0.0, NdotL) * gl_LightSource[6].diffuse * gl_FrontMaterial.diffuse ); 
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[6].specular * gl_FrontMaterial.specular );
+}
+void lighting7(in vec4 vertex, in vec3 refl, in vec3 normal, inout vec4 pc, inout vec4 sc)
+{
+  vec4  lpatt  = lightPosAndAttenuation7(vertex);
+  float NdotL = dot( lpatt.xyz, normal );
+  float RdotL = dot( lpatt.xyz, refl );
+  pc += lpatt.w*(  gl_FrontMaterial.ambient * gl_LightSource[7].ambient
+                 + max(0.0, NdotL) * gl_LightSource[7].diffuse * gl_FrontMaterial.diffuse ); 
+  sc += lpatt.w*(  pow( max(0.0, RdotL) , max(1.0,gl_FrontMaterial.shininess) ) * selfshadowStep(NdotL)
+                 * gl_LightSource[7].specular * gl_FrontMaterial.specular );
+}
+
+float is_perimeter( in vec3 view, in vec3 norm )
+{
+  float temp1 = dot( view, norm );
+  return 1.0 - temp1*temp1;
+}
+
+void main() 
+{
+  // Compute position, eye-to-object direction and normalized world-space normal
+  vec4 position = gl_ModelViewMatrix * gl_Vertex;
+  vec3 eyetopos = normalize(position.xyz);
+  vec3 normal   = normalize(gl_NormalMatrix * gl_Normal);
+  vec3 tangent  = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz);
+  vec3 binormal = cross(tangent, normal) * sign(gl_MultiTexCoord2.w);
+  // Load varyings
+  gl_TexCoord[0] = gl_MultiTexCoord0;
+  gl_TexCoord[1].xyz = normal;
+  gl_TexCoord[2].xyz = tangent;
+  gl_TexCoord[3].xyz = binormal;
+  gl_TexCoord[4].xyz = -eyetopos;
+  gl_TexCoord[5] = lightPosAndSize0(position);
+  gl_TexCoord[1].w =
+  gl_TexCoord[2].w =
+  gl_TexCoord[3].w = 0.0;
+  gl_TexCoord[4].w = is_perimeter( eyetopos, normal );
+  gl_TexCoord[7] = position;
+  // set primary color to the emissive material properties
+  vec4 pc = gl_FrontMaterial.emission;
+  vec4 sc = vec4(0.0);
+  vec3 refl     = reflect( eyetopos, normal );
+  if (max_light_enabled >= 2) {
+    if (light_enabled[1] != 0) lighting1(position, refl, normal, pc, sc);
+    if (light_enabled[2] != 0) lighting2(position, refl, normal, pc, sc);
+    if (light_enabled[3] != 0) lighting3(position, refl, normal, pc, sc);
+  }
+  // Need this instead of ftransform() for invariance
+  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
+  gl_FrontColor = gl_BackColor = pc;
+  gl_FrontSecondaryColor = gl_BackSecondaryColor = sc;
+}
openSUSE Build Service is sponsored by