|
@@ -12,34 +12,53 @@ Class Renderer
|
|
|
Return _shaderDefs
|
|
|
End
|
|
|
|
|
|
- #rem monkeydoc Size of cascading shadow map texture.
|
|
|
+ #rem monkeydoc Size of the cascaded shadow map texture.
|
|
|
|
|
|
Must be a power of 2 size. Defaults to 1024.
|
|
|
|
|
|
#end
|
|
|
- Property CSMTextureSize:Float()
|
|
|
+ Property CSMTextureSize:Int()
|
|
|
|
|
|
Return _csmSize
|
|
|
|
|
|
- Setter( size:Float )
|
|
|
+ Setter( size:Int )
|
|
|
Assert( Log2( size )=Floor( Log2( size ) ),"CSMTextureSize must be a power of 2" )
|
|
|
|
|
|
_csmSize=size
|
|
|
End
|
|
|
|
|
|
- #rem monkeydoc Array containing the Z depths of the cascading shadow map frustum splits.
|
|
|
+ #rem monkeydoc Array containing the cascaded shadow map frustum splits for directional light shadows.
|
|
|
|
|
|
- Defaults to Float[]( 1,20,60,180,1000 ).
|
|
|
+ Defaults to Float[]( 1.0/64.0,1.0/16.0,1.0/4.0 )
|
|
|
+
|
|
|
+ Must have length 3.
|
|
|
|
|
|
#end
|
|
|
- Property CSMSplitDepths:Float[]()
|
|
|
+ Property CSMSplits:Float[]()
|
|
|
|
|
|
Return _csmSplits
|
|
|
-
|
|
|
+
|
|
|
Setter( splits:Float[] )
|
|
|
- Assert( splits.Length=5,"CSMSplitDepths array must have 5 elements" )
|
|
|
+ Assert( splits.Length=3,"CSMSplits array must have 3 elements" )
|
|
|
+
|
|
|
+ _csmSplits=splits.Slice( 0 )
|
|
|
+ End
|
|
|
+
|
|
|
+ #rem monkeydoc Size of the cube texture used for point light shadow mapping.
|
|
|
+
|
|
|
+ Must be a power of 2.
|
|
|
+
|
|
|
+ Defaults to 1024.
|
|
|
+
|
|
|
+ #end
|
|
|
+ Property PSMTextureSize:Int()
|
|
|
|
|
|
- _csmSplits=splits
|
|
|
+ Return _psmSize
|
|
|
+
|
|
|
+ Setter( size:Int )
|
|
|
+ Assert( Log2( size )=Floor( Log2( size ) ),"PSMTextureSize must be a power of 2" )
|
|
|
+
|
|
|
+ _psmSize=size
|
|
|
End
|
|
|
|
|
|
#rem monkeydoc Gets the current renderer.
|
|
@@ -49,21 +68,22 @@ Class Renderer
|
|
|
Global _current:Renderer
|
|
|
|
|
|
If Not _current
|
|
|
+
|
|
|
+ Local hasDepth:=Int( App.GetConfig( "GL_depth_buffer_enabled","0" ) )<>0
|
|
|
+
|
|
|
Select App.GetConfig( "mojo3d_renderer","" )
|
|
|
Case "deferred"
|
|
|
_current=New DeferredRenderer
|
|
|
+ Case "forward-direct"
|
|
|
+ _current=New ForwardRenderer( True )
|
|
|
Case "forward"
|
|
|
_current=New ForwardRenderer( False )
|
|
|
Default
|
|
|
-#If __DESKTOP_TARGET__
|
|
|
- If glexts.GL_draw_buffers
|
|
|
- _current=New DeferredRenderer
|
|
|
- Else
|
|
|
- _current=New ForwardRenderer( True )
|
|
|
- Endif
|
|
|
+#If Not __MOBILE_TARGET__
|
|
|
+ If glexts.GL_draw_buffers _current=New DeferredRenderer
|
|
|
#Endif
|
|
|
End
|
|
|
- If Not _current _current=New ForwardRenderer( False )
|
|
|
+ If Not _current _current=New ForwardRenderer( hasDepth )
|
|
|
Endif
|
|
|
|
|
|
Return _current
|
|
@@ -83,12 +103,20 @@ Class Renderer
|
|
|
|
|
|
OnValidateSize( size )
|
|
|
|
|
|
- ValidateCSM()
|
|
|
+ ValidateShadowMaps()
|
|
|
+
|
|
|
+ _csmSplitDepths[0]=camera.Near
|
|
|
+ For Local i:=1 Until 4
|
|
|
+ _csmSplitDepths[i]=camera.Near+_csmSplits[i-1]*(camera.Far-camera.Near)
|
|
|
+ Next
|
|
|
+ _csmSplitDepths[4]=camera.Far
|
|
|
|
|
|
_runiforms.SetFloat( "Time",Now() )
|
|
|
+
|
|
|
+ _runiforms.SetTexture( "ShadowCSMTexture",_csmTexture )
|
|
|
+ _runiforms.SetVec4f( "ShadowCSMSplits",New Vec4f( _csmSplitDepths[1],_csmSplitDepths[2],_csmSplitDepths[3],_csmSplitDepths[4] ) )
|
|
|
|
|
|
- _runiforms.SetTexture( "ShadowTexture",_csmTexture )
|
|
|
- _runiforms.SetVec4f( "ShadowSplits",New Vec4f( _csmSplits[1],_csmSplits[2],_csmSplits[3],_csmSplits[4] ) )
|
|
|
+ _runiforms.SetTexture( "ShadowCubeTexture",_psmTexture )
|
|
|
|
|
|
'***** Set render scene *****
|
|
|
|
|
@@ -143,7 +171,7 @@ Class Renderer
|
|
|
|
|
|
_renderCamera=Null
|
|
|
|
|
|
- _renderScene=null
|
|
|
+ _renderScene=Null
|
|
|
End
|
|
|
|
|
|
Protected
|
|
@@ -157,6 +185,14 @@ Class Renderer
|
|
|
Method New( shaderDefs:String )
|
|
|
|
|
|
_shaderDefs=shaderDefs
|
|
|
+
|
|
|
+ _rgbaDepthTextures=False 'True' Not glexts.GL_depth_texture
|
|
|
+
|
|
|
+' If Int( App.GetConfig( "mojod3_rgba_depth_textures","" ) ) _rgbaDepthTextures=True
|
|
|
+
|
|
|
+ Print "RGBA depth textures="+Int( _rgbaDepthTextures )
|
|
|
+
|
|
|
+ If _rgbaDepthTextures _shaderDefs+="~nMX2_RGBADEPTHTEXTURES"
|
|
|
|
|
|
_device=New GraphicsDevice( 0,0 )
|
|
|
|
|
@@ -166,12 +202,31 @@ Class Renderer
|
|
|
_device.BindUniformBlock( _runiforms )
|
|
|
_device.BindUniformBlock( _iuniforms )
|
|
|
|
|
|
- _csmSplits=New Float[]( 1,20,60,180,1000 )
|
|
|
-
|
|
|
_defaultEnv=Texture.Load( "asset::textures/env_default.jpg",TextureFlags.FilterMipmap|TextureFlags.Cubemap )
|
|
|
|
|
|
_skyboxShader=Shader.Open( "skybox",_shaderDefs )
|
|
|
-
|
|
|
+
|
|
|
+ _psmFaceTransforms=New Mat3f[](
|
|
|
+ New Mat3f( 0,0,+1, 0,-1,0, -1, 0,0 ), '+X
|
|
|
+ New Mat3f( 0,0,-1, 0,-1,0, +1, 0,0 ), '-X
|
|
|
+ New Mat3f( +1,0, 0, 0,0,+1, 0,+1,0 ), '+Y
|
|
|
+ New Mat3f( +1,0, 0, 0,0,-1, 0,-1,0 ), '-Y
|
|
|
+ New Mat3f( +1,0, 0, 0,-1,0, 0,0,+1 ), '+Z
|
|
|
+ New Mat3f( -1,0, 0, 0,-1,0, 0,0,-1 ) ) '-Z
|
|
|
+
|
|
|
+ #rem
|
|
|
+ Matxf tforms[]={
|
|
|
+ { {0,0,+1},{0,-1,0},{-1,0,0},{0,0,0} }, //+X
|
|
|
+ { {0,0,-1},{0,-1,0},{+1,0,0},{0,0,0} }, //-X
|
|
|
+ { {+1,0,0},{0,0,+1},{0,+1,0},{0,0,0} }, //+Y test me!
|
|
|
+ { {+1,0,0},{0,0,-1},{0,-1,0},{0,0,0} }, //-Y
|
|
|
+ { {+1,0,0},{0,-1,0},{0,0,+1},{0,0,0} }, //+Z
|
|
|
+ { {-1,0,0},{0,-1,0},{0,0,-1},{0,0,0} } //-Z
|
|
|
+ };
|
|
|
+
|
|
|
+ #end
|
|
|
+
|
|
|
+
|
|
|
End
|
|
|
|
|
|
Property Device:GraphicsDevice()
|
|
@@ -273,24 +328,28 @@ Class Renderer
|
|
|
_device.RenderTarget=_csmTarget
|
|
|
_device.Viewport=New Recti( 0,0,_csmTarget.Size )
|
|
|
_device.Scissor=_device.Viewport
|
|
|
- _device.ColorMask=ColorMask.None
|
|
|
+ _device.ColorMask=ColorMask.All
|
|
|
_device.DepthMask=True
|
|
|
- _device.Clear( Null,1.0 )
|
|
|
+ _device.Clear( Color.White,1.0 )
|
|
|
+' _device.ColorMask=ColorMask.None
|
|
|
+' _device.DepthMask=True
|
|
|
+' _device.Clear( Null,1.0 )
|
|
|
|
|
|
_device.DepthFunc=DepthFunc.LessEqual
|
|
|
_device.BlendMode=BlendMode.Opaque
|
|
|
_device.CullMode=CullMode.Back
|
|
|
- _device.RenderPass=4
|
|
|
+ _device.RenderPass=16
|
|
|
|
|
|
Local invLightMatrix:=light.InverseMatrix
|
|
|
+
|
|
|
Local viewLight:=invLightMatrix * _renderCamera.Matrix
|
|
|
|
|
|
- For Local i:=0 Until _csmSplits.Length-1
|
|
|
+ For Local i:=0 Until _csmSplitDepths.Length-1
|
|
|
|
|
|
- Local znear:=_csmSplits[i]
|
|
|
- Local zfar:=_csmSplits[i+1]
|
|
|
+ Local znear:=_csmSplitDepths[i]
|
|
|
+ Local zfar:=_csmSplitDepths[i+1]
|
|
|
|
|
|
- Local splitProj:=Mat4f.Perspective( _renderCamera.Fov,_renderCamera.Aspect,znear,zfar )
|
|
|
+ Local splitProj:=Mat4f.Perspective( _renderCamera.FOV,_renderCamera.Aspect,znear,zfar )
|
|
|
|
|
|
Local invSplitProj:=-splitProj
|
|
|
|
|
@@ -325,9 +384,7 @@ Class Renderer
|
|
|
|
|
|
_device.Scissor=_device.Viewport
|
|
|
|
|
|
- If light.ShadowsEnabled
|
|
|
- RenderRenderOps( _renderQueue.ShadowOps,invLightMatrix,lightProj )
|
|
|
- Endif
|
|
|
+ RenderRenderOps( _renderQueue.ShadowOps,invLightMatrix,lightProj )
|
|
|
|
|
|
Next
|
|
|
|
|
@@ -336,19 +393,74 @@ Class Renderer
|
|
|
_device.Scissor=t_scissor
|
|
|
End
|
|
|
|
|
|
+ Method RenderPointShadows( light:Light )
|
|
|
+
|
|
|
+ 'Perhaps use a different device for CSM...?
|
|
|
+ '
|
|
|
+ Local t_rtarget:=_device.RenderTarget
|
|
|
+ Local t_viewport:=_device.Viewport
|
|
|
+ Local t_scissor:=_device.Scissor
|
|
|
+
|
|
|
+ _device.Viewport=New Recti( 0,0,_psmTexture.Size )
|
|
|
+ _device.Scissor=_device.Viewport
|
|
|
+ _device.ColorMask=ColorMask.All
|
|
|
+ _device.DepthMask=True
|
|
|
+ _device.DepthFunc=DepthFunc.LessEqual
|
|
|
+ '
|
|
|
+ _device.BlendMode=BlendMode.Opaque
|
|
|
+ _device.CullMode=CullMode.Back
|
|
|
+ _device.RenderPass=17
|
|
|
+
|
|
|
+ Local lightProj:=Mat4f.Frustum( -1,+1,-1,+1,1,light.Range )
|
|
|
+
|
|
|
+ Local invLightMatrix:=light.InverseMatrix
|
|
|
+
|
|
|
+ Local viewLight:=invLightMatrix * _renderCamera.Matrix
|
|
|
+
|
|
|
+ _runiforms.SetFloat( "LightRange",light.Range )
|
|
|
+ _runiforms.SetMat4f( "ShadowMatrix0",viewLight )
|
|
|
+
|
|
|
+ For Local i:=0 Until 6
|
|
|
+
|
|
|
+ _device.RenderTarget=_psmTargets[i]
|
|
|
+ _device.Clear( Color.White,1.0 )
|
|
|
+
|
|
|
+ Local viewMatrix:=New AffineMat4f( _psmFaceTransforms[i] ) * invLightMatrix
|
|
|
+
|
|
|
+ RenderRenderOps( _renderQueue.ShadowOps,viewMatrix,lightProj )
|
|
|
+
|
|
|
+ Next
|
|
|
+
|
|
|
+ _device.RenderTarget=t_rtarget
|
|
|
+ _device.Viewport=t_viewport
|
|
|
+ _device.Scissor=t_scissor
|
|
|
+ End
|
|
|
+
|
|
|
Private
|
|
|
|
|
|
+ Field _rgbaDepthTextures:=False
|
|
|
+
|
|
|
Field _shaderDefs:String
|
|
|
|
|
|
Field _device:GraphicsDevice
|
|
|
Field _runiforms:UniformBlock
|
|
|
Field _iuniforms:UniformBlock
|
|
|
+
|
|
|
+ Field _skyboxShader:Shader
|
|
|
|
|
|
- Field _csmSize:=4096
|
|
|
- Field _csmSplits:=New Float[]( 1,20,60,180,1000 )
|
|
|
+ Field _psmFaceTransforms:Mat3f[]
|
|
|
+
|
|
|
+ Field _csmSize:=2048
|
|
|
+ Field _csmSplits:=New Float[]( 1.0/64.0,1.0/16.0,1.0/4.0 )
|
|
|
+ Field _csmSplitDepths:=New Float[5]
|
|
|
Field _csmTexture:Texture
|
|
|
+ Field _csmDepth:Texture
|
|
|
Field _csmTarget:RenderTarget
|
|
|
- Field _skyboxShader:Shader
|
|
|
+
|
|
|
+ Field _psmSize:=2048
|
|
|
+ Field _psmTexture:Texture
|
|
|
+ Field _psmDepth:Texture
|
|
|
+ Field _psmTargets:=New RenderTarget[6]
|
|
|
|
|
|
Field _defaultEnv:Texture
|
|
|
|
|
@@ -359,16 +471,46 @@ Class Renderer
|
|
|
Field _renderScene:Scene
|
|
|
Field _renderCamera:Camera
|
|
|
|
|
|
- Method ValidateCSM()
|
|
|
+ Method ValidateShadowMaps()
|
|
|
|
|
|
If Not _csmTexture Or _csmSize<>_csmTexture.Size.x
|
|
|
|
|
|
- SafeDiscard( _csmTexture )
|
|
|
SafeDiscard( _csmTarget )
|
|
|
+ SafeDiscard( _csmTexture )
|
|
|
+ SafeDiscard( _csmDepth )
|
|
|
|
|
|
- _csmTexture=New Texture( _csmSize,_csmSize,PixelFormat.Depth32F,TextureFlags.Dynamic )
|
|
|
- _csmTarget=New RenderTarget( Null,_csmTexture )
|
|
|
+ If _rgbaDepthTextures
|
|
|
+ _csmTexture=New Texture( _csmSize,_csmSize,PixelFormat.RGBA8,TextureFlags.Dynamic )
|
|
|
+ _csmDepth=New Texture( _csmSize,_csmSize,PixelFormat.Depth32F,TextureFlags.Dynamic )
|
|
|
+ _csmTarget=New RenderTarget( New Texture[]( _csmTexture ),_csmDepth )
|
|
|
+ Else
|
|
|
+ _csmTexture=New Texture( _csmSize,_csmSize,PixelFormat.Depth32F,TextureFlags.Dynamic )
|
|
|
+ _csmTarget=New RenderTarget( Null,_csmTexture )
|
|
|
+ _csmDepth=Null
|
|
|
+ Endif
|
|
|
+
|
|
|
+ Endif
|
|
|
+
|
|
|
+ If Not _psmTexture Or _psmSize*2>_psmTexture.Size.x
|
|
|
+
|
|
|
+ SafeDiscard( _psmTexture )
|
|
|
+ SafeDiscard( _psmDepth )
|
|
|
+ For Local i:=0 Until 6
|
|
|
+ SafeDiscard( _psmTargets[i] )
|
|
|
+ Next
|
|
|
+
|
|
|
+ Local size:=_psmSize*2
|
|
|
|
|
|
+ _psmTexture=New Texture( size,size,PixelFormat.RGBA8,TextureFlags.Cubemap|TextureFlags.Dynamic )
|
|
|
+' _psmTexture=New Texture( size,size,PixelFormat.Depth32F,TextureFlags.Cubemap|TextureFlags.Dynamic )
|
|
|
+ _psmDepth=New Texture( size,size,PixelFormat.Depth32F,TextureFlags.Dynamic )
|
|
|
+ For Local i:=0 Until 6
|
|
|
+ Local face:=_psmTexture.GetCubeFace( Cast<CubeFace>( i ) )
|
|
|
+ _psmTargets[i]=New RenderTarget( New Texture[]( face ),_psmDepth )
|
|
|
+ Next
|
|
|
+
|
|
|
+ glCheck()
|
|
|
+
|
|
|
Endif
|
|
|
|
|
|
End
|