Difference between revisions of "ShaderMirror"

From SimsWiki
Jump to: navigation, search
(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"
  
set mvAspect 1
+
#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)
+
if (viewerRenderType = $kRenderTypeThumbnail)
            create BlankMirrorMaterial($kRenderTypeThumbnail)
+
create BlankMirrorMaterial(viewerRenderType $thumbnailMirrorColor)
        else             
+
elseif (viewerRenderType = $kRenderTypeImposter)
            if (not $mirrorReflectionsEnabled)
+
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
              set currentType (viewerRenderType)
+
elseif (viewerRenderType = $kRenderTypePoolReflection)
              create BlankMirrorMaterial($currentType)
+
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
            else
+
elseif (viewerRenderType = $kRenderTypeOceanReflection)
              create MirrorReflectionMaterial()
+
create BlankMirrorMaterial(viewerRenderType $impostorMirrorColor)
            endif             
+
else             
        endif         
+
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 (0.5,0.6,0.75, 1)
+
             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 6
+
      # 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 6      
+
      # 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))
  stencil true
+
  # only render where the stencil is zero in turbo rect mode
  stencilFunction acceptIfEqual -refValue 0
+
  defaultState $kRenderTypeNormal # Stencil 
  stencilOperation -onPass noWrite
+
      stencil true
end
+
      stencilFunction acceptIfEqual -refValue 0
 
+
      stencilOperation -onPass noWrite
#---------------------------------------------------------------------------------------------------------------#
+
 
+
define TransparentMirrorReflection()
+
  material
+
      if (viewerRenderType = $kRenderTypeShadow)
+
        create StandardShaderShadow()
+
      else
+
        if (viewerRenderType = $kRenderTypeThumbnail)
+
            create TransparentBlankMirrorMaterial($kRenderTypeThumbnail)
+
        else           
+
            if (not $mirrorReflectionsEnabled)
+
              set currentType (viewerRenderType)
+
              create TransparentBlankMirrorMaterial($currentType)
+
            else
+
              create TransparentMirrorReflectionMaterial()
+
            endif           
+
        endif       
+
      endif
+
 
   end
 
   end
enddef
+
endif
  
define TransparentBlankMirrorMaterial(renderType)
+
# Begin DO NOT MODIFY THIS BLOCK
      shader
+
# Material instances bound to reflective surfaces.
        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,0,0) 0.5
+
            stage
+
              textureBlend select(colorScalar) select(colorScalar)
+
            end           
+
        end
+
      end     
+
enddef
+
 
+
define TransparentMirrorReflectionMaterial()
+
     
+
      shader -layer -9998  # this material must render first
+
        validateRenderShaderContext -viewerRenderType $kRenderTypeMirror  # reflection render
+
 
+
        pass -renderEachFrame
+
            renderTarget $reflectionRenderTarget -setViewport viewportFromParentRenderContext
+
 
+
            depthTest true -enableDepthWrite true
+
 
+
            applyStencilStateForOverlappingReflections
+
 
+
            alphaBlend srcFactor(zero) add dstFactor(one)
+
 
+
            cullmode none
+
 
+
            shaderProgram -target vertexProgram -method assemble           
+
              bindConstants 0 -bindingID geomToClipFromParentView -constantCount 4
+
              shaderSource
+
                  vs_1_1
+
                  dcl_position v0
+
                  def c5, 1,0,0,1
+
                  m4x4 r0,  v0,  c0
+
                  mov oPos.x,  -r0
+
                  mov oPos.yzw, r0                 
+
              endShaderSource
+
            end
+
        end
+
      end
+
 
+
      shader -layer 6
+
        validateRenderShaderContext -viewerRenderType $kRenderTypeNormal
+
        pass -modifiedEachFrameHint
+
            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
+
                  m4x4 r0,  v0,  c0
+
                  mov oPos, r0
+
                  mul r2, c9, r0.w
+
                  mad r4, r0, c8, r2
+
                  rcp r3.x, c4.x                                 
+
                  rcp r3.y, c5.y
+
                  mov r3.zw, c9.zw
+
                  mul r3, r3, c10
+
                  mad r6, r0, r3, r4
+
                  mov oT0, r6.xyww
+
              endShaderSource             
+
            end
+
 
+
            alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
+
            depthTest true -enableDepthWrite false
+
            colorScalar (0,0,0) 0.25
+
 
+
            stage
+
              textureTransformType vector3 homogeneous
+
              textureAddressing clamp clamp
+
              texture $reflectionRenderTarget
+
              textureBlend select(texture) select(colorScalar)
+
            end
+
                     
+
        end
+
      end
+
     
+
      shader -layer 6     
+
        validateRenderShaderContext -viewerRenderType $kRenderTypeNormal
+
        pass -modifiedEachFrameHint
+
            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
+
                  m4x4 r0,  v0,  c0
+
                  mov oPos, r0
+
                  mul r2, c9, r0.w
+
                  mad r4, r0, c8, r2
+
                  rcp r3.x, c4.x                                 
+
                  rcp r3.y, c5.y
+
                  mov r3.zw, c9.zw
+
                  mul r3, r3, c10
+
                  mad r1, r0, r3, r4
+
                  rcp r1.w, r1.w
+
                  mul oT0.xy, r1.w, r1.xy
+
              endShaderSource             
+
            end
+
 
+
            alphaBlend srcFactor(srcAlpha) add dstFactor(invSrcAlpha)
+
            depthTest true -enableDepthWrite false
+
            colorScalar (0,0,0) 0.25
+
 
+
            stage
+
              textureAddressing clamp clamp
+
              texture $reflectionRenderTarget
+
              textureBlend select(texture) select(colorScalar)
+
            end
+
           
+
        end
+
      end
+
enddef
+
 
+
#---------------------------------------------------------------------------------------------------------------#
+
 
+
materialDefinition transparent_mirror_reflection
+
  setDefinition TransparentMirrorReflection
+
end
+
  
#---------------------------------------------------------------------------------------------------------------#
+
# 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 00: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

Personal tools
Namespaces

Variants
Actions
Navigation
game select
Toolbox