ShaderPool
From SimsWiki
EP6-BV
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
if ($useHWShader2Path)
create HighEndWaterSurface()
else
create RegularWavesHLSL()
endif
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 (tsIsDay)
bindConstants 25 -bindingID immediateData -data (0.75, 0.75, 0.75, 1)
else
bindConstants 25 -bindingID immediateData -data (0.2, 0.2, 0.2, 1)
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};
const static float4 layerBlue={0.3, 0.7, 1.0, 1};
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.
nightColor = nightColor * 2;
outputVertex.diffuseColor = ((1.0 - fresnel) * saturate(nightColor) * 0.5) * layerBlue;
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 -clipAlways -modifiedEachFrameHint
#fillmode wireframe
alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
seti textureLights (numLightsOfType(environmentCube))
depthTest true -enableDepthWrite false
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
bindConstants 21 -bindingID cameraToGeom -constantCount 3
if (tsIsDay)
bindConstants 25 -bindingID immediateData -data (0.75, 0.75, 0.75, 1)
else
bindConstants 25 -bindingID immediateData -data (0.2, 0.2, 0.2, 1)
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);
float4x3 cameraToGeomMatrix : register(c21);
float4 nightColor: register(c25);
float4 lightDirection : register(c14);
float4 lightColor : register(c15);
float4 lightSpecular : register(c16);
const static float4 refractionWeights={1,1,2,0};
const static float4 layerBlue={0.3, 0.7, 1.0, 1};
struct InputVertex
{
float3 position: POSITION0;
float3 normal : NORMAL0;
};
struct OutputVertex
{
float4 clipPosition : POSITION;
float4 sPos : TEXCOORD0;
float2 Wave0 : TEXCOORD1;
float2 Wave1 : TEXCOORD2;
float2 Wave2 : TEXCOORD3;
float2 Wave3 : TEXCOORD4;
float3 Eye : TEXCOORD5;
float4 specular : COLOR0;
};
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);
float z = sin(temp) * waveDataX.z + inputVertex.position.z;
temp = dot(posAndTime, waveDataY);
posAndTime.z = z + sin(temp) * waveDataY.z;
posAndTime.w = 1.0f;
outputVertex.clipPosition = mul( posAndTime, clipSpaceMatrix);
outputVertex.sPos = float4(0.5f*(outputVertex.clipPosition.ww - outputVertex.clipPosition.xy), outputVertex.clipPosition.ww);
float3 waveNormal = normalize(inputVertex.normal + float3(cos(temp)*waveDataHelper.xy, 0));
float3 cameraSpaceNormal = normalize(mul(waveNormal, cameraSpaceMatrix));
float3 cameraSpacePosition = mul( posAndTime, cameraSpaceMatrix);
float3 viewVector = normalize(-cameraSpacePosition);
float3 halfVector = normalize(viewVector + lightDirection);
outputVertex.specular = lightSpecular*pow(dot(cameraSpaceNormal, halfVector), 50)*nightColor*lightColor*0.5;
float2 fTranslation=float2(fmod(frameInfo.w, 100)*0.005, fmod(frameInfo.w, 100)*0.005);
float2 vTexCoords = posAndTime.xy*0.05;
// Output bump layers texture coordinates
float fSinTranslation=sin(fTranslation*100)*0.005;
float2 vTranslation0=fTranslation+fSinTranslation;
float2 vTranslation1=fTranslation-fSinTranslation;
float2 vTranslation2=fTranslation;
// Scale texture coordinates to get mix of low/high frequency details
outputVertex.Wave0.xy = vTexCoords.xy+fTranslation*2.0;
outputVertex.Wave1.xy = vTexCoords.xy*2.0+fTranslation*4.0;
outputVertex.Wave2.xy = vTexCoords.xy*7.0+fTranslation*2.0;
outputVertex.Wave3.xy = vTexCoords.xy*12.0+fTranslation;
// compute binormal
float3 binormal = normalize(cross(waveNormal, float3(1.0f, 0.0f, 0.0f)));
float3 tangent = normalize(cross(binormal, waveNormal));
// tangent space matrix
float3x3 objToTangentSpace = float3x3(tangent, binormal, waveNormal);
float3 viewVectorInObjSpace = mul(viewVector, (float3x3)cameraToGeomMatrix);
outputVertex.Eye.xyz = mul(objToTangentSpace, viewVectorInObjSpace);
return(outputVertex);
}
endShaderSource
end # shaderProgram
shaderProgram -target pixelProgram -method compile -version 2_0
shaderSource
sampler reflect;
sampler bump;
struct cInputPixel
{
float4 sPos : TEXCOORD0;
float2 Wave0 : TEXCOORD1;
float2 Wave1 : TEXCOORD2;
float2 Wave2 : TEXCOORD3;
float2 Wave3 : TEXCOORD4;
float3 Eye : TEXCOORD5;
float4 specular : COLOR0;
};
float Fresnel(float NdotL, float fresnelBias, float fresnelPow, float facing)
{
return max(fresnelBias + (1.0f - fresnelBias)*pow(facing, fresnelPow), 0.0);
}
float4 PixelMain(cInputPixel pi) : COLOR
{
float3 vEye = normalize(pi.Eye);
// Get bump layers
float3 vBumpTexA = tex2D(bump, pi.Wave0.xy).xyz;
float3 vBumpTexB = tex2D(bump, pi.Wave1.xy).xyz;
float3 vBumpTexC = tex2D(bump, pi.Wave2.xy).xyz;
float3 vBumpTexD = tex2D(bump, pi.Wave3.xy).xyz;
// Average bump layers
float3 vBumpTex=normalize(2.0 * (vBumpTexA.xyz + vBumpTexB.xyz + vBumpTexC.xyz + vBumpTexD.xyz)-4.0);
// Apply individual bump scale for refraction and reflection
float3 vReflBump = vBumpTex.xyz * float3(0.1, 0.1, 1.0);
float4 vReflection = tex2Dproj(reflect, pi.sPos + float4(vReflBump.xy, 0.0f, 0.0f));//*0.001 + float4(2.0*vBumpTexD-1.0f.xxx, 1);
// Compute Fresnel term
float NdotL = max(dot(vEye, vReflBump), 0);
float facing = (1.0 - NdotL);
float fresnel = Fresnel(NdotL, 0.2, 5.0, facing);
vReflection.a = fresnel;
return saturate(vReflection + float4(0.0, 0.25, 0.5, 0.0) + pi.specular);
}
endShaderSource
end
sampler reflect
texture "PoolReflection"
textureAddressing clamp clamp
end
sampler bump
texture "poolShape-body-bump"
textureAddressing tile tile
end
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
if (tsIsDay)
bindConstants 3 -bindingID immediateData -data (0.75, 0.75, 0.75, 1)
else
bindConstants 3 -bindingID immediateData -data (0.2, 0.2, 0.2, 1)
endif
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
mov oD0, c3 # also spit out diffuse color with modcolor information
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
shaderProgram -target pixelProgram -method compile -version 1_1
shaderSource
sampler caustics;
struct cInputPixel
{
float4 color : COLOR;
float2 tc0 : TEXCOORD0;
};
float4 PixelMain(cInputPixel pi) : COLOR
{
float4 texColor = tex2D(caustics, pi.tc0);
return texColor*pi.color;
}
endShaderSource
end
sampler 0
texture causticsTiled
textureAddressing tile tile
end
end
end
else
shader
end
endif
end
enddef
setf causticsStrength 0.8
setf causticsBaseStrength 0.5
###################################################
# 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.0, 1.0)
define PoolDepthLayerMaterial()
material
create DetermineHardwareSupport()
if ($useSWVertexShaderPath or $useFixedFunctionPath)
shader
end
else
shader -layer $poolWaterLayer
validateRenderShaderContext -vertexFormat position 0 required
validateRenderShaderContext -vertexFormat texcoord 0 required
pass
alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
depthTest true -enableDepthWrite false
#fillmode wireframe
shaderProgram -target vertexProgram -method compile -version 1_1
bindConstants 0 -bindingID geomToClip -constantCount 4
bindConstants 4 -bindingID immediateData -data ($poolLayerColour)
shaderSource
float4x4 clipSpaceMatrix : register(c0);
float4 poolLayer : register(c4);
struct cVertexIn
{
float3 mPosition : POSITION0;
float2 alpha : TEXCOORD0;
};
struct cVertexOut
{
float4 mClipPosition : POSITION;
float4 mColor : COLOR0;
};
cVertexOut VertexMain(cVertexIn vertexIn)
{
cVertexOut result;
result.mClipPosition = mul(float4(vertexIn.mPosition, 1), clipSpaceMatrix);
result.mColor = float4(poolLayer.r, poolLayer.g, poolLayer.b, poolLayer.a * vertexIn.alpha.x);
return result;
}
endShaderSource
end
shaderProgram -target pixelProgram -method compile -version 1_1
shaderSource
float4 PixelMain(float4 color : COLOR) : COLOR
{
return color;
}
endShaderSource
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.5, 1.0, 0.2)
end
materialDefinition "poolWaterLayer-2"
setDefinition PoolDepthLayerMaterial
addParam poolLayerColour (0, 0.5, 1.0, 0.2)
end
materialDefinition "poolWaterLayer-3"
setDefinition PoolDepthLayerMaterial
addParam poolLayerColour (0, 0.5, 1.0, 0.5)
end
materialDefinition mtl_0
setDefinition CausticsGeneratorMaterial
end
materialDefinition "lightingwallpoolsimple_reflective"
setDefinition StandardMaterial
addParam stdMatDiffCoef (0.8, 0.8, 0.8)
addParam stdMatAlphaMultiplier 1.0
addParam stdMatAlphaBlendMode none
addParam stdMatSpecCoef 0.091,0.091,0.091
addParam stdMatBaseTextureEnabled true
addParam stdMatBaseTextureName lightingwallpoolsimple-surface
addParam stdMatEnvCubeLockedToCamera 0
addParam stdMatEnvCubeMode reflection
addParam stdMatEnvCubeTextureName reflectionkitchenhighcontrast-envcube
addParam forceIgnoreShapeBlend true
end