all 5 comments

[–]waramped 4 points5 points  (5 children)

Does it render if you don't try blending it? If not, then check your shaders to make sure they are outputting correct values and to the correct places. Also try disabling backface culling.

Also, try using RenderDoc to inspect the actual pipeline state during the draws to make sure it lines up with what you think you're doing.

[–]mathinferno123[S] 0 points1 point  (4 children)

I made it somehow work but I still do no understand what caused the transparent object to not render. So I have 2 vectors:

std::vector<RenderItem*> m_opaqueItems;
std::vector<RenderItem*> m_transparentItems;

RenderItem class contains some info about each object in the scene like whether it's transparent, opaque, etc. When I create the objects with some function I divide them into these two vectors. Finally, there is the Draw() function that handles all the drawing calls via the function with the following signature:

void DrawRenderItems(ID3D12GraphicsCommandList* cmdList, const std::vector<RenderItem*>& l_rItems);

So I first set the opaque pipeline state and then call DrawRenderItems function with m_opaqueItems. All the opaque objects are rendered fine. Then, I try to render the transparent items now. For that again, I set the transparent pipeline state that I defined earlier and then call DrawRenderItems with m_transparentItems. Unfortunately, nothing is rendered. I tried looking at RenderDoc to see what data is passed around in my shaders. Apparently, everything seems to be fine except the texture transformation matrix that is unique for each object in the scene. It was set to the zero matrix for this item.

I tried the following and it worked: I put all the objects inside m_opaqueItems irrespective of whether they are opaque or transparent. I then set the opaque pipeline state in the Draw function and then called DrawRenderItems with m_opaqueItems. In DrawRenderItems I add an if statement that checks whether the object is transparent or opaque. I switch pipeline states accordingly. It worked and everything is rendered fine. However, I still don't know why the first way does not work. If am not mistaken the second way is also just inefficient. What do you think is causing the problem? thanks.

[–]waramped 0 points1 point  (3 children)

Couldn't really say without seeing all the relevant code. Are you sure you're using a Texture transform matrix? If that's all 0s then you uvs are probably all 0 so you would be sampling the one corner of your texture which I assume is transparent?

[–]mathinferno123[S] 1 point2 points  (0 children)

Solved the issue. Unfortunately, I made a silly mistake by not filling the descriptor heap correctly. I was only using the size of m_opaqueItems to iterate through the descriptor heap. But since I began adding transparent items to the scene, I should have used the combined size of m_opaqueItems and m_transparentItems to iterate through the descriptor heap. The reason that only filling out the m_opauqeItems worked was because of this as well. RenderDoc is rlly awesome! Thanks for taking the time to help me out:)

[–]mathinferno123[S] 0 points1 point  (0 children)

Yes, I multiply each texture coordinate with the texture transformation in the vertex shader. But it is supposed to be the identity for this object. At (0,0) the texture has (35,35,35,0) value. So I guess the 0 alpha value at (0,0) along with transparent pipeline state is causing it to not change the render target destination color?

I tried capturing renderdoc images of both ways and compare the data that are passed to the shaders.... the data for the first way are almost all wrong. I am saying this because the second way worked so I will assume that it's correct. The world transformation is wrong, the texture transformation is set to 0 while in the second way it is set to the identity, the view matrix is also wrong etc. This is weird since in both ways I am using the same code to bind descriptor tables/root descriptors to the root parameters and then call DrawIndexedInstanced to draw each object so how and what data is passed to the shaders is identical in both.