Difference between revisions of "ShaderMirror"
From SimsWiki
(Teko Murano 200708) |
(EP6-BV) |
||
| Line 1: | Line 1: | ||
<pre> | <pre> | ||
| + | |||
| + | EP6-BV | ||
| + | 0xCD7FE87A | ||
| + | 0x1C0532FA | ||
| + | 0xBAC036BC | ||
| + | 0xFF123570 | ||
| + | # reflection | ||
version 4 | version 4 | ||
| + | |||
| + | # Shaders for mirror reflections. | ||
| + | |||
| + | # Note: These materials assume that the reflection camera uses the same handed coordinate system as | ||
| + | # the main camera, with the x axis flipped. Therefore, when marking out the area in the stencil buffer | ||
| + | # to be filled in the with the reflection view, the x clip coordinate of the mirror vertices is | ||
| + | # negated. | ||
| + | # | ||
| + | # The layer numbers for the mirror pre- and post-reflection render materials (+/-99998) are referenced | ||
| + | # from C++ code for the censor-in-mirror render. | ||
set reflectionRenderTarget "ScreenReflection" | set reflectionRenderTarget "ScreenReflection" | ||
| − | + | #beginshader SimpleMirrorReflection | |
| + | #description Assign this material to the mirror quad to make it reflective. | ||
| + | #description The mirror quad needs to be centered over the origin in its local space, | ||
| + | #description facing positive Y. You can use a transform bone to orient the mirror | ||
| + | #description however you need. | ||
| + | set mvAspect 1 | ||
| + | setv4 thumbnailMirrorColor (0.5,0.6,0.75, 1) | ||
| + | setv4 impostorMirrorColor (0.4, 0.4, 0.4, 1) | ||
| + | setv4 reflectionsOffMirrorColor (0.6, 0.6, 0.6, 1) | ||
define SimpleMirrorReflection() | define SimpleMirrorReflection() | ||
material | material | ||
| Line 13: | Line 38: | ||
create StandardShaderShadow() | create StandardShaderShadow() | ||
else | else | ||
| − | + | if (viewerRenderType = $kRenderTypeThumbnail) | |
| − | + | create BlankMirrorMaterial(viewerRenderType $thumbnailMirrorColor) | |
| − | + | elseif (viewerRenderType = $kRenderTypeImposter) | |
| − | + | create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor) | |
| − | + | elseif (viewerRenderType = $kRenderTypePoolReflection) | |
| − | + | create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor) | |
| − | + | elseif (viewerRenderType = $kRenderTypeOceanReflection) | |
| − | + | create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor) | |
| − | + | else | |
| − | + | if (not $mirrorReflectionsEnabled) | |
| + | set currentType (viewerRenderType) | ||
| + | create BlankMirrorMaterial($currentType $reflectionsOffMirrorColor) | ||
| + | else | ||
| + | create MirrorReflectionMaterial() | ||
| + | endif | ||
| + | endif | ||
endif | endif | ||
end | end | ||
enddef | enddef | ||
| + | #endshader | ||
| − | define BlankMirrorMaterial(renderType) | + | define BlankMirrorMaterial(renderType mirrorColor) |
| + | # mirror shader for thumbnails. Output a single flat color. | ||
shader | shader | ||
validateRenderShaderContext -viewerRenderType &renderType | validateRenderShaderContext -viewerRenderType &renderType | ||
| Line 41: | Line 74: | ||
end | end | ||
| − | colorScalar | + | colorScalar &mirrorColor |
stage | stage | ||
textureBlend select(colorScalar) select(colorScalar) | textureBlend select(colorScalar) select(colorScalar) | ||
| Line 49: | Line 82: | ||
enddef | enddef | ||
| − | + | # shader to prep stencil buffer on the rendertarget for the mirror reflection view. | |
| + | # When objects are rendered from the viewpoint of the reflection camera after this shader runs, they will | ||
| + | # render only to the area of the rendertarget marked out in the stencil buffer by this shader. | ||
define MirrorReflectionMaterial() | define MirrorReflectionMaterial() | ||
| − | + | create DetermineHardwareSupport() | |
| + | # write depth into the depth buffer as seen from the main camera. Write stencil = 1 | ||
| + | # if this is the mirror we are rendering the reflection for, and 0 otherwise. | ||
shader -layer -9998 # this material must render first | shader -layer -9998 # this material must render first | ||
validateRenderShaderContext -viewerRenderType $kRenderTypeMirror # reflection render | validateRenderShaderContext -viewerRenderType $kRenderTypeMirror # reflection render | ||
| − | + | ||
| − | pass -renderEachFrame | + | # write stencil in area occupied by mirror |
| + | if ($useSWVertexShaderPath) | ||
| + | pass -renderEachFrame -modifiedEachFrameHint | ||
| + | else | ||
| + | pass -renderEachFrame | ||
| + | endif | ||
renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext | renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext | ||
| + | # test and write depth (as seen from the main camera) | ||
depthTest true -enableDepthWrite true | depthTest true -enableDepthWrite true | ||
| + | # This material script command means the following: | ||
| + | # | ||
| + | # if (renderableIsTargetBounded) | ||
| + | # set stencil test to write 1 when depth test passes | ||
| + | # else | ||
| + | # set stencil test to write 0 when depth test passes | ||
| + | # | ||
applyStencilStateForOverlappingReflections | applyStencilStateForOverlappingReflections | ||
| − | + | ||
| + | # do not write color | ||
| + | #colorWriteEnable -red false -green false -blue false -alpha false | ||
alphaBlend srcFactor(zero) add dstFactor(one) | alphaBlend srcFactor(zero) add dstFactor(one) | ||
| − | + | ||
| + | # since we are negating clip space x below we need to prevent this quad from being culled | ||
cullmode none | cullmode none | ||
| − | + | ||
| + | # vertex program | ||
shaderProgram -target vertexProgram -method assemble | shaderProgram -target vertexProgram -method assemble | ||
| − | bindConstants 0 -bindingID geomToClipFromParentView -constantCount 4 | + | bindConstants 0 -bindingID geomToClipFromParentView -constantCount 4 # set the matrices from the parent (i.e. the main view) so that the stencil is written to the right place |
| + | |||
shaderSource | shaderSource | ||
vs_1_1 | vs_1_1 | ||
dcl_position v0 | dcl_position v0 | ||
| + | |||
| + | ; color output for debugging | ||
def c5, 1,0,0,1 | def c5, 1,0,0,1 | ||
| + | |||
| + | ; project vertex to clip coords | ||
m4x4 r0, v0, c0 | m4x4 r0, v0, c0 | ||
| + | |||
| + | ; flip the x coordinate so the stencil is marked in the right place | ||
mov oPos.x, -r0 | mov oPos.x, -r0 | ||
mov oPos.yzw, r0 | mov oPos.yzw, r0 | ||
endShaderSource | endShaderSource | ||
end | end | ||
| − | end | + | end # pass |
| − | end | + | end # shader |
| − | shader -layer | + | # render of the mirror from the main camera. This samples from the reflection render target texture. |
| + | shader -layer 16 # this must be after all opaque objects (especially Sims), but before transparent objects and the censor compositing pass | ||
validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | ||
| − | pass -modifiedEachFrameHint | + | |
| + | pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode | ||
| + | |||
shaderProgram -target vertexProgram -method assemble | shaderProgram -target vertexProgram -method assemble | ||
bindConstants 0 -bindingID geomToClip -constantCount 4 | bindConstants 0 -bindingID geomToClip -constantCount 4 | ||
| Line 91: | Line 155: | ||
def c8, -0.5, -0.5, 1, 1 | def c8, -0.5, -0.5, 1, 1 | ||
def c9, 0.5, 0.5, 0, 0 | def c9, 0.5, 0.5, 0, 0 | ||
| + | |||
def c10, 0.25, 0.25, 0, 0 | def c10, 0.25, 0.25, 0, 0 | ||
| + | |||
| + | # project vertex to clip coords | ||
m4x4 r0, v0, c0 | m4x4 r0, v0, c0 | ||
mov oPos, r0 | mov oPos, r0 | ||
| + | |||
| + | # multiply 0.5 * w so homogenous divide will make it 0.5 again | ||
mul r2, c9, r0.w | mul r2, c9, r0.w | ||
| + | |||
| + | # scale projected xy by .5 and re-center so it's in 0-w range | ||
mad r4, r0, c8, r2 | mad r4, r0, c8, r2 | ||
| − | rcp r3.x, c4.x | + | |
| − | rcp r3.y, c5.y | + | # Try to get an exact texel to pixel mapping by shifting texture coordinates |
| − | mov r3.zw, c9.zw | + | # slightly. |
| − | mul r3, r3, c10 | + | # A texture coordinate of 0 must map to 1/2*(texture dimension) and a |
| + | # coordinate of 1 must map to (1 - 1/2*(texture dimension)). | ||
| + | # Note: This does not seem to eliminate the wobble on the mirror | ||
| + | # reflection entirely. | ||
| + | rcp r3.x, c4.x ;# 2/width | ||
| + | rcp r3.y, c5.y ;# 2/height | ||
| + | mov r3.zw, c9.zw ;# r3 = (2/width, 2/height, 0, 0) | ||
| + | |||
| + | mul r3, r3, c10 ;# r3 = (1/2*width, 1/2*height, 0, 0) | ||
mad r6, r0, r3, r4 | mad r6, r0, r3, r4 | ||
| − | mov oT0, r6.xyww | + | mov oT0, r6.xyww ;# move w into z so we can divide by z in the texture stage; some cards don't handle division by w correctly |
endShaderSource | endShaderSource | ||
end | end | ||
stage | stage | ||
| − | textureTransformType vector3 homogeneous | + | textureTransformType vector3 homogeneous # divide the xy components of the texture coordinate by z |
textureAddressing clamp clamp | textureAddressing clamp clamp | ||
texture $reflectionRenderTarget | texture $reflectionRenderTarget | ||
textureBlend select(texture) select(texture) | textureBlend select(texture) select(texture) | ||
| − | end | + | end # stage |
| − | end | + | end # pass |
| − | end | + | end # shader |
| − | shader -layer | + | # this shader is in case the above case fails. This does projection per vertex. |
| − | validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | + | shader -layer 16 |
| − | pass -modifiedEachFrameHint | + | validateRenderShaderContext -viewerRenderType $kRenderTypeNormal |
| + | |||
| + | pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode | ||
| + | |||
shaderProgram -target vertexProgram -method assemble | shaderProgram -target vertexProgram -method assemble | ||
bindConstants 0 -bindingID geomToClip -constantCount 4 | bindConstants 0 -bindingID geomToClip -constantCount 4 | ||
bindConstants 4 -bindingID clipToViewTarget -constantCount 4 | bindConstants 4 -bindingID clipToViewTarget -constantCount 4 | ||
| + | |||
shaderSource | shaderSource | ||
vs_1_1 | vs_1_1 | ||
dcl_position v0 | dcl_position v0 | ||
def c8, -0.5, -0.5, 1, 1 | def c8, -0.5, -0.5, 1, 1 | ||
| − | def c9, 0.5, 0.5, 0, 0 | + | def c9, 0.5, 0.5, 0, 0 |
| + | |||
def c10, 0.25, 0.25, 0, 0 | def c10, 0.25, 0.25, 0, 0 | ||
| + | |||
| + | # project vertex to clip coords | ||
m4x4 r0, v0, c0 | m4x4 r0, v0, c0 | ||
mov oPos, r0 | mov oPos, r0 | ||
| + | |||
| + | # multiply 0.5 * w so homogenous divide will make it 0.5 again | ||
mul r2, c9, r0.w | mul r2, c9, r0.w | ||
| + | |||
| + | # scale projected xy by .5 and re-center so it's in 0-w range | ||
mad r4, r0, c8, r2 | mad r4, r0, c8, r2 | ||
| − | rcp r3.x, c4.x | + | |
| − | rcp r3.y, c5.y | + | # Try to get an exact texel to pixel mapping by shifting texture coordinates |
| − | mov r3.zw, c9.zw | + | # slightly. |
| − | mul r3, r3, c10 | + | # A texture coordinate of 0 must map to 1/2*(texture dimension) and a |
| − | mad r1, r0, r3, r4 | + | # coordinate of 1 must map to (1 - 1/2*(texture dimension)). |
| − | rcp r1.w, r1.w | + | # Note: This does not seem to eliminate the wobble on the mirror |
| − | mul oT0.xy, r1.w, r1.xy | + | # reflection entirely. |
| + | rcp r3.x, c4.x ;# 2/width | ||
| + | rcp r3.y, c5.y ;# 2/height | ||
| + | mov r3.zw, c9.zw ;# r3 = (2/width, 2/height, 0, 0) | ||
| + | |||
| + | mul r3, r3, c10 ;# r3 = (1/2*width, 1/2*height, 0, 0) | ||
| + | |||
| + | mad r1, r0, r3, r4 ; write to a temp instead of output texcoord (as above) | ||
| + | |||
| + | rcp r1.w, r1.w ; calc 1/w | ||
| + | |||
| + | mul oT0.xy, r1.w, r1.xy ; project per vertex since the intel HW (and maybe others) can't do it per pixel. | ||
| + | |||
endShaderSource | endShaderSource | ||
| − | end | + | end #shader |
stage | stage | ||
| Line 145: | Line 247: | ||
texture $reflectionRenderTarget | texture $reflectionRenderTarget | ||
textureBlend select(texture) select(texture) | textureBlend select(texture) select(texture) | ||
| − | end | + | end # stage |
| − | end | + | end # pass |
| − | end | + | end #shader |
enddef | enddef | ||
| + | # material to clear stencil buffer and set depth buffer to "correct" value on rendertarget. | ||
| + | # The depth value is the depth as seen from the main camera. | ||
| + | define MirrorBackClearStencilAndSetDepth() | ||
| + | material | ||
| + | # AV TODO: this material doesn't do anything now, so it should be removed (from go2sco as well) | ||
| + | shader -layer 9998 | ||
| + | end # shader | ||
| + | end # material | ||
| + | enddef | ||
| + | |||
| + | # used by the mirror render. Sets z to the specified value on the entire reflection render target. | ||
define SetSpecifiedZOnMirrorRTT(zValue) | define SetSpecifiedZOnMirrorRTT(zValue) | ||
material | material | ||
| Line 157: | Line 270: | ||
pass | pass | ||
renderClipSpaceRect | renderClipSpaceRect | ||
| − | renderTarget $reflectionRenderTarget -setViewport fullRenderTargetViewport | + | renderTarget $reflectionRenderTarget -setViewport fullRenderTargetViewport |
| + | |||
| + | # turn off stencil test | ||
stencil false | stencil false | ||
| + | |||
| + | # depth test accept always, write depth | ||
depthTest true -enableDepthWrite true | depthTest true -enableDepthWrite true | ||
depthTestFunction accept | depthTestFunction accept | ||
| + | |||
| + | # do not write color | ||
alphaBlend srcFactor(zero) add dstFactor(one) | alphaBlend srcFactor(zero) add dstFactor(one) | ||
| + | |||
| + | # vertex program | ||
shaderProgram -target vertexProgram -method compile -version 1_1 | shaderProgram -target vertexProgram -method compile -version 1_1 | ||
bindConstants 0 -bindingID immediateData -data (0,0,&zValue, 0) | bindConstants 0 -bindingID immediateData -data (0,0,&zValue, 0) | ||
| + | |||
shaderSource | shaderSource | ||
float4 zValue : register(c0); | float4 zValue : register(c0); | ||
| + | |||
void VertexMain(float4 position : POSITION, out float4 oPosition : POSITION) | void VertexMain(float4 position : POSITION, out float4 oPosition : POSITION) | ||
{ | { | ||
| Line 171: | Line 294: | ||
oPosition.z = zValue.z; // set specified z value | oPosition.z = zValue.z; // set specified z value | ||
} | } | ||
| + | |||
endShaderSource | endShaderSource | ||
end | end | ||
| − | end | + | end # pass |
| − | end | + | end # shader |
| − | end | + | end # material |
enddef | enddef | ||
| + | # used by the mirror camera for dirty rect rendering | ||
define SetNearZOnMirrorRTT() | define SetNearZOnMirrorRTT() | ||
create SetSpecifiedZOnMirrorRTT(0) | create SetSpecifiedZOnMirrorRTT(0) | ||
enddef | enddef | ||
| + | # used by the mirror camera for non-dirty rect rendering | ||
define SetFarZOnMirrorRTT() | define SetFarZOnMirrorRTT() | ||
create SetSpecifiedZOnMirrorRTT(1) | create SetSpecifiedZOnMirrorRTT(1) | ||
enddef | enddef | ||
| + | # used by the censor render in the mirror. Sets stencil on the entire censor render target to 1. | ||
define SetStencilOnCensorRTT() | define SetStencilOnCensorRTT() | ||
material | material | ||
| Line 191: | Line 318: | ||
pass | pass | ||
renderClipSpaceRect | renderClipSpaceRect | ||
| + | |||
| + | # set stencil to 1 everywhere | ||
stencil true | stencil true | ||
stencilFunction accept -refValue 1 | stencilFunction accept -refValue 1 | ||
stencilOperation -onPass writeRef | stencilOperation -onPass writeRef | ||
| + | |||
| + | # depth test accept, do not write depth | ||
depthTest false -enableDepthWrite false | depthTest false -enableDepthWrite false | ||
depthTestFunction accept | depthTestFunction accept | ||
| + | |||
| + | # do not write color | ||
alphaBlend srcFactor(zero) add dstFactor(one) | alphaBlend srcFactor(zero) add dstFactor(one) | ||
| + | |||
shaderProgram -target vertexProgram -method assemble | shaderProgram -target vertexProgram -method assemble | ||
shaderSource | shaderSource | ||
| Line 209: | Line 343: | ||
end | end | ||
| − | end | + | end # pass |
| − | end | + | end # shader |
| − | end | + | end # material |
enddef | enddef | ||
| − | defaultState $kRenderTypeMirror | + | # common state for all objects rendered with the reflection camera |
| + | defaultState $kRenderTypeMirror # reflection render | ||
| + | # stencil test passes only in the areas where the reference value has been written | ||
stencil true | stencil true | ||
stencilFunction acceptIfEqual -refValue 1 | stencilFunction acceptIfEqual -refValue 1 | ||
| Line 220: | Line 356: | ||
end | end | ||
| − | defaultState $kRenderTypeNormal | + | if (not varExists(isContentViewer)) |
| − | + | # only render where the stencil is zero in turbo rect mode | |
| − | + | defaultState $kRenderTypeNormal # Stencil | |
| − | + | stencil true | |
| − | + | stencilFunction acceptIfEqual -refValue 0 | |
| − | + | stencilOperation -onPass noWrite | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
end | end | ||
| − | + | endif | |
| − | + | # Begin DO NOT MODIFY THIS BLOCK | |
| − | + | # Material instances bound to reflective surfaces. | |
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | + | ||
| − | # | + | # Note: The following material instances are bound to exported resources and accessed |
| + | # by runtime code. They CANNOT be deleted without changing the export program. | ||
materialDefinition simple_mirror_reflection | materialDefinition simple_mirror_reflection | ||
Latest revision as of 05:03, 7 September 2007
EP6-BV
0xCD7FE87A
0x1C0532FA
0xBAC036BC
0xFF123570
# reflection
version 4
# Shaders for mirror reflections.
# Note: These materials assume that the reflection camera uses the same handed coordinate system as
# the main camera, with the x axis flipped. Therefore, when marking out the area in the stencil buffer
# to be filled in the with the reflection view, the x clip coordinate of the mirror vertices is
# negated.
#
# The layer numbers for the mirror pre- and post-reflection render materials (+/-99998) are referenced
# from C++ code for the censor-in-mirror render.
set reflectionRenderTarget "ScreenReflection"
#beginshader SimpleMirrorReflection
#description Assign this material to the mirror quad to make it reflective.
#description The mirror quad needs to be centered over the origin in its local space,
#description facing positive Y. You can use a transform bone to orient the mirror
#description however you need.
set mvAspect 1
setv4 thumbnailMirrorColor (0.5,0.6,0.75, 1)
setv4 impostorMirrorColor (0.4, 0.4, 0.4, 1)
setv4 reflectionsOffMirrorColor (0.6, 0.6, 0.6, 1)
define SimpleMirrorReflection()
material
if (viewerRenderType = $kRenderTypeShadow)
create StandardShaderShadow()
else
if (viewerRenderType = $kRenderTypeThumbnail)
create BlankMirrorMaterial(viewerRenderType $thumbnailMirrorColor)
elseif (viewerRenderType = $kRenderTypeImposter)
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
elseif (viewerRenderType = $kRenderTypePoolReflection)
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
elseif (viewerRenderType = $kRenderTypeOceanReflection)
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
else
if (not $mirrorReflectionsEnabled)
set currentType (viewerRenderType)
create BlankMirrorMaterial($currentType $reflectionsOffMirrorColor)
else
create MirrorReflectionMaterial()
endif
endif
endif
end
enddef
#endshader
define BlankMirrorMaterial(renderType mirrorColor)
# mirror shader for thumbnails. Output a single flat color.
shader
validateRenderShaderContext -viewerRenderType &renderType
pass
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClip -constantCount 4
shaderSource
vs_1_1
dcl_position v0
m4x4 oPos, v0, c0
endShaderSource
end
colorScalar &mirrorColor
stage
textureBlend select(colorScalar) select(colorScalar)
end
end
end
enddef
# shader to prep stencil buffer on the rendertarget for the mirror reflection view.
# When objects are rendered from the viewpoint of the reflection camera after this shader runs, they will
# render only to the area of the rendertarget marked out in the stencil buffer by this shader.
define MirrorReflectionMaterial()
create DetermineHardwareSupport()
# write depth into the depth buffer as seen from the main camera. Write stencil = 1
# if this is the mirror we are rendering the reflection for, and 0 otherwise.
shader -layer -9998 # this material must render first
validateRenderShaderContext -viewerRenderType $kRenderTypeMirror # reflection render
# write stencil in area occupied by mirror
if ($useSWVertexShaderPath)
pass -renderEachFrame -modifiedEachFrameHint
else
pass -renderEachFrame
endif
renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext
# test and write depth (as seen from the main camera)
depthTest true -enableDepthWrite true
# This material script command means the following:
#
# if (renderableIsTargetBounded)
# set stencil test to write 1 when depth test passes
# else
# set stencil test to write 0 when depth test passes
#
applyStencilStateForOverlappingReflections
# do not write color
#colorWriteEnable -red false -green false -blue false -alpha false
alphaBlend srcFactor(zero) add dstFactor(one)
# since we are negating clip space x below we need to prevent this quad from being culled
cullmode none
# vertex program
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClipFromParentView -constantCount 4 # set the matrices from the parent (i.e. the main view) so that the stencil is written to the right place
shaderSource
vs_1_1
dcl_position v0
; color output for debugging
def c5, 1,0,0,1
; project vertex to clip coords
m4x4 r0, v0, c0
; flip the x coordinate so the stencil is marked in the right place
mov oPos.x, -r0
mov oPos.yzw, r0
endShaderSource
end
end # pass
end # shader
# render of the mirror from the main camera. This samples from the reflection render target texture.
shader -layer 16 # this must be after all opaque objects (especially Sims), but before transparent objects and the censor compositing pass
validateRenderShaderContext -viewerRenderType $kRenderTypeNormal
pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClip -constantCount 4
bindConstants 4 -bindingID clipToViewTarget -constantCount 4
shaderSource
vs_1_1
dcl_position v0
def c8, -0.5, -0.5, 1, 1
def c9, 0.5, 0.5, 0, 0
def c10, 0.25, 0.25, 0, 0
# project vertex to clip coords
m4x4 r0, v0, c0
mov oPos, r0
# multiply 0.5 * w so homogenous divide will make it 0.5 again
mul r2, c9, r0.w
# scale projected xy by .5 and re-center so it's in 0-w range
mad r4, r0, c8, r2
# Try to get an exact texel to pixel mapping by shifting texture coordinates
# slightly.
# A texture coordinate of 0 must map to 1/2*(texture dimension) and a
# coordinate of 1 must map to (1 - 1/2*(texture dimension)).
# Note: This does not seem to eliminate the wobble on the mirror
# reflection entirely.
rcp r3.x, c4.x ;# 2/width
rcp r3.y, c5.y ;# 2/height
mov r3.zw, c9.zw ;# r3 = (2/width, 2/height, 0, 0)
mul r3, r3, c10 ;# r3 = (1/2*width, 1/2*height, 0, 0)
mad r6, r0, r3, r4
mov oT0, r6.xyww ;# move w into z so we can divide by z in the texture stage; some cards don't handle division by w correctly
endShaderSource
end
stage
textureTransformType vector3 homogeneous # divide the xy components of the texture coordinate by z
textureAddressing clamp clamp
texture $reflectionRenderTarget
textureBlend select(texture) select(texture)
end # stage
end # pass
end # shader
# this shader is in case the above case fails. This does projection per vertex.
shader -layer 16
validateRenderShaderContext -viewerRenderType $kRenderTypeNormal
pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode
shaderProgram -target vertexProgram -method assemble
bindConstants 0 -bindingID geomToClip -constantCount 4
bindConstants 4 -bindingID clipToViewTarget -constantCount 4
shaderSource
vs_1_1
dcl_position v0
def c8, -0.5, -0.5, 1, 1
def c9, 0.5, 0.5, 0, 0
def c10, 0.25, 0.25, 0, 0
# project vertex to clip coords
m4x4 r0, v0, c0
mov oPos, r0
# multiply 0.5 * w so homogenous divide will make it 0.5 again
mul r2, c9, r0.w
# scale projected xy by .5 and re-center so it's in 0-w range
mad r4, r0, c8, r2
# Try to get an exact texel to pixel mapping by shifting texture coordinates
# slightly.
# A texture coordinate of 0 must map to 1/2*(texture dimension) and a
# coordinate of 1 must map to (1 - 1/2*(texture dimension)).
# Note: This does not seem to eliminate the wobble on the mirror
# reflection entirely.
rcp r3.x, c4.x ;# 2/width
rcp r3.y, c5.y ;# 2/height
mov r3.zw, c9.zw ;# r3 = (2/width, 2/height, 0, 0)
mul r3, r3, c10 ;# r3 = (1/2*width, 1/2*height, 0, 0)
mad r1, r0, r3, r4 ; write to a temp instead of output texcoord (as above)
rcp r1.w, r1.w ; calc 1/w
mul oT0.xy, r1.w, r1.xy ; project per vertex since the intel HW (and maybe others) can't do it per pixel.
endShaderSource
end #shader
stage
textureAddressing clamp clamp
texture $reflectionRenderTarget
textureBlend select(texture) select(texture)
end # stage
end # pass
end #shader
enddef
# material to clear stencil buffer and set depth buffer to "correct" value on rendertarget.
# The depth value is the depth as seen from the main camera.
define MirrorBackClearStencilAndSetDepth()
material
# AV TODO: this material doesn't do anything now, so it should be removed (from go2sco as well)
shader -layer 9998
end # shader
end # material
enddef
# used by the mirror render. Sets z to the specified value on the entire reflection render target.
define SetSpecifiedZOnMirrorRTT(zValue)
material
shader
pass
renderClipSpaceRect
renderTarget $reflectionRenderTarget -setViewport fullRenderTargetViewport
# turn off stencil test
stencil false
# depth test accept always, write depth
depthTest true -enableDepthWrite true
depthTestFunction accept
# do not write color
alphaBlend srcFactor(zero) add dstFactor(one)
# vertex program
shaderProgram -target vertexProgram -method compile -version 1_1
bindConstants 0 -bindingID immediateData -data (0,0,&zValue, 0)
shaderSource
float4 zValue : register(c0);
void VertexMain(float4 position : POSITION, out float4 oPosition : POSITION)
{
oPosition = position;
oPosition.z = zValue.z; // set specified z value
}
endShaderSource
end
end # pass
end # shader
end # material
enddef
# used by the mirror camera for dirty rect rendering
define SetNearZOnMirrorRTT()
create SetSpecifiedZOnMirrorRTT(0)
enddef
# used by the mirror camera for non-dirty rect rendering
define SetFarZOnMirrorRTT()
create SetSpecifiedZOnMirrorRTT(1)
enddef
# used by the censor render in the mirror. Sets stencil on the entire censor render target to 1.
define SetStencilOnCensorRTT()
material
shader
pass
renderClipSpaceRect
# set stencil to 1 everywhere
stencil true
stencilFunction accept -refValue 1
stencilOperation -onPass writeRef
# depth test accept, do not write depth
depthTest false -enableDepthWrite false
depthTestFunction accept
# do not write color
alphaBlend srcFactor(zero) add dstFactor(one)
shaderProgram -target vertexProgram -method assemble
shaderSource
vs_1_1
dcl_position v0
mov oPos, v0
endShaderSource
end
stage
textureBlend select(colorScalar) select(colorScalar)
end
end # pass
end # shader
end # material
enddef
# common state for all objects rendered with the reflection camera
defaultState $kRenderTypeMirror # reflection render
# stencil test passes only in the areas where the reference value has been written
stencil true
stencilFunction acceptIfEqual -refValue 1
stencilOperation -onPass noWrite
end
if (not varExists(isContentViewer))
# only render where the stencil is zero in turbo rect mode
defaultState $kRenderTypeNormal # Stencil
stencil true
stencilFunction acceptIfEqual -refValue 0
stencilOperation -onPass noWrite
end
endif
# Begin DO NOT MODIFY THIS BLOCK
# Material instances bound to reflective surfaces.
# Note: The following material instances are bound to exported resources and accessed
# by runtime code. They CANNOT be deleted without changing the export program.
materialDefinition simple_mirror_reflection
setDefinition SimpleMirrorReflection
end
materialDefinition MirrorBackPostReflectionRenderMaterial
setDefinition MirrorBackClearStencilAndSetDepth
end
# bound to the bounding mesh around the mirror plane that prevents the mirror from being
# undesirably culled
materialDefinition MirrorBoundingBoxMaterial
setDefinition Null
end
# used to clear the mirror render target to z = 0 wherever the stencil has been set to 1
materialDefinition ZClearToNearPlaneMaterial
setDefinition SetNearZOnMirrorRTT
end
# used to clear the mirror render target to z = 0 wherever the stencil has been set to 1
materialDefinition ZClearToFarPlaneMaterial
setDefinition SetFarZOnMirrorRTT
end
# bound to a compositing pass geometry that preps the stencil buffer for rendering into
# the censor render target from the mirror view
materialDefinition CensorInMirrorStencilPrepMaterial
setDefinition SetStencilOnCensorRTT
end
# End DO NOT MODIFY THIS BLOCK