Alpha Channel makes opaque objects disappear

Started by
16 comments, last by lucky6969b 12 years, 10 months ago
Hi,
When I enable alpha channel, some opaque objects gone missing

m_pDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, true);
m_pDevice->SetRenderState (D3DRS_ZENABLE, true);


when I turn off the depth buffer, everything appears in the scene
but transparency was lost.
I have optimized the mesh with Optimize( ATTRSORT....
And using an attribute table, The materials buffer should be correct, otherwise the main object won't appear
when I disable z-buffer.
Any thoughts.. (Post pics later)
Thanks
Jack
Advertisement
Alpha blending has no effect on z buffer. So if a transparent face is in front of something solid but is drawn before it in the rendering, the solid object wont be drawn. Is this maybe your problem? When I've written rendering code before that uses alpha transparency, I've done the rendering in 2 passes, first of all the solid stuff then the transparent.


Hi,
When I enable alpha channel, some opaque objects gone missing

m_pDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, true);
m_pDevice->SetRenderState (D3DRS_ZENABLE, true);


when I turn off the depth buffer, everything appears in the scene
but transparency was lost.
I have optimized the mesh with Optimize( ATTRSORT....
And using an attribute table, The materials buffer should be correct, otherwise the main object won't appear
when I disable z-buffer.
Any thoughts.. (Post pics later)
Thanks
Jack



m_pDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, true);
m_pDevice->SetRenderState (D3DRS_ZENABLE, true);




Can you post some more code than this? the problem no doubt lies in how you are setting your render states
These opaque objects disappearing don't happen to have alpha component in their texture or perhaps the material values contain zero alpha values?

- basically you should turn on alpha blending just for objects requiring it. So "global" alpha blend enable for every object isn't good approach.
- also, keep in mind that alpha transparency is draw order dependent procedure.

Cheers!




u32 CPerfectSimView::Draw(float fElapsedTime)
{
CPerfectSimDoc *pDoc = GetDocument();
m_fElapsedTime = fElapsedTime;



pDoc->GetCamera()->Update(m_fElapsedTime, false);

// SetPerspective();
// SetWorld2View();

m_pDevice->SetRenderState(D3DRS_FORCE_DWORD , true);
m_pDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, true );
m_pDevice->SetRenderState( D3DRS_ALPHATESTENABLE, true );


m_pDevice->SetRenderState( D3DRS_SRCBLEND , D3DBLEND_SRCALPHA );
m_pDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA) ;
m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP, D3DTOP_MODULATE );
m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
m_pDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
m_pDevice->SetRenderState( D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL );

m_pDevice->SetRenderState(D3DRS_ZENABLE, false);
m_pDevice->SetRenderState(D3DRS_ZWRITEENABLE, false);

m_pDevice->SetRenderState(D3DRS_ALPHAREF, 0x00000001);
m_pDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_FORCE_DWORD | D3DCMP_ALWAYS );
m_pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_COLORVALUE(0.5, 0.5, 0.5, 1.0));

m_pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);


// normalize since objects are being scaled therefore normals aren't correct anymore
m_pDevice->SetRenderState(D3DRS_NORMALIZENORMALS, true);



m_pDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
m_pDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
m_pDevice->SetSamplerState( 0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR );
m_pDevice->SetRenderState(D3DRS_LIGHTING, true);



m_pDevice->LightEnable(DIRECTIONAL, true);

mFX->SetValue(mhLight, &mLight, sizeof(DirLight));
mFX->SetValue(mAmbientLight, &mLight.ambient, sizeof(D3DXCOLOR));
mFX->SetValue(mDiffuseLight, &mLight.diffuse, sizeof(D3DXCOLOR));
D3DXVECTOR3 v(0.0f, -1.0f, 0.0);
mFX->SetValue(mLightVecW, &v, sizeof(D3DXVECTOR3));




ProcessTask();

pDoc->WHObj->Render();



The code is very likely to be wrong. Had no ideas how to correct this mess :) Thanks Jack
Hi,

I took a quick look in your code and I got impression that you are mixing fixed function pipeline stuff and effect stuff. Are you using vertex/pixel shaders?

My knowledge of the old SetRenderState functions start to get rusty, but "[font=CourierNew, monospace][size=2]D3DCMP_FORCE_DWORD" flag is definetely wrong. You seem to use it in several occasions. It is a enum for the compilers. [/font][font=CourierNew, monospace][size=2]However, it shouldn't have significance here or anywhere. [/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2][color=#1C2837][font=arial, verdana, tahoma, sans-serif][color=#000000]m_pDevice[color=#666600]->[color=#660066]SetRenderState[color=#666600]([color=#000000] D3DRS_DIFFUSEMATERIALSOURCE[color=#666600],[color=#000000] D3DMCS_MATERIAL [color=#666600]);[/font][/font]
[font=CourierNew, monospace][size=2]
[/font]
[font=CourierNew, monospace][size=2]The above line doesn't have meaning unless you set [/font]D3DRS_COLORVERTEX to true.


[font="'Segoe UI"]As you said, it is a mess. Especially if you mix effect files and shaders with ffp processing. Can you show more code perhaps? Show some shaders?[/font]
[font="'Segoe UI"]
[/font]
[font="'Segoe UI"]Cheers![/font]
This is the shader code i am using
thanks very much



struct Mtrl
{
float4 ambient;
float4 diffuse;
float4 spec;
float specPower;
};

struct DirLight
{
float4 ambient;
float4 diffuse;
float4 spec;
float3 dirW;
};

uniform extern float4x4 gWorld;
uniform extern float4x4 gWorldInvTrans;
uniform extern float4x4 gWVP;
uniform extern Mtrl gMtrl;
uniform extern DirLight gLight;
uniform extern float3 gEyePosW;
uniform extern texture gTex;



sampler TexS = sampler_state
{
Texture = <gTex>;
MinFilter = Anisotropic;
MagFilter = LINEAR;
MipFilter = Point;
MaxAnisotropy = 8;
AddressU = WRAP;
AddressV = WRAP;
};


struct OutputVS
{
float4 posH : POSITION0;
float3 normalW : TEXCOORD0;
float3 toEyeW : TEXCOORD1;
float2 tex0 : TEXCOORD2;
float4 color : COLOR0;
};

OutputVS PhongDirLtTexVS(float3 posL : POSITION0, float3 normalL : NORMAL0, float2 tex0: TEXCOORD0)
{
// Zero out our output.
OutputVS outVS = (OutputVS)0;

// Transform normal to world space.
outVS.normalW = mul(float4(normalL, 0.0f), gWorldInvTrans).xyz;

// Transform vertex position to world space.
float3 posW = mul(float4(posL, 1.0f), gWorld).xyz;

// Compute the unit vector from the vertex to the eye.
outVS.toEyeW = gEyePosW - posW;


// Transform normal to world space.
float3 normalW = mul(float4(normalL, 0.0f), gWVP).xyz;
normalW = normalize(normalW);

// Compute the color: Equation 10.2.
//float s = max(dot(gLightVecW, normalW), 0.0f);
//float3 diffuse = s*(gDiffuseMtrl*gDiffuseLight).rgb;
//float3 ambient = gAmbientMtrl*gAmbientLight;
// outVS.color.rgb = ambient + diffuse;
// outVS.color.a = gDiffuseMtrl.a;

// Transform to homogeneous clip space.
outVS.posH = mul(float4(posL, 1.0f), gWVP);

// Pass on texture coordinates to be interpolated in rasterization.
outVS.tex0 = tex0;

// Done--return the output.
return outVS;
}

float4 PhongDirLtTexPS(float3 normalW : TEXCOORD0, float3 toEyeW : TEXCOORD1, float2 tex0 : TEXCOORD2) : COLOR
{
// Interpolated normals can become unnormal--so normalize.
normalW = normalize(normalW);
toEyeW = normalize(toEyeW);

// Light vector is opposite the direction of the light.
float3 lightVecW = -gLight.dirW;

// Compute the reflection vector.
float3 r = reflect(-lightVecW, normalW);

// Determine how much (if any) specular light makes it into the eye.
float t = pow(max(dot(r, toEyeW), 0.0f), gMtrl.specPower);

// Determine the diffuse light intensity that strikes the vertex.
float s = max(dot(lightVecW, normalW), 0.0f);

// Compute the ambient, diffuse and specular terms separatly.
float3 spec = t*(gMtrl.spec*gLight.spec).rgb;
float3 diffuse = s*(gMtrl.diffuse*gLight.diffuse).rgb;
float3 ambient = gMtrl.ambient*gLight.ambient;

// Get the texture color.
float4 texColor = tex2D(TexS, tex0);


// Combine the color from lighting with the texture color.
//float3 color = (ambient + diffuse)*texColor.rgb + spec;
// float3 color = (ambient + diffuse) + spec;
float3 color = (ambient + diffuse);
// if (texColor != 0) {
// color = gMtrl.diffuse*texColor.rgb;
// }

// Sum all the terms together and copy over the diffuse alpha.
// float3 outcolor = color.rgb * 0.5f;
//return float4(color, gMtrl.diffuse.a*texColor.a);
return float4(color, gMtrl.diffuse.a);
}

technique PhongDirLtTexTech
{
pass P0
{
// Specify the vertex and pixel shader associated with this pass.
vertexShader = compile vs_2_0 PhongDirLtTexVS();
pixelShader = compile ps_2_0 PhongDirLtTexPS();
}
}
Here are the pics. I enable and disable z-buffering in these 2 trials
http://img220.imageshack.us/i/beforeh.png/
http://img217.imageshack.us/i/afteruo.png/
Thanks
Jack
Hi,

I took another quick look to your code and the lines below are "no no" when using vertex/pixel shaders, although they shouldn't matter
[color=#1C2837][size=2][color=#000000]m_pDevice[color=#666600]->[color=#660066]SetRenderState[color=#666600]([color=#000000]D3DRS_LIGHTING[color=#666600],[color=#000000] [color=#000088]true[color=#666600]);[color=#000000]
m_pDevice[color=#666600]->[color=#660066]LightEnable[color=#666600]([color=#000000]DIRECTIONAL[color=#666600],[color=#000000] [color=#000088]true[color=#666600]);

Also, you are setting sampler states in your code and you also define a sampler in the shader code.

I'd get rid most of the SetRenderStates and move what's necessary to your fx-file.

What you can test is to manually set the alpha value in your shader output and then try the alphablending.

I don't see you setting your gMtrl value anywhere in the code.

Good luck!
Hi,
Thanks for your help first. Really appreciate it :)
I actually set gMtrl inside the render method

for (int j = 0; j < m_pMesh->m_cAttributes; ++j)
{
int mtrlIndex = m_pMesh->attTable[j].AttribId;
Mtrl m = m_pMesh->GetMaterial()[mtrlIndex];
mFX->SetValue(mhMtrl, &m, sizeof(Mtrl));
.....


I am not sure how to set individual pixels to alpha (is that what you meant?) to the mesh
because the mesh is a large chunk by itself. Could you please give me more hints on that?
Thanks
Jack

This topic is closed to new replies.

Advertisement