ZFail shadow's bug [SOLVED]

Started by
5 comments, last by ShadowTzu 18 years, 5 months ago
Hi, (sorry for my bad english) I have a bug with Zbuffer, i thinks, when render my zpass shadow's to Zfail: Good Render (Zpass or Zfail with Device.RenderState.ZBufferFunction=Compare.Greater, but bug when camera is in shadow) screen2.jpg Bad render (Zfail, camera in shadow work fine) screen1.jpg Code:

        Device.RenderState.StencilEnable = True
        Device.RenderState.AlphaTestEnable = False
        Device.RenderState.ZBufferWriteEnable = False
        Device.RenderState.ShadeMode = ShadeMode.Flat
        Device.RenderState.StencilFunction = Compare.Always
        Device.RenderState.StencilFail = StencilOperation.Keep
        Device.RenderState.StencilPass = StencilOperation.Keep

        Device.RenderState.ReferenceStencil = 0
        Device.RenderState.StencilMask = -1
        Device.RenderState.StencilWriteMask = -1

        Device.RenderState.AlphaBlendEnable = True
        Device.RenderState.SourceBlend = Blend.Zero
        Device.RenderState.DestinationBlend = Blend.One


'Build_Shadow


        Device.RenderState.CullMode = Cull.Clockwise
        Device.RenderState.StencilZBufferFail = StencilOperation.Increment
        Device.DrawUserPrimitives(PrimitiveType.TriangleList, Tab_Ombre(Index).Nbr_VertDiv3, Tab_Ombre(Index).vertices)

        Device.RenderState.CullMode = Cull.CounterClockwise
        Device.RenderState.StencilZBufferFail = StencilOperation.Decrement
        Device.DrawUserPrimitives(PrimitiveType.TriangleList, Tab_Ombre(Index).Nbr_VertDiv3, Tab_Ombre(Index).vertices)

'[...] set RenderState to default


Render Shadow:

        Device.RenderState.ZBufferEnable = False
        Device.RenderState.StencilEnable = True
        Device.RenderState.FogEnable = False

        Device.RenderState.AlphaBlendEnable = True
        Device.RenderState.SourceBlend = Blend.SourceAlpha
        Device.RenderState.DestinationBlend = Blend.InvSourceAlpha

        Device.RenderState.CullMode = Cull.CounterClockwise
        Device.RenderState.ReferenceStencil = 0
        Device.RenderState.StencilFunction = Compare.Less
        Device.RenderState.StencilZBufferFail = StencilOperation.Keep
        Device.DrawUserPrimitives(PrimitiveType.TriangleStrip, 2, v)


Anyone can I help me please? [Edited by - ShadowTzu on November 3, 2005 9:19:14 AM]
Advertisement
Hi,

Just a quick question : do you cap your shadow volume when using ZFAIL ?
I dont know:
Public Sub Constuire_Ombre(ByVal Index As Integer, ByVal Lumiere_Position As Vector3, ByRef lMesh As Mesh)        Tab_Ombre(Index).numVertices = 0        Dim tempVertices As Vertex() = Nothing        Dim indices As Short() = Nothing        Dim edges As Short() = Nothing        Dim numFaces As Integer = lMesh.NumberFaces        Dim numVerts As Integer = lMesh.NumberVertices        Dim numEdges As Integer = 0        ' Allocate a temporary edge list        edges = New Short(numFaces * 6) {}        ' Lock the geometry buffers        tempVertices = CType(lMesh.LockVertexBuffer(GetType(Vertex), 0, numVerts), Vertex())        indices = CType(lMesh.LockIndexBuffer(GetType(Short), 0, numFaces * 3), Short())        ' For each face        Dim i As Integer        For i = 0 To numFaces - 1            Dim face0 As Short = indices((3 * i + 0))            Dim face1 As Short = indices((3 * i + 1))            Dim face2 As Short = indices((3 * i + 2))            Dim v0 As Vector3 = tempVertices(face0).p            Dim v1 As Vector3 = tempVertices(face1).p            Dim v2 As Vector3 = tempVertices(face2).p            ' Transform vertices or transform light?            Dim vCross1 As Vector3 = Vector3.Subtract(v2, v1)            Dim vCross2 As Vector3 = Vector3.Subtract(v1, v0)            Dim vNormal As Vector3 = Vector3.Cross(vCross1, vCross2)            If Vector3.Dot(vNormal, Lumiere_Position) >= 0.0F Then                AddEdge(edges, numEdges, face0, face1)                AddEdge(edges, numEdges, face1, face2)                AddEdge(edges, numEdges, face2, face0)            End If        Next i        For i = 0 To numEdges - 1            Dim v1 As Vector3 = tempVertices(edges((2 * i + 0))).p            Dim v2 As Vector3 = tempVertices(edges((2 * i + 1))).p            Dim v3 As Vector3 = Vector3.Subtract(v1, Vector3.Multiply(Lumiere_Position, 1000))            Dim v4 As Vector3 = Vector3.Subtract(v2, Vector3.Multiply(Lumiere_Position, 1000))            ' Add a quad (two triangles) to the vertex list            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v1 : Tab_Ombre(Index).numVertices += 1            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v2 : Tab_Ombre(Index).numVertices += 1            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v3 : Tab_Ombre(Index).numVertices += 1            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v2 : Tab_Ombre(Index).numVertices += 1            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v4 : Tab_Ombre(Index).numVertices += 1            Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = v3 : Tab_Ombre(Index).numVertices += 1        Next i        Tab_Ombre(Index).Nbr_VertDiv3 = Tab_Ombre(Index).numVertices / 3        ' Unlock the geometry buffers        lMesh.UnlockVertexBuffer()        lMesh.UnlockIndexBuffer()    End Sub    Private Sub AddEdge(ByVal edges() As Short, ByRef numEdges As Integer, ByVal v0 As Short, ByVal v1 As Short)        ' Remove interior edges (which appear in the list twice)        Dim i As Integer        For i = 0 To numEdges - 1            If edges((2 * i + 0)) = v0 And edges((2 * i + 1)) = v1 Or (edges((2 * i + 0)) = v1 And edges((2 * i + 1)) = v0) Then                If numEdges > 1 Then                    edges((2 * i + 0)) = edges((2 * (numEdges - 1) + 0))                    edges((2 * i + 1)) = edges((2 * (numEdges - 1) + 1))                End If                numEdges -= 1                Return            End If        Next i        edges((2 * numEdges + 0)) = v0        edges((2 * numEdges + 1)) = v1        numEdges += 1    End Sub 'AddEdge


[Edited by - ShadowTzu on November 3, 2005 8:29:03 AM]
Yerk O_o
Sorry, I'm not used to VB (or whatever language this is) ^^ And use [ source ] and [ /source ] tags, it will be easier for other people to read, and help you ^^

Edit : Hmm I tried to read your code, and it seems you don't cap your volume. With your current code, your shadow volume only has the form of a "tube". It's opened at. You need to "close" your volume (add the caps) so that ZFAIL will work.

ShadowVolume (MSDN Sample)

This is quite good. It mentions the caps, so you should read it to understand what it is. It's quite easy to add it to your code after you understand it ^^
thanks I read this!
That is VB.NET. What you want to do, is insert a flat quad inbetween the shared edge of 2 triangles, every shared edge. The normals of the left 2 vertices are the normals of the first edge and the normals of the right 2 vertices are the normals of the right edge. Use this as your sides. Use the face normals to check if a face is frontfacing or backfacing. If it is frontfacing, extrude it. The flat quad will stretch and create a tube automatically. The flat quad uses it's vertex normals, not it's face normal.

Hope this helps :)
it's good, thanks paic and CadeF :)

I have add after:
If Vector3.Dot(vNormal, Lumiere_Position) >= 0.0F Then[...]AddEdge(edges, numEdges, face2, face0)


this:
Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v2, Vector3.Multiply(tempVertices(face2).n, 0.003)) : Tab_Ombre(Index).numVertices += 1                Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v1, Vector3.Multiply(tempVertices(face1).n, 0.003)) : Tab_Ombre(Index).numVertices += 1                Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v0, Vector3.Multiply(tempVertices(face0).n, 0.003)) : Tab_Ombre(Index).numVertices += 1                Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v0, Vector3.Multiply(Lumiere_Position, 1000)) : Tab_Ombre(Index).numVertices += 1                Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v1, Vector3.Multiply(Lumiere_Position, 1000)) : Tab_Ombre(Index).numVertices += 1                Tab_Ombre(Index).vertices(Tab_Ombre(Index).numVertices) = Vector3.Subtract(v2, Vector3.Multiply(Lumiere_Position, 1000)) : Tab_Ombre(Index).numVertices += 1

This topic is closed to new replies.

Advertisement