renderer.monkey2 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. Namespace mojo3d
  2. #rem monkeydoc The mojo3d Renderer class.
  3. A renderer is an object that renders scenes. There is normally only ever one renderer created and it is created for you automatically when required so you don't normally need to worry about renderers at all.
  4. When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be used to control the type of renderer created. Use "deferred" to create a deferred renderer and "foward" to create a forward renderer. See [[std:std.filesystem.SetConfig|SetConfig]] for more information about config settings. By default, a deferred renderer is created for desktop and web targets and a forward renderer for mobile targets.
  5. #end
  6. Class Renderer
  7. #rem monkeydoc Creates a new renderer.
  8. When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be used to control the type of renderer created. Use "deferred" to create a deferred renderer and "foward" to create a forward renderer. See [[std:std.filesystem.SetConfig|SetConfig]] for more information about config settings. By default, a deferred renderer is created for desktop and web targets and a forward renderer for mobile targets.
  9. #end
  10. Method New()
  11. If Not _current _current=Self
  12. _direct=False
  13. _deferred=False
  14. Local cfg:=GetConfig( "MOJO3D_RENDERER" )
  15. Select cfg
  16. Case "deferred"
  17. _deferred=True
  18. Case "forward"
  19. _deferred=False
  20. Case ""
  21. #If __DESKTOP_TARGET__ Or __WEB_TARGET__
  22. _deferred=True
  23. #else
  24. _deferred=False
  25. #endif
  26. Default
  27. RuntimeError( "Unrecognized MOJO3D_RENDERER config setting value '"+cfg+"'" )
  28. End
  29. Print "GL_VERSION="+opengl.glGetString( opengl.GL_VERSION )
  30. If _deferred
  31. Print "Renderer is using deferred rendering"
  32. Else
  33. Print "Renderer is using forward rendering"
  34. Endif
  35. If _deferred _defs="MX2_DEFERREDRENDERER" Else _defs="MX2_FORWARDRENDERER"
  36. _defs+=";MX2_LINEAROUTPUT"
  37. End
  38. #rem monkeydoc True if renderer is using deferred rendering.
  39. #end
  40. Property Deferred:Bool()
  41. Return _deferred
  42. End
  43. #rem monkeydoc @hidden
  44. #end
  45. Property ShaderDefs:String()
  46. Return _defs
  47. End
  48. #rem monkeydoc Size of the cascaded shadow map texture.
  49. Must be a power of 2 size. Defaults to 2048.
  50. #end
  51. Property CSMTextureSize:Int()
  52. Return _csmSize
  53. Setter( size:Int )
  54. Assert( Log2( size )=Floor( Log2( size ) ),"CSMTextureSize must be a power of 2" )
  55. _csmSize=size
  56. End
  57. #rem monkeydoc Size of the cube texture used for point light shadow mapping.
  58. Must be a power of 2. Defaults to 2048.
  59. #end
  60. Property PSMTextureSize:Int()
  61. Return _psmSize
  62. Setter( size:Int )
  63. Assert( Log2( size )=Floor( Log2( size ) ),"PSMTextureSize must be a power of 2" )
  64. _psmSize=size
  65. End
  66. #rem monkeydoc Gets the current renderer.
  67. If there is no current renderer and new renderer is created.
  68. #end
  69. Function GetCurrent:Renderer()
  70. If Not _current New Renderer
  71. Return _current
  72. End
  73. Method Render( target:RenderTarget,targetSize:Vec2i,viewport:Recti,scene:Scene,viewMatrix:AffineMat4f,projMatrix:Mat4f,near:Float,far:Float ) Virtual
  74. Init()
  75. ValidateCSMShadows()
  76. ValidatePSMShadows()
  77. SetOutputRenderTarget( target,targetSize,viewport )
  78. SetScene( scene )
  79. SetCamera( viewMatrix,projMatrix,near,far )
  80. RenderBackground()
  81. RenderOpaque()
  82. RenderTransparent()
  83. RenderPostEffects()
  84. RenderCopy()
  85. End
  86. Method RenderBackground()
  87. If _scene.SkyTexture
  88. _gdevice.ColorMask=ColorMask.None
  89. _gdevice.DepthMask=True
  90. _gdevice.Clear( Null,1.0 )
  91. _gdevice.ColorMask=ColorMask.All
  92. _gdevice.DepthMask=False
  93. _gdevice.DepthFunc=DepthFunc.Always
  94. _gdevice.BlendMode=BlendMode.Opaque
  95. _gdevice.CullMode=CullMode.None
  96. _gdevice.Shader=_skyboxShader
  97. _gdevice.RenderPass=0
  98. RenderQuad()
  99. Else
  100. _gdevice.ColorMask=ColorMask.All
  101. _gdevice.DepthMask=True
  102. Local color:=_scene.ClearColor
  103. color.r=Pow( color.r,2.2 )
  104. color.g=Pow( color.g,2.2 )
  105. color.b=Pow( color.b,2.2 )
  106. _gdevice.Clear( color,1.0 )
  107. Endif
  108. End
  109. Method RenderDeferredLighting( light:Light )
  110. Local renderPass:=0
  111. Local lvmatrix:=_viewMatrix * light.Matrix
  112. Local qscale:=New Vec2f( 1 )
  113. Local qtrans:=New Vec2f( 0 )
  114. Select light.Type
  115. Case LightType.Directional
  116. If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  117. renderPass|=4
  118. Case LightType.Point
  119. Local r:=light.Range
  120. If lvmatrix.t.z<-r
  121. ' Print "clip1, z="+lvmatrix.t.z
  122. Return
  123. Endif
  124. If lvmatrix.t.z>r
  125. Local box:=New Boxf( lvmatrix.t+New Vec3f( -r ),lvmatrix.t+New Vec3f( r ) )
  126. Local cmin:=New Vec2f( 1 ),cmax:=New Vec2f( 0 )
  127. For Local i:=0 Until 8
  128. Local v:=(_projMatrix * box.Corner( i ) ).XY * 0.5 + 0.5
  129. cmin.x=Min( cmin.x,v.x );cmin.y=Min( cmin.y,v.y )
  130. cmax.x=Max( cmax.x,v.x );cmax.y=Max( cmax.y,v.y )
  131. Next
  132. If cmin.x>=1.0 Or cmin.y>=1.0 Return
  133. If cmax.x<0.0 Or cmax.y<0.0 Return
  134. qscale=cmax-cmin
  135. qtrans=cmin
  136. Endif
  137. If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  138. renderPass|=8
  139. Case LightType.Spot
  140. If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  141. renderPass|=12
  142. Default
  143. Return
  144. End
  145. _runiforms.SetVec2f( "QuadCoordScale",qscale )
  146. _runiforms.SetVec2f( "QuadCoordTrans",qtrans )
  147. _runiforms.SetMat4f( "LightViewMatrix",lvmatrix )
  148. _runiforms.SetMat4f( "InverseLightViewMatrix",-lvmatrix )
  149. _runiforms.SetColor( "LightColor",light.Color )
  150. _runiforms.SetFloat( "LightRange",light.Range )
  151. _runiforms.SetFloat( "LightInnerAngle",light.InnerAngle*Pi/180.0 )
  152. _runiforms.SetFloat( "LightOuterAngle",light.OuterAngle*Pi/180.0 )
  153. _runiforms.SetTexture( "LightCubeTexture",light.Texture ?Else _whiteCubeTexture )
  154. _runiforms.SetTexture( "LightTexture",light.Texture ?Else _whiteTexture )
  155. _gdevice.ColorMask=ColorMask.All
  156. _gdevice.DepthMask=False
  157. _gdevice.DepthFunc=DepthFunc.Always
  158. _gdevice.BlendMode=BlendMode.Additive
  159. _gdevice.RenderPass=renderPass
  160. _gdevice.Shader=_deferredLightingShader
  161. _gdevice.CullMode=CullMode.None
  162. _runiforms.SetMat4f( "InverseProjectionMatrix",_invProjMatrix )
  163. RenderQuad()
  164. End
  165. Method RenderDeferredFog()
  166. If _scene.FogColor.a=0 Return
  167. _gdevice.ColorMask=ColorMask.All
  168. _gdevice.DepthMask=False
  169. _gdevice.DepthFunc=DepthFunc.Always
  170. _gdevice.BlendMode=BlendMode.Alpha
  171. _gdevice.RenderPass=0
  172. _gdevice.Shader=_deferredFogShader
  173. _gdevice.CullMode=CullMode.None
  174. RenderQuad()
  175. End
  176. Method RenderOpaqueDeferred()
  177. _gdevice.ColorMask=ColorMask.All
  178. _gdevice.DepthMask=True
  179. _gdevice.DepthFunc=DepthFunc.LessEqual
  180. _gdevice.BlendMode=BlendMode.Opaque
  181. _gdevice.RenderPass=1
  182. RenderOpaqueOps()
  183. 'only write to accum buffer only from now on...
  184. _gdevice.RenderTarget=_renderTarget1
  185. For Local light:=Eachin _scene.Lights
  186. RenderDeferredLighting( light )
  187. Next
  188. RenderDeferredFog()
  189. End
  190. Method RenderOpaqueForward()
  191. Local first:=True
  192. For Local light:=Eachin _scene.Lights
  193. Local renderPass:=2
  194. Select light.Type
  195. Case LightType.Directional
  196. If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  197. renderPass|=4
  198. Case LightType.Point
  199. If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  200. renderPass|=8
  201. Case LightType.Spot
  202. If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  203. renderPass|=12
  204. End
  205. Local lvmatrix:=_viewMatrix * light.Matrix
  206. _runiforms.SetMat4f( "LightViewMatrix",lvmatrix )
  207. _runiforms.SetMat4f( "InverseLightViewMatrix",-lvmatrix )
  208. _runiforms.SetColor( "LightColor",light.Color )
  209. _runiforms.SetFloat( "LightRange",light.Range )
  210. _runiforms.SetFloat( "LightInnerAngle",light.InnerAngle*Pi/180.0 )
  211. _runiforms.SetFloat( "LightOuterAngle",light.OuterAngle*Pi/180.0 )
  212. _runiforms.SetTexture( "LightCubeTexture",light.Texture ?Else _whiteCubeTexture )
  213. _runiforms.SetTexture( "LightTexture",light.Texture ?Else _whiteTexture )
  214. _gdevice.ColorMask=ColorMask.All
  215. _gdevice.DepthMask=first
  216. _gdevice.DepthFunc=DepthFunc.LessEqual
  217. _gdevice.BlendMode=first ? BlendMode.Opaque Else BlendMode.Additive
  218. _gdevice.RenderPass=renderPass
  219. RenderOpaqueOps()
  220. first=False
  221. Next
  222. If first
  223. _gdevice.ColorMask=ColorMask.All
  224. _gdevice.DepthMask=True
  225. _gdevice.DepthFunc=DepthFunc.LessEqual
  226. _gdevice.BlendMode=BlendMode.Opaque
  227. _gdevice.RenderPass=2
  228. RenderOpaqueOps()
  229. Endif
  230. End
  231. Method RenderOpaque()
  232. If _deferred
  233. RenderOpaqueDeferred()
  234. Else
  235. RenderOpaqueForward()
  236. Endif
  237. End
  238. Method RenderSelfIlluminated()
  239. _gdevice.ColorMask=ColorMask.All
  240. _gdevice.DepthMask=True
  241. _gdevice.DepthFunc=DepthFunc.LessEqual
  242. _gdevice.RenderPass=1
  243. RenderSelfIlluminatedOps()
  244. End
  245. Method RenderTransparent()
  246. If _deferred _gdevice.RenderTarget=_renderTarget0
  247. Local first:=True
  248. For Local light:=Eachin _scene.Lights
  249. Local renderPass:=2
  250. Select light.Type
  251. Case LightType.Directional
  252. ' If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  253. renderPass|=4
  254. Case LightType.Point
  255. ' If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  256. renderPass|=8
  257. Case LightType.Spot
  258. ' If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  259. renderPass|=12
  260. End
  261. _runiforms.SetColor( "LightColor",light.Color )
  262. _runiforms.SetFloat( "LightRange",light.Range )
  263. _runiforms.SetMat4f( "LightViewMatrix",_viewMatrix * light.Matrix )
  264. _gdevice.ColorMask=ColorMask.All
  265. _gdevice.DepthMask=False
  266. _gdevice.DepthFunc=DepthFunc.LessEqual
  267. _gdevice.RenderPass=renderPass
  268. RenderTransparentOps()
  269. first=False
  270. Exit
  271. Next
  272. If first
  273. _gdevice.ColorMask=ColorMask.All
  274. _gdevice.DepthMask=False
  275. _gdevice.DepthFunc=DepthFunc.LessEqual
  276. _gdevice.RenderPass=2
  277. RenderTransparentOps()
  278. Endif
  279. End
  280. Method RenderDirectionalShadows( light:Light )
  281. 'Perhaps use a different device for CSM...?
  282. '
  283. Local t_rtarget:=_gdevice.RenderTarget
  284. Local t_viewport:=_gdevice.Viewport
  285. Local t_scissor:=_gdevice.Scissor
  286. _gdevice.RenderTarget=_csmTarget
  287. _gdevice.Viewport=New Recti( 0,0,_csmTexture.Size )
  288. _gdevice.Scissor=_gdevice.Viewport
  289. _gdevice.ColorMask=ColorMask.All
  290. _gdevice.DepthMask=True
  291. _gdevice.Clear( Color.White,1.0 )
  292. _gdevice.DepthFunc=DepthFunc.LessEqual
  293. _gdevice.BlendMode=BlendMode.Opaque
  294. _gdevice.CullMode=CullMode.Front
  295. _gdevice.RenderPass=3|4
  296. Local viewLight:=light.InverseMatrix * _invViewMatrix
  297. For Local i:=0 Until _csmSplitDepths.Length-1
  298. Local znear:=_csmSplitDepths[i]
  299. Local zfar:=_csmSplitDepths[i+1]
  300. Local splitProj:=_projMatrix
  301. splitProj.k.z=(zfar+znear)/(zfar-znear)
  302. splitProj.t.z=-(zfar*znear*2)/(zfar-znear)
  303. Local invSplitProj:=-splitProj
  304. Local bounds:=Boxf.EmptyBounds
  305. For Local z:=-1 To 1 Step 2
  306. For Local y:=-1 To 1 Step 2
  307. For Local x:=-1 To 1 Step 2
  308. Local c:=New Vec3f( x,y,z ) 'clip coords
  309. Local v:=invSplitProj * c 'clip->view
  310. Local l:=viewLight * v 'view->light
  311. bounds|=l
  312. Next
  313. Next
  314. Next
  315. bounds.min.z-=100
  316. Local lightProj:=Mat4f.Ortho( bounds.min.x,bounds.max.x,bounds.min.y,bounds.max.y,bounds.min.z,bounds.max.z )
  317. 'set matrices for next pass...
  318. _runiforms.SetMat4f( "ShadowMatrix"+i,lightProj * viewLight )
  319. Local size:=_csmTexture.Size,hsize:=size/2
  320. Select i
  321. Case 0 _gdevice.Viewport=New Recti( 0,0,hsize.x,hsize.y )
  322. Case 1 _gdevice.Viewport=New Recti( hsize.x,0,size.x,hsize.y )
  323. Case 2 _gdevice.Viewport=New Recti( 0,hsize.y,hsize.x,size.y )
  324. Case 3 _gdevice.Viewport=New Recti( hsize.x,hsize.y,size.x,size.y )
  325. End
  326. _gdevice.Scissor=_gdevice.Viewport
  327. RenderShadowOps( light.InverseMatrix,lightProj )
  328. Next
  329. _gdevice.RenderTarget=t_rtarget
  330. _gdevice.Viewport=t_viewport
  331. _gdevice.Scissor=t_scissor
  332. End
  333. Method RenderPointShadows( light:Light )
  334. 'Perhaps use a different device for CSM...?
  335. '
  336. Local t_rtarget:=_gdevice.RenderTarget
  337. Local t_viewport:=_gdevice.Viewport
  338. Local t_scissor:=_gdevice.Scissor
  339. _gdevice.Viewport=New Recti( 0,0,_psmTexture.Size )
  340. _gdevice.Scissor=_gdevice.Viewport
  341. _gdevice.ColorMask=ColorMask.All
  342. _gdevice.DepthMask=True
  343. _gdevice.DepthFunc=DepthFunc.LessEqual
  344. _gdevice.BlendMode=BlendMode.Opaque
  345. _gdevice.CullMode=CullMode.Back'Front
  346. _gdevice.RenderPass=3|8
  347. Local near:=0.1
  348. Local lightProj:=Mat4f.Frustum( -near,+near,-near,+near,near,light.Range )
  349. lightProj.k.z=1'(zfar+znear)/(zfar-znear)
  350. lightProj.t.z=0'-(zfar*znear*2)/(zfar-znear)
  351. Local viewLight:=light.InverseMatrix * _invViewMatrix
  352. _runiforms.SetFloat( "LightRange",light.Range )
  353. _runiforms.SetMat4f( "ShadowMatrix0",viewLight )
  354. For Local i:=0 Until 6
  355. _gdevice.RenderTarget=_psmTargets[i]
  356. _gdevice.Clear( Color.White,1.0 )
  357. Local viewMatrix:=New AffineMat4f( _psmFaceTransforms[i] ) * light.InverseMatrix
  358. RenderShadowOps( viewMatrix,lightProj )
  359. Next
  360. _gdevice.RenderTarget=t_rtarget
  361. _gdevice.Viewport=t_viewport
  362. _gdevice.Scissor=t_scissor
  363. End
  364. Method RenderSpotShadows( light:Light )
  365. Local t_rtarget:=_gdevice.RenderTarget
  366. Local t_viewport:=_gdevice.Viewport
  367. Local t_scissor:=_gdevice.Scissor
  368. Local near:=0.1
  369. Local lightProj:=Mat4f.Frustum( -near,+near,-near,+near,near,light.Range )
  370. Local viewLight:=light.InverseMatrix * _invViewMatrix
  371. _runiforms.SetFloat( "LightRange",light.Range )
  372. _runiforms.SetMat4f( "ShadowMatrix0",lightProj * viewLight )
  373. _gdevice.RenderTarget=_csmTarget
  374. _gdevice.Viewport=New Recti( 0,0,_csmTexture.Size/2 )
  375. _gdevice.Scissor=_gdevice.Viewport
  376. _gdevice.ColorMask=ColorMask.All
  377. _gdevice.DepthMask=True
  378. _gdevice.Clear( Color.White,1.0 )
  379. _gdevice.DepthFunc=DepthFunc.LessEqual
  380. _gdevice.BlendMode=BlendMode.Opaque
  381. _gdevice.CullMode=CullMode.Front'Back
  382. _gdevice.RenderPass=3|12
  383. RenderShadowOps( light.InverseMatrix,lightProj )
  384. _gdevice.RenderTarget=t_rtarget
  385. _gdevice.Viewport=t_viewport
  386. _gdevice.Scissor=t_scissor
  387. End
  388. Method RenderPostEffects()
  389. If _deferred _gdevice.RenderTarget=_renderTarget1
  390. PostEffect.BeginRendering( _gdevice,_runiforms )
  391. For Local effect:=Eachin _scene.PostEffects
  392. If Not effect.Enabled Continue
  393. _gdevice.ColorMask=ColorMask.All
  394. _gdevice.DepthMask=False
  395. _gdevice.CullMode=CullMode.None
  396. _gdevice.DepthFunc=DepthFunc.Always
  397. _gdevice.BlendMode=BlendMode.Opaque
  398. _gdevice.RenderPass=0
  399. effect.Render()
  400. Next
  401. PostEffect.EndRendering()
  402. End
  403. Method RenderCopy()
  404. If _direct Return
  405. Local rsize:=_gdevice.Viewport.Size
  406. Local rtarget:=_gdevice.RenderTarget
  407. Local rtexture:=rtarget.GetColorTexture( 0 )
  408. _runiforms.SetTexture( "SourceBuffer",rtexture )
  409. _runiforms.SetVec2f( "SourceBufferSize",Cast<Vec2f>( rsize ) )
  410. _runiforms.SetVec2f( "SourceBufferScale",Cast<Vec2f>( rsize )/Cast<Vec2f>( rtexture.Size ) )
  411. _gdevice.RenderTarget=_outputRenderTarget
  412. _gdevice.Resize( _outputRenderTargetSize )
  413. _gdevice.Viewport=_outputViewport
  414. _gdevice.Scissor=_outputViewport
  415. _gdevice.ColorMask=ColorMask.All
  416. _gdevice.DepthMask=False
  417. _gdevice.DepthFunc=DepthFunc.Always
  418. _gdevice.BlendMode=BlendMode.Opaque
  419. _gdevice.CullMode=CullMode.None
  420. _gdevice.Shader=_copyShader
  421. _gdevice.RenderPass=0
  422. RenderCopyQuad()
  423. _gdevice.RenderTarget=Null
  424. _gdevice.Resize( Null )
  425. End
  426. Method RenderCopyQuad() Virtual 'So VRRenderer can override, ie: cheeze it for now!
  427. If _outputRenderTarget
  428. RenderInvertedQuad()
  429. Else
  430. RenderQuad()
  431. Endif
  432. End
  433. Method RenderInvertedQuad()
  434. Global _vertices:=New VertexBuffer( New Vertex3f[](
  435. New Vertex3f( 0,1,0,0,0 ),
  436. New Vertex3f( 1,1,0,1,0, ),
  437. New Vertex3f( 1,0,0,1,1 ),
  438. New Vertex3f( 0,0,0,0,1 ) ) )
  439. _gdevice.VertexBuffer=_vertices
  440. _gdevice.Render( 4,1 )
  441. End
  442. Method RenderQuad()
  443. Global _vertices:=New VertexBuffer( New Vertex3f[](
  444. New Vertex3f( 0,1,0,0,1 ),
  445. New Vertex3f( 1,1,0,1,1 ),
  446. New Vertex3f( 1,0,0,1,0 ),
  447. New Vertex3f( 0,0,0,0,0 ) ) )
  448. _gdevice.VertexBuffer=_vertices
  449. _gdevice.Render( 4,1 )
  450. End
  451. Method SortTransparentOps()
  452. _renderQueue.TransparentOps.Sort( Lambda:Int( x:RenderOp,y:RenderOp )
  453. If y.distance<x.distance Return -1
  454. If x.distance<y.distance Return 1
  455. Return 0
  456. End )
  457. End
  458. Method SortSpriteOps()
  459. _renderQueue.SpriteOps.Sort( Lambda:Int( x:SpriteOp,y:SpriteOp )
  460. If y.distance<x.distance Return -1
  461. If x.distance<y.distance Return 1
  462. Return 0
  463. End )
  464. End
  465. Method RenderOpaqueOps()
  466. RenderRenderOps( _renderQueue.OpaqueOps,_viewMatrix,_projMatrix )
  467. End
  468. Method RenderSelfIlluminatedOps()
  469. RenderRenderOps( _renderQueue.SelfIlluminatedOps,_viewMatrix,_projMatrix )
  470. End
  471. Method RenderTransparentOps()
  472. RenderRenderOps( _renderQueue.TransparentOps,_viewMatrix,_projMatrix )
  473. End
  474. Method RenderRenderOps( ops:Stack<RenderOp>,viewMatrix:AffineMat4f,projMatrix:Mat4f )
  475. Local viewProjMatrix:=projMatrix * viewMatrix
  476. _runiforms.SetMat4f( "ViewMatrix",viewMatrix )
  477. _runiforms.SetMat4f( "ProjectionMatrix",projMatrix )
  478. _runiforms.SetMat4f( "ViewProjectionMatrix",viewProjMatrix )
  479. _runiforms.SetMat4f( "InverseProjectionMatrix",-projMatrix )
  480. Local instance:Entity=Null,first:=True
  481. Local material:Material
  482. Local bones:Mat4f[]
  483. For Local op:=Eachin ops
  484. If op.instance<>instance Or first
  485. first=False
  486. instance=op.instance
  487. Local modelMat:=instance ? instance.Matrix Else New AffineMat4f
  488. Local modelViewMat:=viewMatrix * modelMat
  489. Local modelViewNormMat:=modelViewMat.m.Cofactor()
  490. Local modelViewProjMat:=projMatrix * modelViewMat
  491. _iuniforms.SetMat4f( "ModelMatrix",modelMat )
  492. _iuniforms.SetMat4f( "ModelViewMatrix",modelViewMat )
  493. _iuniforms.SetMat3f( "ModelViewNormalMatrix",modelViewNormMat )
  494. _iuniforms.SetMat4f( "ModelViewProjectionMatrix",modelViewProjMat )
  495. _iuniforms.SetColor( "Color",instance ? instance.Color Else Color.White )
  496. _iuniforms.SetFloat( "Alpha",instance ? instance.Alpha Else 1.0 )
  497. Endif
  498. If op.bones
  499. _iuniforms.SetMat4fArray( "ModelBoneMatrices",op.bones )
  500. Endif
  501. If op.uniforms
  502. _gdevice.BindUniformBlock( op.uniforms )
  503. Endif
  504. If op.material<>material
  505. material=op.material
  506. _gdevice.Shader=op.shader
  507. _gdevice.BindUniformBlock( material.Uniforms )
  508. _gdevice.CullMode=material.CullMode
  509. Endif
  510. _gdevice.BlendMode=op.blendMode
  511. _gdevice.VertexBuffer=op.vbuffer
  512. If op.ibuffer
  513. _gdevice.IndexBuffer=op.ibuffer
  514. _gdevice.RenderIndexed( op.order,op.count,op.first )
  515. Else
  516. _gdevice.Render( op.order,op.count,op.first )
  517. Endif
  518. Next
  519. End
  520. Method RenderShadowOps( viewMatrix:AffineMat4f,projMatrix:Mat4f )
  521. Local ops:=_renderQueue.ShadowOps
  522. Local viewProjMatrix:=projMatrix * viewMatrix
  523. _runiforms.SetMat4f( "ViewMatrix",viewMatrix )
  524. _runiforms.SetMat4f( "ProjectionMatrix",projMatrix )
  525. _runiforms.SetMat4f( "ViewProjectionMatrix",viewProjMatrix )
  526. _runiforms.SetMat4f( "InverseProjectionMatrix",-projMatrix )
  527. Local instance:Entity=Null,first:=True
  528. Local material:Material
  529. Local bones:Mat4f[]
  530. For Local op:=Eachin ops
  531. If op.instance<>instance Or first
  532. first=False
  533. instance=op.instance
  534. Local modelMat:=instance ? instance.Matrix Else New AffineMat4f
  535. Local modelViewMat:=viewMatrix * modelMat
  536. Local modelViewNormMat:=modelViewMat.m.Cofactor()
  537. Local modelViewProjMat:=projMatrix * modelViewMat
  538. _iuniforms.SetMat4f( "ModelMatrix",modelMat )
  539. _iuniforms.SetMat4f( "ModelViewMatrix",modelViewMat )
  540. _iuniforms.SetMat3f( "ModelViewNormalMatrix",modelViewNormMat )
  541. _iuniforms.SetMat4f( "ModelViewProjectionMatrix",modelViewProjMat )
  542. Endif
  543. If op.bones _iuniforms.SetMat4fArray( "ModelBoneMatrices",op.bones )
  544. If op.uniforms _gdevice.BindUniformBlock( op.uniforms )
  545. If op.material<>material
  546. material=op.material
  547. _gdevice.Shader=material.GetRenderShader()
  548. _gdevice.BindUniformBlock( material.Uniforms )
  549. Endif
  550. _gdevice.VertexBuffer=op.vbuffer
  551. If op.ibuffer
  552. _gdevice.IndexBuffer=op.ibuffer
  553. _gdevice.RenderIndexed( op.order,op.count,op.first )
  554. Else
  555. _gdevice.Render( op.order,op.count,op.first )
  556. Endif
  557. Next
  558. End
  559. Private
  560. Field _direct:Bool=False
  561. Field _deferred:Bool=True
  562. Field _defs:String
  563. Field _gdevice:GraphicsDevice
  564. Field _runiforms:UniformBlock
  565. Field _iuniforms:UniformBlock
  566. Field _defaultEnv:Texture
  567. Field _skyboxShader:Shader
  568. Field _copyShader:Shader
  569. Field _deferredLightingShader:Shader
  570. Field _deferredFogShader:Shader
  571. Field _renderQueue:RenderQueue
  572. Field _spriteBuffer:=New SpriteBuffer
  573. Field _accumBuffer:Texture
  574. Field _colorBuffer:Texture
  575. Field _normalBuffer:Texture
  576. Field _depthBuffer:Texture
  577. Field _renderTarget0:RenderTarget 'all buffers
  578. Field _renderTarget1:RenderTarget 'accum buffer only
  579. Field _effectBuffer:Texture
  580. Field _effectTarget:RenderTarget
  581. Field _csmSize:=2048
  582. Field _csmSplits:Float[]
  583. Field _csmSplitDepths:=New Float[5]
  584. Field _csmTexture:Texture
  585. Field _csmDepth:Texture
  586. Field _csmTarget:RenderTarget
  587. Field _psmSize:=2048
  588. Field _psmTexture:Texture
  589. Field _psmDepth:Texture
  590. Field _psmTargets:=New RenderTarget[6]
  591. Field _psmFaceTransforms:Mat3f[]
  592. Field _outputRenderTarget:RenderTarget
  593. Field _outputRenderTargetSize:Vec2i
  594. Field _outputViewport:Recti
  595. Field _scene:Scene
  596. Field _viewMatrix:AffineMat4f
  597. Field _projMatrix:Mat4f
  598. Field _near:Float
  599. Field _far:Float
  600. Field _invViewMatrix:AffineMat4f
  601. Field _invProjMatrix:Mat4f
  602. Field _ambientRendered:Bool
  603. Field _whiteCubeTexture:Texture
  604. Field _whiteTexture:Texture
  605. Global _current:Renderer
  606. Method Init()
  607. Global inited:Bool
  608. If inited Return
  609. inited=True
  610. _gdevice=New GraphicsDevice( 0,0 )
  611. _runiforms=New UniformBlock( 1,True )
  612. _iuniforms=New UniformBlock( 2,True )
  613. _gdevice.BindUniformBlock( _runiforms )
  614. _gdevice.BindUniformBlock( _iuniforms )
  615. _defaultEnv=Texture.Load( "asset::textures/env_default.jpg",TextureFlags.FilterMipmap|TextureFlags.Cubemap|TextureFlags.Envmap )
  616. _skyboxShader=Shader.Open( "misc/skybox",ShaderDefs )
  617. _copyShader=Shader.Open( "misc/copy" )
  618. If _deferred
  619. _deferredLightingShader=Shader.Open( "misc/lighting-deferred",ShaderDefs )
  620. _deferredFogShader=Shader.Open( "misc/fog-deferred",ShaderDefs )
  621. Endif
  622. _renderQueue=New RenderQueue
  623. _psmFaceTransforms=New Mat3f[](
  624. New Mat3f( 0,0,+1, 0,-1,0, -1, 0,0 ), '+X
  625. New Mat3f( 0,0,-1, 0,-1,0, +1, 0,0 ), '-X
  626. New Mat3f( +1,0, 0, 0,0,+1, 0,+1,0 ), '+Y
  627. New Mat3f( +1,0, 0, 0,0,-1, 0,-1,0 ), '-Y
  628. New Mat3f( +1,0, 0, 0,-1,0, 0,0,+1 ), '+Z
  629. New Mat3f( -1,0, 0, 0,-1,0, 0,0,-1 ) ) '-Z
  630. Local pixmap:=New Pixmap( 1,1,PixelFormat.I8 )
  631. pixmap.Clear( Color.White )
  632. _whiteCubeTexture=New Texture( pixmap,TextureFlags.Cubemap )
  633. _whiteTexture=Texture.ColorTexture( Color.White )
  634. ValidateSize( New Vec2i( 1920,1080 ) )
  635. End
  636. Method ValidateSize( size:Vec2i )
  637. If _direct Return
  638. If _accumBuffer And size.x<=_accumBuffer.Size.x And size.y<=_accumBuffer.Size.y Return
  639. _accumBuffer?.Discard()
  640. _colorBuffer?.Discard()
  641. _normalBuffer?.Discard()
  642. _depthBuffer?.Discard()
  643. _renderTarget0?.Discard()
  644. _renderTarget1?.Discard()
  645. #If Not __MOBILE_TARGET__
  646. Const color_format:=PixelFormat.RGBA32F
  647. Const depth_format:=PixelFormat.Depth32
  648. #Else
  649. Const color_format:=PixelFormat.RGBA8
  650. Const depth_format:=PixelFormat.Depth32
  651. #Endif
  652. If _deferred
  653. _accumBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  654. _colorBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  655. _normalBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  656. _depthBuffer=New Texture( size.x,size.y,depth_format,TextureFlags.Dynamic )
  657. _renderTarget0=New RenderTarget( New Texture[]( _accumBuffer,_colorBuffer,_normalBuffer ),_depthBuffer )
  658. _renderTarget1=New RenderTarget( New Texture[]( _accumBuffer ),Null )
  659. _runiforms.SetTexture( "AccumBuffer",_accumBuffer )
  660. _runiforms.SetTexture( "ColorBuffer",_colorBuffer )
  661. _runiforms.SetTexture( "NormalBuffer",_normalBuffer )
  662. _runiforms.SetTexture( "DepthBuffer",_depthBuffer )
  663. Else
  664. _accumBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  665. _depthBuffer=New Texture( size.x,size.y,depth_format,TextureFlags.Dynamic )
  666. _renderTarget0=New RenderTarget( New Texture[]( _accumBuffer ),_depthBuffer )
  667. _renderTarget1=New RenderTarget( New Texture[]( _accumBuffer ),Null )
  668. _runiforms.SetTexture( "AccumBuffer",_accumBuffer )
  669. _runiforms.SetTexture( "DepthBuffer",_depthBuffer )
  670. Endif
  671. End
  672. Method ValidateCSMShadows()
  673. If Not _csmTexture Or _csmSize*2<>_csmTexture.Size.x
  674. _csmTarget?.Discard()
  675. _csmTexture?.Discard()
  676. _csmDepth?.Discard()
  677. const depth_format:=PixelFormat.Depth32
  678. _csmTexture=New Texture( _csmSize*2,_csmSize*2,depth_format,TextureFlags.Dynamic )'|TextureFlags.Filter )
  679. _csmTarget=New RenderTarget( Null,_csmTexture )
  680. _csmDepth=Null
  681. _runiforms.SetTexture( "ShadowCSMTexture",_csmTexture )
  682. Endif
  683. End
  684. Method ValidatePSMShadows()
  685. If Not _psmTexture Or _psmSize<>_psmTexture.Size.x
  686. _psmTexture?.Discard()
  687. _psmDepth?.Discard()
  688. For Local i:=0 Until 6
  689. _psmTargets[i]?.Discard()
  690. Next
  691. const color_format:=PixelFormat.RGBA8
  692. const depth_format:=PixelFormat.Depth32
  693. _psmTexture=New Texture( _psmSize,_psmSize,color_format,TextureFlags.Cubemap|TextureFlags.Dynamic )
  694. _psmDepth=New Texture( _psmSize,_psmSize,depth_format,TextureFlags.Dynamic )
  695. For Local i:=0 Until 6
  696. Local face:=_psmTexture.GetCubeFace( Cast<CubeFace>( i ) )
  697. _psmTargets[i]=New RenderTarget( New Texture[]( face ),_psmDepth )
  698. Next
  699. _runiforms.SetTexture( "ShadowCubeTexture",_psmTexture )
  700. Endif
  701. End
  702. Method SetOutputRenderTarget( renderTarget:RenderTarget,renderTargetSize:Vec2i,viewport:Recti )
  703. _outputRenderTarget=renderTarget
  704. _outputRenderTargetSize=renderTargetSize
  705. _outputViewport=viewport
  706. ValidateSize( viewport.Size )
  707. If _direct
  708. _gdevice.RenderTarget=renderTarget
  709. _gdevice.Resize( renderTargetSize )
  710. _gdevice.Viewport=viewport
  711. _gdevice.Scissor=viewport
  712. Return
  713. Endif
  714. _gdevice.RenderTarget=_renderTarget0
  715. _gdevice.Viewport=New Recti( 0,0,viewport.Size )
  716. _gdevice.Scissor=_gdevice.Viewport
  717. _runiforms.SetVec2f( "BufferCoordScale",Cast<Vec2f>( viewport.Size )/Cast<Vec2f>( _accumBuffer.Size ) )
  718. End
  719. Method SetScene( scene:Scene )
  720. _scene=scene
  721. Local sky:=_scene.SkyTexture
  722. If sky
  723. _runiforms.SetColor( "SkyColor",_scene.SkyColor )
  724. If sky.Flags & TextureFlags.Cubemap
  725. _runiforms.SetTexture( "SkyTextureCube",sky )
  726. _runiforms.SetTexture( "SkyTexture2D",_whiteTexture )
  727. _runiforms.SetInt( "SkyCube",1 )
  728. Else
  729. _runiforms.SetTexture( "SkyTextureCube",_whiteCubeTexture )
  730. _runiforms.SetTexture( "SkyTexture2D",sky )
  731. _runiforms.SetInt( "SkyCube",0 )
  732. Endif
  733. Else
  734. _runiforms.SetTexture( "SkyTextureCube",Null )
  735. _runiforms.SetTexture( "SkyTexture2D",Null )
  736. Endif
  737. _runiforms.SetColor( "ClearColor",_scene.ClearColor )
  738. _runiforms.SetColor( "AmbientDiffuse",_scene.AmbientLight )
  739. Local env:=(_scene.EnvTexture ?Else _scene.SkyTexture) ?Else _defaultEnv
  740. If env.Flags & TextureFlags.Cubemap
  741. _runiforms.SetTexture( "EnvTextureCube",env )
  742. _runiforms.SetTexture( "EnvTexture2D",_whiteTexture )
  743. _runiforms.SetInt( "EnvCube",1 )
  744. Else
  745. _runiforms.SetTexture( "EnvTextureCube",_whiteCubeTexture )
  746. _runiforms.SetTexture( "EnvTexture2D",env )
  747. _runiforms.SetInt( "EnvCube",0 )
  748. Endif
  749. _runiforms.SetFloat( "EnvTextureMaxLod",Log2( env.Size.x ) )
  750. _runiforms.SetColor( "EnvColor",_scene.EnvColor )
  751. _runiforms.SetColor( "FogColor",_scene.FogColor )
  752. _runiforms.SetFloat( "FogNear",_scene.FogNear )
  753. _runiforms.SetFloat( "FogFar",_scene.FogFar )
  754. _runiforms.SetFloat( "ShadowAlpha",_scene.ShadowAlpha )
  755. _csmSplits=_scene.CSMSplits
  756. End
  757. Method SetCamera( viewMatrix:AffineMat4f,projMatrix:Mat4f,near:Float,far:Float )
  758. _viewMatrix=viewMatrix
  759. _projMatrix=projMatrix
  760. _near=near
  761. _far=far
  762. _invViewMatrix=-_viewMatrix
  763. _invProjMatrix=-_projMatrix
  764. _runiforms.SetMat3f( "EnvMatrix",_invViewMatrix.m )
  765. _runiforms.SetMat4f( "ProjectionMatrix",_projMatrix )
  766. _runiforms.SetMat4f( "InverseProjectionMatrix",_invProjMatrix )
  767. _runiforms.SetMat4f( "ViewMatrix",_viewMatrix )
  768. _runiforms.SetMat4f( "CameraMatrix",_invViewMatrix )
  769. _runiforms.SetFloat( "DepthNear",_near )
  770. _runiforms.SetFloat( "DepthFar",_far )
  771. _csmSplitDepths[0]=_near
  772. For Local i:=1 Until 5
  773. _csmSplitDepths[i]=Min( _csmSplitDepths[i-1]+_csmSplits[i-1],_far )
  774. Next
  775. _runiforms.SetVec4f( "ShadowCSMSplits",New Vec4f( _csmSplitDepths[1],_csmSplitDepths[2],_csmSplitDepths[3],_csmSplitDepths[4] ) )
  776. _renderQueue.Clear()
  777. Local time:=Float( Now() )
  778. _renderQueue.Time=time
  779. _runiforms.SetFloat( "Time",time )
  780. _renderQueue.EyePos=_invViewMatrix.t
  781. For Local r:=Eachin _scene.Renderables
  782. _renderQueue.AddShadowOps=r.CastsShadow
  783. r.OnRender( _renderQueue )
  784. Next
  785. SortTransparentOps()
  786. SortSpriteOps()
  787. _spriteBuffer.InsertRenderOps( _renderQueue,_invViewMatrix )
  788. End
  789. End