Difference between revisions of "ShaderMirror"
From SimsWiki
(EP0-TS2) |
|||
Line 1: | Line 1: | ||
<pre> | <pre> | ||
− | + | ||
+ | EP0-TS2 | ||
0xCD7FE87A | 0xCD7FE87A | ||
0x1C0532FA | 0x1C0532FA | ||
Line 29: | Line 30: | ||
set mvAspect 1 | set mvAspect 1 | ||
− | + | ||
− | + | ||
− | + | ||
define SimpleMirrorReflection() | define SimpleMirrorReflection() | ||
material | material | ||
Line 38: | Line 37: | ||
else | else | ||
if (viewerRenderType = $kRenderTypeThumbnail) | if (viewerRenderType = $kRenderTypeThumbnail) | ||
− | create BlankMirrorMaterial( | + | create BlankMirrorMaterial($kRenderTypeThumbnail) |
− | + | ||
− | + | ||
else | else | ||
if (not $mirrorReflectionsEnabled) | if (not $mirrorReflectionsEnabled) | ||
set currentType (viewerRenderType) | set currentType (viewerRenderType) | ||
− | create BlankMirrorMaterial($currentType | + | create BlankMirrorMaterial($currentType) |
else | else | ||
create MirrorReflectionMaterial() | create MirrorReflectionMaterial() | ||
Line 54: | Line 51: | ||
#endshader | #endshader | ||
− | define BlankMirrorMaterial(renderType | + | define BlankMirrorMaterial(renderType) |
# mirror shader for thumbnails. Output a single flat color. | # mirror shader for thumbnails. Output a single flat color. | ||
shader | shader | ||
Line 69: | Line 66: | ||
end | end | ||
− | colorScalar | + | colorScalar (0.5,0.6,0.75, 1) |
stage | stage | ||
textureBlend select(colorScalar) select(colorScalar) | textureBlend select(colorScalar) select(colorScalar) | ||
Line 81: | Line 78: | ||
# render only to the area of the rendertarget marked out in the stencil buffer by this shader. | # render only to the area of the rendertarget marked out in the stencil buffer by this shader. | ||
define MirrorReflectionMaterial() | define MirrorReflectionMaterial() | ||
− | + | ||
# write depth into the depth buffer as seen from the main camera. Write stencil = 1 | # 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. | # if this is the mirror we are rendering the reflection for, and 0 otherwise. | ||
Line 88: | Line 85: | ||
# write stencil in area occupied by mirror | # write stencil in area occupied by mirror | ||
− | + | pass -renderEachFrame | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext | renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext | ||
Line 137: | Line 130: | ||
# render of the mirror from the main camera. This samples from the reflection render target texture. | # render of the mirror from the main camera. This samples from the reflection render target texture. | ||
− | shader -layer | + | shader -layer 6 # this must be after all opaque objects (especially Sims), but before transparent objects and the censor compositing pass |
validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | ||
Line 190: | Line 183: | ||
# this shader is in case the above case fails. This does projection per vertex. | # this shader is in case the above case fails. This does projection per vertex. | ||
− | shader -layer | + | shader -layer 6 |
validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | validateRenderShaderContext -viewerRenderType $kRenderTypeNormal | ||
− | + | ||
pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode | pass -modifiedEachFrameHint # we want the mirrors to be rendered every frame even in dirty rect mode | ||
Line 351: | Line 344: | ||
end | end | ||
− | + | # only render where the stencil is zero in turbo rect mode | |
− | + | defaultState $kRenderTypeNormal # Stencil | |
− | + | stencil true | |
− | + | stencilFunction acceptIfEqual -refValue 0 | |
− | + | stencilOperation -onPass noWrite | |
− | + | end | |
− | + | ||
− | + | ||
# Begin DO NOT MODIFY THIS BLOCK | # Begin DO NOT MODIFY THIS BLOCK | ||
Line 398: | Line 390: | ||
# End DO NOT MODIFY THIS BLOCK | # End DO NOT MODIFY THIS BLOCK | ||
− | </pre> | + | </pre> |
Revision as of 04:23, 19 March 2007
EP0-TS2 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 define SimpleMirrorReflection() material if (viewerRenderType = $kRenderTypeShadow) create StandardShaderShadow() else if (viewerRenderType = $kRenderTypeThumbnail) create BlankMirrorMaterial($kRenderTypeThumbnail) else if (not $mirrorReflectionsEnabled) set currentType (viewerRenderType) create BlankMirrorMaterial($currentType) else create MirrorReflectionMaterial() endif endif endif end enddef #endshader define BlankMirrorMaterial(renderType) # 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 (0.5,0.6,0.75, 1) 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() # 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 pass -renderEachFrame 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 6 # 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 6 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 # only render where the stencil is zero in turbo rect mode defaultState $kRenderTypeNormal # Stencil stencil true stencilFunction acceptIfEqual -refValue 0 stencilOperation -onPass noWrite end # 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