Difference between revisions of "ShaderPool"

From SimsWiki
Jump to: navigation, search
 
Line 1: Line 1:
 
<PRE>
 
<PRE>
  
 
+
EP1-UNI
EP0-TS2
+
 
0xCD7FE87A
 
0xCD7FE87A
 
0x1C0532FA
 
0x1C0532FA
Line 8: Line 7:
 
0xFF76EA99
 
0xFF76EA99
 
# poolwater
 
# poolwater
 
  
 
##############################################################
 
##############################################################
Line 162: Line 160:
 
const static float4 refractionWeights={1,1,2,0};
 
const static float4 refractionWeights={1,1,2,0};
 
 
### dNL
 
 
 
struct InputVertex
 
struct InputVertex
 
{
 
{
Line 526: Line 522:
 
         mul oT0.xy, r8.xy, c2.xy
 
         mul oT0.xy, r8.xy, c2.xy
 
          
 
          
### dNL
 
 
 
       endShaderSource
 
       endShaderSource
 
    
 
    
Line 751: Line 745:
 
   setDefinition CausticsGeneratorMaterial
 
   setDefinition CausticsGeneratorMaterial
 
end
 
end
 +
  
  

Revision as of 07:13, 5 March 2007


EP1-UNI
0xCD7FE87A
0x1C0532FA
0x6852819C
0xFF76EA99
# poolwater

##############################################################
# Pool Water
#

seti poolWaterLayer 5



##############################################################
# Simple water material
#
# This material modulates the vertices by two sin waves --
# one in X and one in Y. It then produces reflection and
# refraction direction texture coordinates suitable for a
# cubic environment map.


#beginshader PoolWaterMaterialTwoWave
#description Pool water with X/Y waves

#BeginStdAttrBlock


setf wmTransparency  0.5
#attrdescription Water transparency

setf wmXSpeed        3     # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.
setf wmXRepeat       1     # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.
setf wmXWaveHeight   0.1   # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.

setf wmYSpeed        5     # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.
setf wmYRepeat       1.8   # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.
setf wmYWaveHeight   0.2   # min:0 max:100
#attrdescription Lookup texture for diffuse intensity.

set wmReflectionTexture reflectionoutdoorwater-envcube
#attrdescription Environment cube map texture for reflection

setb wmRefractionEnabled false
#attrdescription Whether refraction is enabled

set wmRefractionTexture reflectionoutdoorwater-envcube
#attrdescription Environment cube map texture for refraction


#EndStdAttrBlock

define PoolWaterSurfaceMaterial()
   material
      shader -layer $poolWaterLayer
         validateRenderShaderContext -vertexFormat position 0 required
 
         create DetermineHardwareSupport()
    
         if ($useSWVertexShaderPath or $useFixedFunctionPath)
            # The vertex shader to ripple the water surface is deemed too expensive for SWVS.
            # Note that because on some low-end cards shaders are turned off, DetermineHardwareSupport()
            # will set $useFixedFunctionPath to true and $useSWVertexShaderPath to false; however, 
            # since the device is in swvp mode, the RegularWavesHLSL shader would validate anyway, which
            # we don't want. Therefore here we do the simplified water surface if using either SWVS or FFP.
            create SimplifiedWaterSurface()
         else
            create RegularWavesHLSL()
         endif
         
      end #end shader
      
      # basic fallback.
      shader -layer $poolWaterLayer
         create SimplifiedWaterSurface()          
      end #end shader
      
   end  #end material
enddef

define SimplifiedWaterSurface()
   pass -fixedFunction
      alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
      depthTest true -enableDepthWrite false
      colorScalar (0.2,0.3,1.0) 0.4
            
      stage
         textureBlend select(colorScalar) select(colorScalar)
      end
   end
enddef


define RegularWavesHLSL()
	
   #DRIVERBUG
   # The -clipAlways flag is needed to work around what appears to be a driver bug.
   # On NVIDIA GF2 class HW, the presence of the cube map texture in the pass below
   # leads to a large performance drop whenever the pass is rendered with clipping disabled.
   # Rendering this pass with clipping enabled avoids the performance drop. In addition,
   # substituting a 2D texture for the cube map texture, or rendering this pass in HW
   # using fixed function vertex processing also avoids the performance drop (but would obviously
   # not have the desired visual result).
   # The cause of this is unknown. This was observed on a GF4GO, driver version 42.58.
	pass -clipAlways -modifiedEachFrameHint
		#fillmode wireframe
		alphaBlend srcFactor(one) add dstFactor(one)
      seti textureLights (numLightsOfType(environmentCube))
      
      
   
		shaderProgram -target vertexProgram -method compile -version 1_1

			bindConstants 0 -bindingID geomToClip -constantCount 4
			bindConstants 4 -bindingID geomToCamera -constantCount 3

			bindConstants 7 -bindingID frameInfo 

			bindConstants 11 -bindingID immediateData -data ($wmXRepeat, 0, $wmXWaveHeight, $wmXSpeed)
			bindConstants 12 -bindingID immediateData -data (0, $wmYRepeat, $wmYWaveHeight, $wmYSpeed)

			# pre-evaluate these
			setf xscale (-$wmXRepeat * $wmXWaveHeight)
			setf yscale (-$wmYRepeat * $wmYWaveHeight)
			bindConstants 13 -bindingID immediateData -data ($xscale,$yscale, 1,0)
			bindConstants 14 -bindingID allStandardLightData -constantCount 4 -constantType float
			bindConstants 18 -bindingID cameraToGlobal -constantCount 3

         if ($textureLights) 
            bindConstants 25 -bindingID allTextureLights -constantCount 1 -constantType float
         else
            bindConstants 25 -bindingID immediateData -data (1,1,1,1) -constantType float
         endif
         


			shaderSource

				float4 frameInfo : register(c7);
				float4 waveDataX : register(c11);
				float4 waveDataY : register(c12);
				float4 waveDataHelper : register(c13);
				float4x4 clipSpaceMatrix : register(c0);
				float4x3 cameraSpaceMatrix : register(c4);
				float4x3 cameraToGlobalMatrix : register(c18);
				
            float4 nightColor: register(c25);
            
				float4 lightDirection : register(c14);
				float4 lightColor : register(c15);
				const static float4 refractionWeights={1,1,2,0};
				
				struct InputVertex
				{
					float3 position: POSITION0;
					float3 normal : NORMAL0;
				};
				
				struct OutputVertex
				{
					float4 clipPosition : POSITION;
					float4 diffuseColor: COLOR0;
					float4 specularColor: COLOR1;
					float3 reflection : TEXCOORD0;
					
				};
            
		
		
				OutputVertex VertexMain( InputVertex inputVertex)
				{
					// Do	Y-direction	waves
					// r0	= (x, y, z,	t)
					
					OutputVertex outputVertex;
					
					float4 posAndTime;
					posAndTime.xyz = inputVertex.position;
					posAndTime.w = frameInfo.w;
					
					float temp = dot(posAndTime, waveDataX);
								
					// z = h * sin(...)

					float z;
					// scale temp to fit -pi +pi range
					//temp = temp *  (1 / (2 * 3.14159)) + 0.5;
					
					float3 waveNormal;
					
					z = sin(temp) * waveDataX.z + inputVertex.position.z;
					
					waveNormal.x = cos(temp) * waveDataHelper.x + inputVertex.normal.x;
					
					temp = dot(posAndTime, waveDataY);
					//temp = temp *  (1 / (2 * 3.14159)) + 0.5;
					
					z +=  sin(temp) * waveDataY.z;
					
					waveNormal.y = cos(temp) * waveDataHelper.y + inputVertex.normal.y;
					
					waveNormal.z = inputVertex.normal.z;
					
					waveNormal = normalize(waveNormal);
					
					posAndTime.w = 1.0;
					posAndTime.z = z;
					
					outputVertex.clipPosition = mul( posAndTime, clipSpaceMatrix);
					
					float3 cameraSpaceNormal = normalize(mul(waveNormal, cameraSpaceMatrix));

					float3 cameraSpacePosition = mul( posAndTime, cameraSpaceMatrix);
					
					float3 viewVector = normalize(-cameraSpacePosition);
					
					float3 R = reflect(viewVector, cameraSpaceNormal);
					
					outputVertex.reflection = mul( -R, cameraToGlobalMatrix);
					
							
					float fresnel = dot(viewVector , cameraSpaceNormal);
							
					float rdotl = saturate(dot(R, lightDirection));
					
					float I = pow(rdotl+0.1, 15); // fudge factor to punch up the highlights.
					
                           
					outputVertex.diffuseColor = (1.0 - fresnel) * nightColor * 0.5;
					outputVertex.specularColor = I;
					return(outputVertex);
					
				}


			endShaderSource  
		end # shaderProgram
		
		stage
			texture $wmReflectionTexture
			textureAddressing clamp clamp clamp
			textureBlend multiply(texture diffuse) select(diffuse)
		end
      
      
		addSpecular true
					
	end # end pass

enddef


define HighEndWaterSurface()


   pass
		#fillmode wireframe
		alphaBlend srcFactor(one) add dstFactor(one)
		
      shaderProgram -target vertexProgram -method compile -version 1_1
      
         bindConstants 0 -bindingID geomToClip -constantCount 4
         bindConstants 4 -bindingID geomToCamera -constantCount 3
      
         bindConstants 7 -bindingID frameInfo 
      
         bindConstants 11 -bindingID immediateData -data ($wmXRepeat, 0, $wmXWaveHeight, $wmXSpeed)
         bindConstants 12 -bindingID immediateData -data (0, $wmYRepeat, $wmYWaveHeight, $wmYSpeed)
      
         # pre-evaluate these
         setf xscale (-$wmXRepeat * $wmXWaveHeight)
         setf yscale (-$wmYRepeat * $wmYWaveHeight)
         bindConstants 13 -bindingID immediateData -data ($xscale,$yscale, 1,0)
         bindConstants 14 -bindingID allStandardLightData -constantCount 4 -constantType float
         bindConstants 18 -bindingID cameraToGlobal -constantCount 3
   
         shaderSource
      
            float4 frameInfo : register(c7);
            float4 waveDataX : register(c11);
            float4 waveDataY : register(c12);
            float4 waveDataHelper : register(c13);
            float4x4 clipSpaceMatrix : register(c0);
            float4x3 cameraSpaceMatrix : register(c4);
            float4x3 cameraToGlobalMatrix : register(c18);
            
            float4 lightDirection : register(c14);
            float4 lightColor : register(c15);
            const static float4 refractionWeights={1,1,2,0};
            
            struct InputVertex
            {
               float4 position: POSITION0;
               float3 normal : NORMAL0;
               float2 texc : TEXCOORD0;
            };
            
            struct OutputVertex
            {
               float4 clipPosition : POSITION;
               float3 normal : TEXCOORD0;
               float3 viewVector : TEXCOORD1;
         
            };
            
            static float2 waveCenter1 = {0.0, 0.0};
            static float2 waveCenter2 = {-0.6, 0.2};
            
            static float2 timeScale = {2,1};
            static float2 waveHeight = {0.04, 0.02};
            static float2 distScale = {12, 8};
            
            
            
            float4 ComputeWavePositionTwoWay(float2 pos1, float2 pos2)
            {
            
			   float2 vec;
               float4 dist;
               
               vec = waveCenter1 - pos1;
               dist.x = dot(vec, vec);
               
               vec = waveCenter2 - pos1;
               dist.y = dot(vec,vec);
               
			   vec = waveCenter2 - pos2;
               dist.z = dot(vec, vec);
               
               vec = waveCenter2 - pos2;
               dist.w = dot(vec,vec);
		   
			   dist *= distScale.xyxy;
			   
			   float4 sinResult = sin(dist + frameInfo.w * timeScale.xyxy);

			   //sinResult = 1.0- abs(sinResult);
				
			   return(sinResult);
				
            }
            
            float2 ComputeWavePosition(float2 pos1)
            {
            
			   float2 vec;
               float2 dist;
			   
			   vec = waveCenter1 - pos1;
               dist.x = dot(vec, vec);
               
               vec = waveCenter2 - pos1;
               dist.y = dot(vec,vec);
               		   
			   dist *= distScale.xy;
			   
			   float2 sinResult = sin(dist + frameInfo.w * timeScale);

			   //sinResult = 1.0- abs(sinResult);
				
			   return(sinResult);
				
            }
            
            OutputVertex VertexMain( InputVertex inputVertex)
            {
               // Do	Y-direction	waves
               // r0	= (x, y, z,	t)
               
               OutputVertex outputVertex;
			
				float4 pos = inputVertex.position;
				
				float2 sample1, sample2, sample3;
				
				sample1 = inputVertex.position;
				sample2 = inputVertex.position;
				sample3 = inputVertex.position;
				sample2.x += 0.1;
				sample3.y += 0.1;
				
				float4 heights1=ComputeWavePositionTwoWay(sample1, sample2);
				float2 heights2=ComputeWavePosition(sample3);
				
				
			float3 pos1, pos2;
				pos1 = pos;
				pos2 = pos;
				
			   pos.z += (heights1.x* waveHeight.x);// + heights1.y *  waveHeight.y);
			   pos1.z += (heights1.z* waveHeight.x);// + heights1.w *  waveHeight.y);
			   pos2.z += (heights2.x* waveHeight.x);// + heights2.y *  waveHeight.y);
				
				pos1.x +=0.1;
				pos2.y +=0.1;
				float3 vec1, vec2;
				vec1 = normalize(pos1 - pos);
				vec2 = normalize(pos2 - pos);
				
				float3 normal = cross(vec1, vec2);
				
				normal = mul(normal, (float3x3)cameraSpaceMatrix);

				float3 viewVector = mul(pos, cameraSpaceMatrix);
			
				outputVertex.viewVector = normalize(-viewVector);
				
               outputVertex.clipPosition = mul(pos, clipSpaceMatrix);
               outputVertex.normal = normal;
               return(outputVertex);
               
         }
            
         endShaderSource
      
      end # end shaderProgram
         
      shaderProgram -target pixelProgram -method assemble
         bindConstants 0 -bindingID allStandardLightData -constantCount 4 -constantType float

         shaderSource
            ps_2_0
            def c10,20,4,0,0
            def c11, 0,0.5,1,2
            dcl t0
            dcl t1 ; v
			dcl_cube s0
			      
            nrm r0, t0       ; n
            
            add r1, r0, r0  ; 2N
            
            dp3 r1.w, r0, t1 ; N.V
			mad r2.xyz, r1, r1.w, -t1     ; 2N * (N.V) -V 
			
			texld r5, r2, s0
			
			dp3 r3.x, r2, c0  ; R.L
			pow r4, r3.x, c10.x
			
			mov_sat r1.x, r1.w
			
			add r6.x, c11.z, -r1.x       ; 1 - Fresnel
			
			pow r3.y, r6.x, c10.y   ; N.V ^ 4
		
			mul r7, r5, r3.y
			mad r4, r4, r3.y, r7
			mul r4, r4, c11.y
			
			mov oC0, r4
            
         endShaderSource
      end
      
      sampler 0 
		texture $wmReflectionTexture
		textureAddressing clamp clamp clamp
      end
   end  # pass
   
enddef


#endshader PoolWaterSurfaceMaterial



# NOTE: 
# refraction in vector terms:
#   v  = incoming unit vector
#   n  = surface normal
#   v' = refracted vector
#   a  = refraction ratio, ni / nr =~ 0.75 for air->water
#
# v' = v - sn
# where s = sqrt(1 - a^2 (1 - (v.n)^2))  - v.n.



##########################################################
# Caustics
#

define TiledTextureAnimShaderProgram(tilesX tilesY speed)
   shaderProgram -target vertexProgram -method assemble
   
      bindConstants 0 -bindingID frameInfo            # for time in .w
      bindConstants 1 -data      (&tilesX, &tilesY, &speed, 1)         # tx, ty, speed
      bindConstants 2 -data      ((1/&tilesX), (1/&tilesY), (&tilesY - 1), 1) # 1/tx 1/ty ty-1
      
      shaderSource
         vs_1_1
         dcl_position v0
         dcl_texcoord v1

         mov oPos, v0  # clip space quad, no transforms needed.
      
         # tiled texture animation
         mov r0, c0
         mul r1, c1.z, r0.w
         frc r5.y, r1.y
         
         mul r1, c1.y, r5.y    # f -> [0, ty)
         frc r5.y, r1
         sub r3.y, r1, r5.y    # v' = floor(f)
         
         mul r1, c1.x, r5.y    # f -> [0, tx)
         frc r5.y, r1
         sub r3.x, r1, r5.y    # u' = floor(f)

         add r8.xy, v1.xy,  r3.xy
         mul oT0.xy, r8.xy, c2.xy
         
      endShaderSource
   
   end		
enddef

define CausticsGeneratorMaterial()   
   material
      # This material updates a render target with the current frame
      # of the tile animation. This is the only way to handle a repeated
      # animating texture (not to mention using it for projective texturing)
      # in the absence of clip maps.
      
      create DetermineHardwareSupport()
      
      if ($causticsEnabled and $useFixedFunctionPath = false and $useSWVertexShaderPath = false)
      
         shader -layer +9999 

            pass
               renderClipSpaceRect
               
               renderTarget causticsTile -fixed (64, 64) -allocateDepthBuffer false -undo

               create TiledTextureAnimShaderProgram(8 4 1)
               
               alphaBlend srcFactor(one) add dstFactor(zero)
               alphaTest false 0
               alphaTestFunction acceptIfGreater

               depthTest false -enableDepthWrite false
               depthTestFunction accept

               # 7/24/2004 Fix bug with kRenderTypeNormal default stencil state and nv40.  
               # It reads random stencil values even this target has no depth stencil target.               
               # This stencil call will break pixo, but pixo does not show caustics.
               stencil false

               fillmode $stdMatFillMode

               stage
                  texture causticsTiled
                  textureAddressing tile tile
                  textureBlend select(texture) select(texture)
               end
            end   
         end
      else
         shader
         
         end
      endif
   end
enddef

  
define CausticsProjectorShaderProgram()
   shaderProgram -target vertexProgram -method assemble
   
      bindConstants 0 -bindingID geomToClip     -constantCount 4
      bindConstants 4 -bindingID geomToCamera   -constantCount 3
      bindConstants 7 -bindingID cameraToGlobal -constantCount 3
      bindConstants 10 -data (0.3, $causticsStrength, (1 - $causticsBaseStrength), 1)
      
      # alignment matrix
      bindConstants 11 -data ( 1, -1, 0, 1)
      bindConstants 12 -data ( 1,  1, 1, 1)
      bindConstants 13 -data (-1, -1, 1, 1)
      
      shaderSource
         vs_1_1
         dcl_position v0
         dcl_texcoord v1

         m4x4 oPos, v0, c0
         
         m4x3 r1, v0, c4
         mov  r1.w, c10.w         
         m4x3 r0, r1, c7
         
         mul r0.xyz, r0.xyz, c10.x
         m3x3 oT0, r0, c11
         
         mul oD0.rgb, v1.y, c10.y
         mad oD0.a, v1.y, -c10.z, c10.w        # 1 - v * 0.3
         
      endShaderSource
   end		
enddef

 
setf causticsStrength 0.8
setf causticsBaseStrength 0.5


if ($causticsEnabled)
   define FloorCausticsPass()
      pass
      end
      #create FloorCausticsPassFF()
   enddef
   define WallCausticsPass()
      pass
      end
      #create WallCausticsPassFF()
   enddef
endif


###################################################
# Materials
#


# Pool surface materials
materialDefinition "poolWater-0"
   setDefinition PoolWaterSurfaceMaterial
   addParam stdMatDiffCoef (0, 0, 1)   
   addParam wmRefractionEnabled true
end

materialDefinition "poolWater-1"
   setDefinition PoolWaterSurfaceMaterial
   addParam stdMatLightingEnabled false
   addParam stdMatLayer 0
   
   addParam stdMatDiffCoef (1, 1, 1)   

   addParam wmReflectionTexture swimming_pool-envcube

   addParam wmTransparency 0.4

   addParam wmXSpeed        3
   addParam wmXRepeat       5
   addParam wmXWaveHeight   0.01 
   
   addParam wmYSpeed        3
   addParam wmYRepeat       6
   addParam wmYWaveHeight   0.01 
end

materialDefinition "poolWater-2"
   setDefinition PoolWaterSurfaceMaterial
   addParam stdMatLightingEnabled false
   addParam stdMatLayer 0
   
   addParam stdMatDiffCoef (0, 0, 1)   

   addParam wmTransparency 0.5

   addParam wmXSpeed        3
   addParam wmXRepeat       12
   addParam wmXWaveHeight   0 #0.02 
   
   addParam wmYSpeed        3
   addParam wmYRepeat       12 
   addParam wmYWaveHeight   0 # 0.02 
end

materialDefinition "poolWater-4"
   setDefinition WaterAnimatingTextures
   addParam waterSpeed 0.3
end


# Pool depth layer materials

# this is here soley because the layering on standard material
# is too constrained. We need a layer less than 7, or we'll
# render over transparent areas of Sims (e.g. hair) when
# they're in the pool at a shallow view angle. 
setc poolLayerColour (0, 0.5, 1)
define PoolDepthLayerMaterial()
   material
      create DetermineHardwareSupport()

      if ($useSWVertexShaderPath or $useFixedFunctionPath)
         shader
         end
      else
         shader -layer $poolWaterLayer
            pass -fixedFunction
               create NonStandardLighting()
               alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
               depthTest true -enableDepthWrite false
               cullmode none
               # the env light is awaiting possible on/off functionality, because we do want the 
               # pool layers to light up if there are pool lights present.
               colorScalar $poolLayerColour 0.9  -applyTextureLightColor 0 0

               stage
                  texture swimming_pool_deeplayer
                  textureBlend multiply(texture colorScalar) multiply(texture colorScalar)
               end
            end
         end
      endif
   end
enddef

materialDefinition "poolWaterLayer-0"
   # this layer does nothing but create the caustics tile.
   setDefinition CausticsGeneratorMaterial
end 

materialDefinition "poolWaterLayer-1"
   setDefinition PoolDepthLayerMaterial
   # addParam poolLayerColour (0, 0, 1)
end
materialDefinition "poolWaterLayer-2" 
   setDefinition PoolDepthLayerMaterial
   # addParam poolLayerColour (0, 1, 0)
end
materialDefinition "poolWaterLayer-3"
   setDefinition PoolDepthLayerMaterial
   # addParam poolLayerColour (1, 0, 0)
end



# For testing
materialDefinition mtl_0
   setDefinition CausticsGeneratorMaterial
end









niol 05:12, 5 March 2007 (CST)

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox