@Gabriel TV3d+Bmax Defferd rendering

BlitzMax Forums/BlitzMax Programming/@Gabriel TV3d+Bmax Defferd rendering

Duckstab[o](Posted 2010) [#1]
Hi im trying to convert the Defferd Tutorial by Arius to Bmax but im having a few problems

I cant find the correct way to create the MRT surface

gBuffer = m_Scene.CreateMultiRenderSurface(3, W, H, True, True, 1, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, "gbuffer")

also have you managed to get it working as i would like to use the minimesh version so i can have projectile lights for spells casting exposions ect ?? is it possible

i tried setting up the project using 4 renders surfaces but the output was nothing like the included exe in the project folder


Gabriel(Posted 2010) [#2]
Hi,

I've not done anything with multiple render targets. I'm not entirely sure what you're asking though. Are you saying that there's something about the wrapper which is stopping this working as it should? What's the original line?


Duckstab[o](Posted 2010) [#3]
well firstly i need to know the correct way to create a MRT surface using your wrapper

Making gBuffer:ctvrendersurface[4] and calling the createMultirendersurface works but then crashes when assigning the surface to the shader

Imports MTV3D65
Public Class Form1

    ' Deferred Lighting.
    ' Original code AriusEso from TV3D Forums -> a very smart guy!!
    ' I have just translated to VB.NET for VB users like me :)

    'This program is free software: you can redistribute it and/or modify
    'it under the terms of the GNU General Public License as published by
    'the Free Software Foundation, either version 3 of the License, or
    '(at your option) any later version.

    'This program is distributed in the hope that it will be useful,
    'but WITHOUT ANY WARRANTY; without even the implied warranty of
    'MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    'GNU General Public License for more details.

    'You should have received a copy of the GNU General Public License
    'along with this program.  If not, see <http://www.gnu.org/licenses/>.

    Public shadeBuffer As TVShader
    Public shadeDeferred As TVShader

    Public gBuffer As TVRenderSurface
    Public sceneGeom As TVMesh
    Public pointLight As TVMesh

    Public m_Camera As TVCamera
    Public m_Math As TVMathLibrary
    Public m_Scene As TVScene
    Public m_Engine As TVEngine
    Public Globals As TVGlobals 'We need this later to create a 3D vector easily

    Dim W As Integer = 800
    Dim H As Integer = 600
    Dim fHoriz As Single

    Public Sub SetupScene()

        m_Camera = New TVCamera
        m_Math = New TVMathLibrary
        m_Scene = New TVScene
        m_Engine = New TVEngine
        Globals = New TVGlobals 'We need this later to create a 3D vector easily
        m_Engine.SetDebugFile("debug.txt")
        m_Engine.SetAngleSystem(CONST_TV_ANGLE.TV_ANGLE_DEGREE)
        m_Engine.Init3DWindowed(Me.Handle, True)
        'm_Engine.Init3DFullscreen(W, H, 32, True, False, cTV_DEPTHBUFFER_BESTBUFFER, 1, Handle)

        'Load in some geom for the scene. I'm just using a plane with a diffuse texture and normal map on it - it also has a parallax height map in the normal maps alpha channel.
        sceneGeom = m_Scene.CreateMeshBuilder("scene")
        sceneGeom.LoadTVM("data\\floor.tvm", True, True)
        sceneGeom.SetLightingMode(CONST_TV_LIGHTINGMODE.TV_LIGHTING_BUMPMAPPING_TANGENTSPACE, 0, 0)

        'Lets create our point light mesh with a radius of 40, putting it at position 0, 3, 0 - just above the floor.
        pointLight = m_Scene.CreateMeshBuilder("light")
        pointLight.CreateSphere(40, 12, 12)
        pointLight.SetMaterial(0, -1)
        pointLight.SetCullMode(CONST_TV_CULLING.TV_FRONT_CULL)
        pointLight.SetPosition(0, 3, 0)

        'We create our MRT based GBuffer.
        gBuffer = m_Scene.CreateMultiRenderSurface(3, W, H, True, True, 1, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16,..
 CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, "gbuffer")

        'Load in the shaders.
        shadeBuffer = m_Scene.CreateShader("buffers")
        shadeBuffer.CreateFromEffectFile("data\\gbuffer.fx")
        'Set how much bump we want.
        shadeBuffer.SetEffectParamFloat("bump", 0.03F)

        shadeDeferred = m_Scene.CreateShader("deferred")
        shadeDeferred.CreateFromEffectFile("data\\deferred.fx")

        'We want to send our MRT textures to the lighting shader. Again, this is easy.
        shadeDeferred.SetEffectParamTexture("c", gBuffer.GetTextureEx(0))
        shadeDeferred.SetEffectParamTexture("n", gBuffer.GetTextureEx(1))
        shadeDeferred.SetEffectParamTexture("p", gBuffer.GetTextureEx(2))
        'Send in the inverse viewport dimension.
        shadeDeferred.SetEffectParamFloat("invWidth", (1 / W))
        shadeDeferred.SetEffectParamFloat("invHeight", (1 / H))
        'Set our light position, colour and range. You can of course change this on the fly and if you had a lighting class it would be tidier.
        shadeDeferred.SetEffectParamVector3("lp", pointLight.GetPosition()) 'Light position.
        shadeDeferred.SetEffectParamVector3("lc", Globals.Vector3(1, 1, 1))          'Light colour. 
        shadeDeferred.SetEffectParamFloat("lr", 39)                         
'We make this 1 less than our actual sphere radius - the lighting calculation in the shader is done on the sphere
'so we need to keep attenuation within that limit. Easiest way is just to do sphereradius - 1.

        'Set the lighting shader on to our sphere mesh.
        pointLight.SetShader(shadeDeferred)
        'Set the buffer shader on to your scene mesh.
        sceneGeom.SetShader(shadeBuffer)

        m_Camera.SetCamera(50, 25, 0, 0, 3, 0)
        fHoriz = 0
    End Sub


    Public Sub RenderGBuffer()
        'Move our camera around a bit.
        Dim fTime As Single = m_Engine.AccurateTimeElapsed()
        Dim vNew As TV_3DVECTOR = m_Math.MoveAroundPoint(Globals.Vector3(0, 25, 0), 35, fHoriz, 0)
        m_Camera.SetCamera(vNew.x, vNew.y, vNew.z, 0, 3, 0)
        fHoriz += 0.003F * fTime

        'Render the buffer.
        gBuffer.SetNewCamera(m_Camera)
        gBuffer.StartRender(False)
        sceneGeom.Render()
        gBuffer.EndRender()
    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Show()
        SetupScene()

        While (1 <> 2)
            'Once a frame we render our gbuffer.
            RenderGBuffer()
            m_Engine.Clear(False)
            pointLight.Render()
            m_Engine.RenderToScreen()
            Application.DoEvents()
        End While

        m_Engine.ReleaseAll()
        End
    End Sub
End Class



The above is the code im trying to convert


Gabriel(Posted 2010) [#4]
well firstly i need to know the correct way to create a MRT surface using your wrapper

Exactly the same as you would without the wrapper.

Making gBuffer:ctvrendersurface[4] and calling the createMultirendersurface works but then crashes when assigning the surface to the shader

Why are you trying to store the result an array though? Scene->CreateMultiRenderSurface doesn't return an array, and the example certainly isn't using an array. He declares gbuffer as a single CTVRenderSurface:

Public gBuffer As TVRenderSurface


So your GBuffer should also be a single CTVRenderSurface. Unless you actually want three multirendersurfaces, in which case you should be using only one index of the array when creating the multirendersurface. EG:

gBuffer[0] = m_Scene.CreateMultiRenderSurface(3, W, H, True, True, 1, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, CONST_TV_RENDERSURFACEFORMAT.TV_TEXTUREFORMAT_HDR_FLOAT16, "gbuffer")


The way you're doing it now, you're going to end up with GBuffer pointing to an array which doesn't exist, and I can certainly see that crashing when you try to access the contents of the array.

If I'm misunderstanding what you're doing then I'll need to see more of your code.


Duckstab[o](Posted 2010) [#5]
Compile Error: Unable to convert from 'CTVRenderSurface Array' to 'glimmer.tv3d65.CTVRenderSurface'
Build Error: failed to compile E:/TV3DBMAX/Areonx Demo Room/Areonx Demo 1.bmx

this is the error i get when creating the MRT are you sure it doesnt return an array ?

Global Gbuffer:CTVRenderSurface

Gbuffer = pScene.CreateMultiRenderSurface(3, W, H, True, True, 1, cTV_TEXTUREFORMAT_HDR_FLOAT16, cTV_TEXTUREFORMAT_HDR_FLOAT16, cTV_TEXTUREFORMAT_HDR_FLOAT16, cTV_TEXTUREFORMAT_HDR_FLOAT16)



Gabriel(Posted 2010) [#6]
I'm pretty sure it doesn't. It's not easy when there's no documentation, but I checked the wrapper and Arius' sample code last night and they're both expecting it to return a single rendersurface. I don't remember ever changing how the wrapper operated but if you're getting an error expecting an array, I suppose I must have had it returning an array at some point.

I'll be home in a couple of hours. I'll send you the version I'm running, which definitely doesn't return an array. Then maybe we can see if that's the only problem. Sorry for the inconvenience.


Duckstab[o](Posted 2010) [#7]
	Method CreateMultiRenderSurface:CTVRenderSurface[] (iNumRenderTargets:Int, iWidth:Int, iHeight:Int, bUsedepth:Int, bUseMainBufferSize:Int, fMainBufferScale:Float, iFormat1:Int, iFormat2:Int, iFormat3:Int, iFormat4:Int) 
		Local P:Byte Ptr = CTVScene_CreateMultiRenderSurface(Self.WrapperHandle, iNumRenderTargets, iWidth, iHeight, bUseDepth, bUseMainBufferSize, fMainBufferScale, iFormat1, iFormat2, iFormat3, iFormat4) 
		Local B:TBank = CreateStaticBank(P, 4 * iNumRenderTargets) 
		Local R:CTVRenderSurface[] = New CTVRenderSurface[iNumRenderTargets] 
		For Local I:Int = 0 To iNumRenderTargets - 1
			R[0] = New CTVRenderSurface
			R[0].WrapperHandle = Byte Ptr(B.PeekInt(I * 4)) 
		Next
		Return R
	End Method


thats the TVW method in the mod

thanks in advance for your help


Duckstab[o](Posted 2010) [#8]
thanks for the mail im gonna test it out in a minute :)


Duckstab[o](Posted 2010) [#9]
Perfect working fine with Single light Getting ready to do a multilights version now :)

445Fps @1680*1050 4XAA with single Deferred Light


Gabriel(Posted 2010) [#10]
I'm glad that resolved it. Let me know if you come across any other issues.


kenshin(Posted 2010) [#11]
Would you be kind enough to send me a copy of this updated version of the wrapper Gabriel? I'm interested in seeing Deferred Rendering working as well.


Duckstab[o](Posted 2010) [#12]
Okay looks like its will be harder than i think :) tried doing 4 Lights as i cant get minimesh to work with shader

But the results are borked Clipping issues between overlapping lights or if view one lit area from another

back to the drawing board :)


Duckstab[o](Posted 2010) [#13]
Just a Quick update

Havent found a way to avoid clipping in the singular lighting method except for portalvis this limits its capabilities

But on a good infact very good note ive got the 52 minimesh version working like a charm

200fps with 52 lights visable at 1680*1050
each lights scale directly effects the light calculation
so if i half their scale ie get

400fps :)

allowing that this lest was done with a bumpmapped plane 1000*1000 units
and nothing to block the light visability this is looking to be a good lighting alternative

Im going to do a futher test with more random objects and maybe do a flyby to see if the Geometry visability furthers this performance


Duckstab[o](Posted 2010) [#14]
okay Pushing it to the max

Ive setup a insta-Drop Newton physics Room

Since the Mrt Deferred Renderer for minimesh is working around batching 52 lights thats the base i use and multiply it ie knowing its including another pass

For Each LightSource ive added a Sphere (texture,Mat same as the floor)
These are physical objects and the MiniLights are moved to their center each rendering frame

Using this and randomly creating lights at different heights

tbh is nice to watch them all fall

i get 38Fps with 2600Spheres 2600lights omg :)
1680*1050 res