DirectX8 - Transparacy to both sides of a polygon.

Started by
12 comments, last by Jacob Roman 19 years, 6 months ago
My polygons are transparent on one side but when it rotates 180 degrees to the other side, the area of the textured polygon that's supposed to be transparent is the same color as the background that's being cleared out, and not transparent. Is there a setting I'm leaving out?
Advertisement
Polygons are one-sided. When you look at them from the back, they're culled (not drawn). Lookup backface culling in the DX docs.
You can control this using the renderstate D3DRS_CULLMODE

D3DCULL_NONE for no culling..
No. It is viewed on both sides already. I already was using D3DCULL_NONE for two sided polygons. My problem is that it is transparent on one side, but not on the other. I want both sides transparent. You can still see the texture on both sides. Just that the Area that is supposed to be transparent is the same color as the clearing color. Like if you clear the backbuffer with red, the transparency for the opposite side is red, rather than being transparent. Like I said, the texture already is viewed on both sides. I know I must be missing a setting.

[Edited by - Jacob Roman on October 2, 2004 5:50:26 PM]
Okay, just so I understand: your using a color key, as in billboards? On noe side that color is "replaced" by 100% transparancy, on the other side you still see that color (and no transparancy)?
Draw the transparent objects last, back to front. What you're seeing is the result of

1) The transparent object drawn first fills the Z buffer.
2a) The objects behind it, drawn after, are not visible because they fail the Z test.
2b) The second half of the object isn't drawn because the first half is drawn in front first, so the second half fails the Z test.

To aid with areas that are solid or invisible you can use alpha test, which will skip writing to Z and color if it fails. For areas with n% transparency you MUST follow a strict back to front order for blending to work correctly. Solid objects are often drawn first sorted by texture/effect. Transparent objects are then drawn in Z order.
They are already in back to front order. But it could be a setting I'm missing. Here is what I have as an example:

'Here are my 3D settingsPublic Sub Direct3D8_Initialize(Window As Long)    If Direct3D8.CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Direct3D_Display_Mode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16) = D3D_OK Then            Direct3D_Window.AutoDepthStencilFormat = D3DFMT_D16        Direct3D_Window.EnableAutoDepthStencil = 1            End If        If Direct3D_Window.BackBufferFormat <> COLOR_DEPTH_UNKNOWN And Direct3D_Window.BackBufferFormat <> COLOR_DEPTH_8_BIT Then            Set Direct3D_Device = Direct3D8.CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, Window, D3DCREATE_SOFTWARE_VERTEXPROCESSING, Direct3D_Window)        Else            MsgBox "The color depth needs to be greater than 8 bit color mode (greater than 256 colors.)", vbCritical        End If        Direct3D_Device.SetVertexShader FVF_LIT_VERTEX        Direct3D_Device.SetRenderState D3DRS_ZENABLE, 1        Direct3D_Device.SetRenderState D3DRS_CULLMODE, D3DCULL_NONE        Direct3D_Device.SetRenderState D3DRS_LIGHTING, 0        Direct3D_Device.SetRenderState D3DRS_SRCBLEND, D3DBLEND_SRCALPHA    Direct3D_Device.SetRenderState D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA        Direct3D_Device.SetTextureStageState 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR        Direct3D_Device.SetTextureStageState 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR        Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, 1        D3DXMatrixIdentity World_Transformation_Matrix    Direct3D_Device.SetTransform D3DTS_WORLD, World_Transformation_Matrix 'commit this matrix to the device        D3DXMatrixLookAtLH Camera_Transformation_Matrix, Create_Vector(0, 0, -20), Create_Vector(0, 0, 0), Create_Vector(0, 1, 0)    Direct3D_Device.SetTransform D3DTS_VIEW, Camera_Transformation_Matrix        D3DXMatrixPerspectiveFovLH Perspective_Transformation_Matrix, PI / 4, 3 / 4, 0.1, 1000    Direct3D_Device.SetTransform D3DTS_PROJECTION, Perspective_Transformation_MatrixEnd Sub'There could possibly be a problem in here too where it'loads the texture for all I know.Public Sub Direct3D8_Load_Texture(Texture As Direct3DTexture8, File_Path As String, Width As Long, Height As Long, Transparent_Color As Long)    Set Texture = Direct3DX.CreateTextureFromFileEx(Direct3D_Device, File_Path, Width, Height, _                                                                            D3DX_DEFAULT, 0, D3DFMT_UNKNOWN, _                                                                            D3DPOOL_MANAGED, D3DX_FILTER_POINT, _                                                                            D3DX_FILTER_POINT, Transparent_Color, _                                                                            ByVal 0, ByVal 0) End Sub'This is where it creates it:Public Sub Create_Object()                                             Dim Number_Of_Vertices As Long    Vertex_List(0) = Create_Lit_Vertex(-5, 5, -5, RGB(255, 255, 255), 0, 0, 0)    Vertex_List(1) = Create_Lit_Vertex(5, 5, -5, RGB(255, 255, 255), 0, 1, 0)    Vertex_List(2) = Create_Lit_Vertex(5, -5, -5, RGB(255, 255, 255), 0, 1, 1)    Vertex_List(3) = Create_Lit_Vertex(-5, 5, -5, RGB(255, 255, 255), 0, 0, 0)    Vertex_List(4) = Create_Lit_Vertex(5, -5, -5, RGB(255, 255, 255), 0, 1, 1)    Vertex_List(5) = Create_Lit_Vertex(-5, -5, -5, RGB(255, 255, 255), 0, 0, 1)        Number_Of_Vertices = 6        Set Vertex_Buffer = Direct3D_Device.CreateVertexBuffer(Len(Vertex_List(0)) * Number_Of_Vertices, 0, FVF_LIT_VERTEX, D3DPOOL_MANAGED)        If Vertex_Buffer Is Nothing Then Exit Sub    D3DVertexBuffer8SetData Vertex_Buffer, 0, Len(Vertex_List(0)) * Number_Of_Vertices, 0, Vertex_List(0)        Vertex_List2(0) = Create_Lit_Vertex(-5, 5, 1, RGB(255, 255, 255), 0, 0, 0)    Vertex_List2(1) = Create_Lit_Vertex(5, 5, 1, RGB(255, 255, 255), 0, 1, 0)    Vertex_List2(2) = Create_Lit_Vertex(-5, -5, 1, RGB(255, 255, 255), 0, 0, 1)    Vertex_List2(3) = Create_Lit_Vertex(5, 5, 1, RGB(255, 255, 255), 0, 1, 0)    Vertex_List2(4) = Create_Lit_Vertex(5, -5, 1, RGB(255, 255, 255), 0, 1, 1)    Vertex_List2(5) = Create_Lit_Vertex(-5, -5, 1, RGB(255, 255, 255), 0, 0, 1)        Number_Of_Vertices = 6        Set Vertex_Buffer2 = Direct3D_Device.CreateVertexBuffer(Len(Vertex_List2(0)) * Number_Of_Vertices, 0, FVF_LIT_VERTEX, D3DPOOL_MANAGED)        If Vertex_Buffer2 Is Nothing Then Exit Sub    D3DVertexBuffer8SetData Vertex_Buffer2, 0, Len(Vertex_List2(0)) * Number_Of_Vertices, 0, Vertex_List2(0)        End Sub'Here is where it draws it. I have 2 polygons as an example'and as it rotates, it has one side transparent, other side'not, on both polygons.Public Sub Draw_Object()    'Note: Must be used in between DirectX_Device.BeginScene and DirectX_Device.EndScene        Direct3D_Device.SetVertexShader FVF_LIT_VERTEX        Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, 1        Direct3D_Device.SetStreamSource 0, Vertex_Buffer, Len(Vertex_List(0))        Direct3D_Device.SetTexture 0, Sprite_Texture(0)        Direct3D_Device.DrawPrimitive D3DPT_TRIANGLELIST, 0, 2        '-----------------------------------------------------------            Direct3D_Device.SetVertexShader FVF_LIT_VERTEX        Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, 1        Direct3D_Device.SetStreamSource 0, Vertex_Buffer2, Len(Vertex_List2(0))        Direct3D_Device.SetTexture 0, Sprite_Texture(2)        Direct3D_Device.DrawPrimitive D3DPT_TRIANGLELIST, 0, 2End Sub


If I'm missing some crucial code needed please let me know.
Quote:Original post by Jacob Roman
Like if you clear the backbuffer with red, the transparency for the opposite side is red, rather than being transparent. Like I said, the texture already is viewed on both sides. I know I must be missing a setting.

Ok, so if you don't expect to see the red, what do you expect to see? You say you're expecting to see 100% transparent, but what do you mean by that? Are there other meshes? Are you expecting to see the other side of this mesh? What? Perhaps a screenshot would help.

My money is still on the wrong draw order. If it's the other side of the same mesh you're expecting to see, note that you can't guarantee the correct draw order without breaking the mesh into quadrants, or sorting the faces individually. If you don't try to stop it, whichever part of the mesh that's drawn first is drawn first always, whether it's the furthest part or closest part of the mesh isn't D3D's problem.
Polygon Quad #1 is at Z --> -5 and drawn first in the Draw_Object() Sub. Here are the coodinates:

    Vertex_List(0) = Create_Lit_Vertex(-5, 5, -5, RGB(255, 255, 255), 0, 0, 0)    Vertex_List(1) = Create_Lit_Vertex(5, 5, -5, RGB(255, 255, 255), 0, 1, 0)    Vertex_List(2) = Create_Lit_Vertex(5, -5, -5, RGB(255, 255, 255), 0, 1, 1)    Vertex_List(3) = Create_Lit_Vertex(-5, 5, -5, RGB(255, 255, 255), 0, 0, 0)    Vertex_List(4) = Create_Lit_Vertex(5, -5, -5, RGB(255, 255, 255), 0, 1, 1)    Vertex_List(5) = Create_Lit_Vertex(-5, -5, -5, RGB(255, 255, 255), 0, 0, 1)


Polygon Quad #2 is at Z --> 5 and drawn last in the Draw_Object() Sub. Here are the coodinates:

    Vertex_List3(0) = Create_Lit_Vertex(-5, 5, 5, RGB(255, 255, 255), 0, 0, 0)    Vertex_List3(1) = Create_Lit_Vertex(5, 5, 5, RGB(255, 255, 255), 0, 1, 0)    Vertex_List3(2) = Create_Lit_Vertex(-5, -5, 5, RGB(255, 255, 255), 0, 0, 1)    Vertex_List3(3) = Create_Lit_Vertex(5, 5, 5, RGB(255, 255, 255), 0, 1, 0)    Vertex_List3(4) = Create_Lit_Vertex(5, -5, 5, RGB(255, 255, 255), 0, 1, 1)    Vertex_List3(5) = Create_Lit_Vertex(-5, -5, 5, RGB(255, 255, 255), 0, 0, 1)


So back to front doesn't seem to be the problem here. If I were to reverse it, it would still be the same problem. One side transparent, other side not, only reversed. I only have two textures in this example. One for one polygon, and another for the other. That "red" color was just an example color. It's actually black in my program. But the transparency is 0% on one side of my polygons and changing the area that's supposed to be transparent the same color as my clear color. If it didn't affect that opposite side at all, the picture's backcolor in the bitmap file that you want transparent, let's say black, would be black in the program. But it's not. In my program with an example clearing color of red, has that opposite side's transparent area with red with 0% transparency! So it's affecting that opposite side in someway. Just not what I want. I want 100% transparency on both sides. It could be the Z buffer too for all I know, but I don't see how it would affect the transparency colors other than back to front order issues, which isn't really the case here. And yes, a billboard effect is a good example of what I'm talking about, except the only difference is I want mine to be 3D, not stay 2D. If staying 2D where the case, I wouldn't have any problems with the transparency. I'll try to get some screenshots going when I can. What would help me more is if I see an example program written in VB that's based on transparency to help me find out where I went wrong.

[Edited by - Jacob Roman on October 2, 2004 7:35:46 PM]
How are you viewing the other side of the objects? Are you rotating the meshes, or rotating the camera around the scene? For the sake of completeness, I'm going to try to describe how moving the camera requires changing the render order. Just because A is at Z=-5 and B is at Z = 5 doesn't mean you always render B then A. It depends on the Z in camera space.

C = Camera, A = Object1 B = Object2. Caps just help show orientation.

Top down, map style view of scene.Rotate quads, leave camera alone... same Z order    A  BC   a  b    a  bbecomes    a  bC   a  b    A  Bor, rotate camera, leaving quads alone... Z order changes.    A  BC   a  b    a  bbecomes    A  B    a  b  C    a  b


Now you have A with Z = -5, and B with Z = 5... so you're drawing B then A... however, if your doing the camera move, in the second position A is now the more distant object in camera space, so you need to draw A then B... however when the camera moves back to the first position you need to draw B then A. It all depends on where the objects are relative to the camera, sorted at runtime.

You might be doing this. Maybe I'm describing things overly simplistic for you. I don't know your skill level. You haven't described what you're doing in enough detail to know whether you're sorting by camera space Z, how your objects are interacting, etc. The reason I'm persisting in the Z buffer problem is because it's the simplest thing that produces this error and you haven't yet convinced me that it's not the problem.

Your render states seem fine, and other than that render order is about the only thing you have to worry about.

When dealing with complex meshes, the render order of the faces of the mesh comes into play, and this is one of the most annoying parts of 3D graphics. When dealing with simple meshes like quads, you just have to sort them in camera space. If you have a particle system, with overlapping, intermixing faces, you're pretty much screwed. You can do things like additive blending, but regular alpha blending math just won't work unless you split the individual particles where two particles intersect, and sort all the fragments of quads you end up with. It's a complex mess, which no game ever tries to deal with.

This topic is closed to new replies.

Advertisement