Difference between revisions of "ShaderPool"
From SimsWiki
(EP0-TS2) |
|||
Line 1: | Line 1: | ||
<PRE> | <PRE> | ||
− | + | EP0-TS2 | |
0xCD7FE87A | 0xCD7FE87A | ||
0x1C0532FA | 0x1C0532FA | ||
Line 13: | Line 13: | ||
seti poolWaterLayer 5 | seti poolWaterLayer 5 | ||
− | |||
############################################################## | ############################################################## | ||
Line 60: | Line 59: | ||
define PoolWaterSurfaceMaterial() | define PoolWaterSurfaceMaterial() | ||
− | material | + | material |
shader -layer $poolWaterLayer | shader -layer $poolWaterLayer | ||
validateRenderShaderContext -vertexFormat position 0 required | validateRenderShaderContext -vertexFormat position 0 required | ||
Line 74: | Line 73: | ||
create SimplifiedWaterSurface() | create SimplifiedWaterSurface() | ||
else | else | ||
− | + | create RegularWavesHLSL() | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
endif | endif | ||
Line 92: | Line 87: | ||
define SimplifiedWaterSurface() | define SimplifiedWaterSurface() | ||
− | pass -fixedFunction | + | pass -fixedFunction |
alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha) | alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha) | ||
depthTest true -enableDepthWrite false | depthTest true -enableDepthWrite false | ||
− | colorScalar (0.2,0.3,1.0) 0.4 | + | colorScalar (0.2,0.3,1.0) 0.4 |
+ | |||
stage | stage | ||
textureBlend select(colorScalar) select(colorScalar) | textureBlend select(colorScalar) select(colorScalar) | ||
Line 117: | Line 113: | ||
#fillmode wireframe | #fillmode wireframe | ||
alphaBlend srcFactor(one) add dstFactor(one) | alphaBlend srcFactor(one) add dstFactor(one) | ||
− | seti textureLights (numLightsOfType(environmentCube)) | + | seti textureLights (numLightsOfType(environmentCube)) |
+ | |||
+ | |||
shaderProgram -target vertexProgram -method compile -version 1_1 | shaderProgram -target vertexProgram -method compile -version 1_1 | ||
Line 135: | Line 133: | ||
bindConstants 14 -bindingID allStandardLightData -constantCount 4 -constantType float | bindConstants 14 -bindingID allStandardLightData -constantCount 4 -constantType float | ||
bindConstants 18 -bindingID cameraToGlobal -constantCount 3 | bindConstants 18 -bindingID cameraToGlobal -constantCount 3 | ||
− | + | ||
− | if ( | + | if ($textureLights) |
− | bindConstants 25 -bindingID | + | bindConstants 25 -bindingID allTextureLights -constantCount 1 -constantType float |
else | else | ||
− | bindConstants 25 -bindingID immediateData -data ( | + | bindConstants 25 -bindingID immediateData -data (1,1,1,1) -constantType float |
endif | endif | ||
+ | |||
+ | |||
shaderSource | shaderSource | ||
Line 158: | Line 158: | ||
const static float4 refractionWeights={1,1,2,0}; | const static float4 refractionWeights={1,1,2,0}; | ||
− | + | ### dNL | |
− | + | ||
struct InputVertex | struct InputVertex | ||
{ | { | ||
Line 235: | Line 235: | ||
float I = pow(rdotl+0.1, 15); // fudge factor to punch up the highlights. | float I = pow(rdotl+0.1, 15); // fudge factor to punch up the highlights. | ||
− | |||
− | outputVertex.diffuseColor = | + | outputVertex.diffuseColor = (1.0 - fresnel) * nightColor * 0.5; |
− | + | ||
outputVertex.specularColor = I; | outputVertex.specularColor = I; | ||
return(outputVertex); | return(outputVertex); | ||
Line 258: | Line 256: | ||
end # end pass | end # end pass | ||
− | |||
enddef | enddef | ||
Line 264: | Line 261: | ||
define HighEndWaterSurface() | 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 | endShaderSource | ||
− | end | + | end |
− | sampler | + | sampler 0 |
− | + | texture $wmReflectionTexture | |
− | + | textureAddressing clamp clamp clamp | |
− | end | + | end |
− | + | end # pass | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
enddef | enddef | ||
Line 488: | Line 497: | ||
bindConstants 0 -bindingID frameInfo # for time in .w | bindConstants 0 -bindingID frameInfo # for time in .w | ||
bindConstants 1 -data (&tilesX, &tilesY, &speed, 1) # tx, ty, speed | 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 | + | bindConstants 2 -data ((1/&tilesX), (1/&tilesY), (&tilesY - 1), 1) # 1/tx 1/ty ty-1 |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
shaderSource | shaderSource | ||
Line 518: | Line 522: | ||
mul oT0.xy, r8.xy, c2.xy | mul oT0.xy, r8.xy, c2.xy | ||
− | + | ### dNL | |
− | + | ||
endShaderSource | endShaderSource | ||
Line 526: | Line 530: | ||
define CausticsGeneratorMaterial() | define CausticsGeneratorMaterial() | ||
− | material | + | material |
# This material updates a render target with the current frame | # This material updates a render target with the current frame | ||
# of the tile animation. This is the only way to handle a repeated | # of the tile animation. This is the only way to handle a repeated | ||
Line 538: | Line 542: | ||
shader -layer +9999 | shader -layer +9999 | ||
− | pass | + | pass |
renderClipSpaceRect | renderClipSpaceRect | ||
Line 557: | Line 561: | ||
stencil false | stencil false | ||
− | fillmode $stdMatFillMode | + | fillmode $stdMatFillMode |
− | + | ||
− | + | stage | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
texture causticsTiled | texture causticsTiled | ||
− | textureAddressing tile tile | + | textureAddressing tile tile |
+ | textureBlend select(texture) select(texture) | ||
end | end | ||
− | |||
end | end | ||
end | end | ||
Line 589: | Line 577: | ||
end | end | ||
enddef | 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 causticsStrength 0.8 | ||
setf causticsBaseStrength 0.5 | setf causticsBaseStrength 0.5 | ||
+ | |||
+ | |||
+ | if ($causticsEnabled) | ||
+ | define FloorCausticsPass() | ||
+ | pass | ||
+ | end | ||
+ | #create FloorCausticsPassFF() | ||
+ | enddef | ||
+ | define WallCausticsPass() | ||
+ | pass | ||
+ | end | ||
+ | #create WallCausticsPassFF() | ||
+ | enddef | ||
+ | endif | ||
Line 607: | Line 645: | ||
materialDefinition "poolWater-1" | materialDefinition "poolWater-1" | ||
− | setDefinition PoolWaterSurfaceMaterial | + | setDefinition PoolWaterSurfaceMaterial |
addParam stdMatLightingEnabled false | addParam stdMatLightingEnabled false | ||
addParam stdMatLayer 0 | addParam stdMatLayer 0 | ||
Line 656: | Line 694: | ||
# render over transparent areas of Sims (e.g. hair) when | # render over transparent areas of Sims (e.g. hair) when | ||
# they're in the pool at a shallow view angle. | # they're in the pool at a shallow view angle. | ||
− | setc poolLayerColour (0, 0.5, 1 | + | setc poolLayerColour (0, 0.5, 1) |
define PoolDepthLayerMaterial() | define PoolDepthLayerMaterial() | ||
− | material | + | material |
− | create DetermineHardwareSupport() | + | create DetermineHardwareSupport() |
+ | |||
if ($useSWVertexShaderPath or $useFixedFunctionPath) | if ($useSWVertexShaderPath or $useFixedFunctionPath) | ||
shader | shader | ||
Line 665: | Line 704: | ||
else | else | ||
shader -layer $poolWaterLayer | shader -layer $poolWaterLayer | ||
− | + | pass -fixedFunction | |
− | + | create NonStandardLighting() | |
− | + | ||
− | + | ||
alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha) | 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 | + | |
− | end | + | |
end | end | ||
endif | endif | ||
Line 719: | Line 725: | ||
materialDefinition "poolWaterLayer-0" | materialDefinition "poolWaterLayer-0" | ||
# this layer does nothing but create the caustics tile. | # this layer does nothing but create the caustics tile. | ||
− | setDefinition CausticsGeneratorMaterial | + | setDefinition CausticsGeneratorMaterial |
end | end | ||
materialDefinition "poolWaterLayer-1" | materialDefinition "poolWaterLayer-1" | ||
− | setDefinition PoolDepthLayerMaterial | + | setDefinition PoolDepthLayerMaterial |
− | addParam poolLayerColour (0, 0 | + | # addParam poolLayerColour (0, 0, 1) |
end | end | ||
materialDefinition "poolWaterLayer-2" | materialDefinition "poolWaterLayer-2" | ||
− | setDefinition PoolDepthLayerMaterial | + | setDefinition PoolDepthLayerMaterial |
− | addParam poolLayerColour (0 | + | # addParam poolLayerColour (0, 1, 0) |
end | end | ||
materialDefinition "poolWaterLayer-3" | materialDefinition "poolWaterLayer-3" | ||
setDefinition PoolDepthLayerMaterial | setDefinition PoolDepthLayerMaterial | ||
− | addParam poolLayerColour ( | + | # addParam poolLayerColour (1, 0, 0) |
end | end | ||
+ | |||
+ | |||
+ | # For testing | ||
materialDefinition mtl_0 | materialDefinition mtl_0 | ||
setDefinition CausticsGeneratorMaterial | setDefinition CausticsGeneratorMaterial | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
end | end | ||
</PRE> | </PRE> | ||
− |
Revision as of 12:26, 26 March 2007
EP0-TS2 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}; ### dNL 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 ### dNL 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