png texture alpha blending without any alpha cutoff
png texture alpha blending without any alpha cutoff
Hello,
In my test application I simply draw two quads, each one with a png texture with alpha channel. To manage the alpha blending I'm trying to use the EMT_TRANSPARENT_ALPHA_CHANNEL flag but it introduces an alpha cutoff (..MaterialTypeParam etc...) that degrades the original textures alpha channel.
Drawing the second quads over the first, I would like to achieve a simply alpha blending between the two quads, based only on the original png alpha channel.
I read several posts but I'm little bit confused if I still have to use the EMT_TRANSPARENT_ALPHA_CHANNEL flag but I make a mistake, or to use the EMT_ONETEXTURE_BLEND flag with something like MaterialTypeParam = irr::video::pack_textureBlendFunc(irr::video::EBF_SRC_ALPHA, irr::video::EBF_ONE_MINUS_SRC_ALPHA, irr::video::EMFN_MODULATE_1X, irr::video::EAS_TEXTURE)...
Can anyone help me?
Thanks in advance,
Henry
In my test application I simply draw two quads, each one with a png texture with alpha channel. To manage the alpha blending I'm trying to use the EMT_TRANSPARENT_ALPHA_CHANNEL flag but it introduces an alpha cutoff (..MaterialTypeParam etc...) that degrades the original textures alpha channel.
Drawing the second quads over the first, I would like to achieve a simply alpha blending between the two quads, based only on the original png alpha channel.
I read several posts but I'm little bit confused if I still have to use the EMT_TRANSPARENT_ALPHA_CHANNEL flag but I make a mistake, or to use the EMT_ONETEXTURE_BLEND flag with something like MaterialTypeParam = irr::video::pack_textureBlendFunc(irr::video::EBF_SRC_ALPHA, irr::video::EBF_ONE_MINUS_SRC_ALPHA, irr::video::EMFN_MODULATE_1X, irr::video::EAS_TEXTURE)...
Can anyone help me?
Thanks in advance,
Henry
Re: png texture alpha blending without any alpha cutoff
The default MaterialTypeParam is 0, so the cutoff is not in effect. Have you set it to something else on purpose?
Re: png texture alpha blending without any alpha cutoff
Hi hendu,
I tried to set it to 0 (or to leave the default) but it seems to imply that alpha cutoff value is 0, so the texture appears totally opaque.
Trying value greater than 0, i.e 0.5, the result is that pixels with alpha less than 0.5 are considered fully transparent, and > 0.5 are considered opaque, as I could expect, and again I can't preserve the original alpha channel.
I tried to set it to 0 (or to leave the default) but it seems to imply that alpha cutoff value is 0, so the texture appears totally opaque.
Trying value greater than 0, i.e 0.5, the result is that pixels with alpha less than 0.5 are considered fully transparent, and > 0.5 are considered opaque, as I could expect, and again I can't preserve the original alpha channel.
Re: png texture alpha blending without any alpha cutoff
Then there is a bug. The default should have proper, perfect transparency.
Please post an example that reproduces this issue. Which version of irrlicht, which driver, which OS?
Please post an example that reproduces this issue. Which version of irrlicht, which driver, which OS?
Re: png texture alpha blending without any alpha cutoff
Hi,
I tried Irrlicht 1.7.3 and now 1.8 release. Windows 7 64bit, Direct3D9 driver.
But I'm an Irrlicht newbie and I believe it's likely my own mistake. Let me add some informations:
- each quad is a couple of triangles, drawn via drawIndexedTriangleList.
- each quad is managed by a custom scene node (with the transparent flag set), and the material is based on a shader, that for what I know simply copy the texture color on output.
- the destination rendering is a RTT texture, that at the end of the process I draw to the display through an additional quad with the texture set as material (I tried to draw the two alpha quads directly to the display, skipping the RTT pass, with the same result).
Can these informations make you to glimpse something wrong?
I tried Irrlicht 1.7.3 and now 1.8 release. Windows 7 64bit, Direct3D9 driver.
But I'm an Irrlicht newbie and I believe it's likely my own mistake. Let me add some informations:
- each quad is a couple of triangles, drawn via drawIndexedTriangleList.
- each quad is managed by a custom scene node (with the transparent flag set), and the material is based on a shader, that for what I know simply copy the texture color on output.
- the destination rendering is a RTT texture, that at the end of the process I draw to the display through an additional quad with the texture set as material (I tried to draw the two alpha quads directly to the display, skipping the RTT pass, with the same result).
Can these informations make you to glimpse something wrong?
Re: png texture alpha blending without any alpha cutoff
Hi,
maybe I have found the problem, but I'm not sure.
Going to the Irrlicht source code, the class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL (CD3D9MaterialRenderer.h) enables the alpha-blending and the alpha-test:
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f));
pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
I believe the problem is that the alpha-test is always applied, without the possibility to skip it. So, setting the MaterialTypeParam to 0 results in a cutoff value of 0 applied to the current rendering and not in a alphatest disabling.
Could be this the cause of the transparency problem?
maybe I have found the problem, but I'm not sure.
Going to the Irrlicht source code, the class CD3D9MaterialRenderer_TRANSPARENT_ALPHA_CHANNEL (CD3D9MaterialRenderer.h) enables the alpha-blending and the alpha-test:
pID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE);
pID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
pID3DDevice->SetRenderState(D3DRS_ALPHAREF, core::floor32(material.MaterialTypeParam * 255.f));
pID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
pID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
I believe the problem is that the alpha-test is always applied, without the possibility to skip it. So, setting the MaterialTypeParam to 0 results in a cutoff value of 0 applied to the current rendering and not in a alphatest disabling.
Could be this the cause of the transparency problem?
Re: png texture alpha blending without any alpha cutoff
I don't do DX, but that code looks correct - alpha test with >= 0 still passes full alpha through.
Try to reproduce with as simple an example as possible - create a box with such a texture, etc.
Try to reproduce with as simple an example as possible - create a box with such a texture, etc.
Re: png texture alpha blending without any alpha cutoff
Hi,
I wrote a simplified test application with same shaders and png and alpha is ok.
I'm still investigating if the RTT use in my workflow could be the cause.
I wrote a simplified test application with same shaders and png and alpha is ok.
I'm still investigating if the RTT use in my workflow could be the cause.
Re: png texture alpha blending without any alpha cutoff
are you using a custom shader or just the normal alpha material?
Re: png texture alpha blending without any alpha cutoff
a custom shader that simply copies the texture color on output.
Re: png texture alpha blending without any alpha cutoff
Now, in my simplified test application, also with RTT the alpha is ok (and at this moment I don't know why in my original application it doesn't work), but there is a new problem: using a RTT as intermediate stage, alpha blending has less quality than in the direct rendering case.
No RTT: http://www.gammared.it/TEMP/IRR/irr_no_rtt.png
RTT: http://www.gammared.it/TEMP/IRR/irr_rtt.png
The shader for each shape and for the final quad rendering is the same:
// Pixel shader output structure
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
sampler2D tex0 : register(s0);
PS_OUTPUT pixelMain( float4 Position : POSITION,
float4 Diffuse : COLOR0,
float2 TexCoord : TEXCOORD0 )
{
PS_OUTPUT Output;
float4 col = tex2D( tex0, TexCoord ); // sample color map
Output.RGBColor = col;
return Output;
}
No RTT: http://www.gammared.it/TEMP/IRR/irr_no_rtt.png
RTT: http://www.gammared.it/TEMP/IRR/irr_rtt.png
The shader for each shape and for the final quad rendering is the same:
// Pixel shader output structure
struct PS_OUTPUT
{
float4 RGBColor : COLOR0; // Pixel color
};
sampler2D tex0 : register(s0);
PS_OUTPUT pixelMain( float4 Position : POSITION,
float4 Diffuse : COLOR0,
float2 TexCoord : TEXCOORD0 )
{
PS_OUTPUT Output;
float4 col = tex2D( tex0, TexCoord ); // sample color map
Output.RGBColor = col;
return Output;
}
Re: png texture alpha blending without any alpha cutoff
Maybe could be that the alpha channel is rendered twice, as it is mentioned in this thread "Draw fonts to RTT with alpha", http://irrlicht.sourceforge.net/forum/v ... hp?t=45901 ?
If yes, is there anyone that know a solution/workaround?
If yes, is there anyone that know a solution/workaround?
Re: png texture alpha blending without any alpha cutoff
I solved the final issue setting in the addHighLevelShaderMaterialFromFiles(...) call for each shape rendered in the RTT intermediate stage, a EMT_ONETEXTURE_BLEND material type instead of EMT_TRANSPARENT_ALPHA_CHANNEL:
io::path psFileName0; // filename for the pixel shader
psFileName0 = "C:\\Shaders\\copyshaderA.hlsl";
video::IVideoDriver* driver = SceneManager->getVideoDriver();
video::IGPUProgrammingServices * gpu = driver->getGPUProgrammingServices();
s32 newMaterialType1 = 0;
if (gpu)
{
MyShaderCallBack0 * mc0 = new MyShaderCallBack0();
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
"" , "" , video::EVST_VS_1_1, //vsFileName0 "vertexMain"
psFileName0, "pixelMain", video::EPST_PS_2_0,
mc0, EMT_ONETEXTURE_BLEND); /*video::EMT_TRANSPARENT_ALPHA_CHANNEL*/
mc0->drop();
}
m_oMaterial.MaterialType = (E_MATERIAL_TYPE) newMaterialType1;
m_oMaterial.Wireframe = false;
m_oMaterial.Lighting = false;
m_oMaterial.AntiAliasing = EAAM_OFF;
m_oMaterial.MaterialTypeParam = irr::video::pack_textureBlendFunc(irr::video::EBF_SRC_ALPHA, irr::video::EBF_ONE_MINUS_SRC_ALPHA, irr::video::EMFN_MODULATE_1X, irr::video::EAS_TEXTURE);
m_oMaterial.setFlag(EMF_BLEND_OPERATION, true);
io::path psFileName0; // filename for the pixel shader
psFileName0 = "C:\\Shaders\\copyshaderA.hlsl";
video::IVideoDriver* driver = SceneManager->getVideoDriver();
video::IGPUProgrammingServices * gpu = driver->getGPUProgrammingServices();
s32 newMaterialType1 = 0;
if (gpu)
{
MyShaderCallBack0 * mc0 = new MyShaderCallBack0();
newMaterialType1 = gpu->addHighLevelShaderMaterialFromFiles(
"" , "" , video::EVST_VS_1_1, //vsFileName0 "vertexMain"
psFileName0, "pixelMain", video::EPST_PS_2_0,
mc0, EMT_ONETEXTURE_BLEND); /*video::EMT_TRANSPARENT_ALPHA_CHANNEL*/
mc0->drop();
}
m_oMaterial.MaterialType = (E_MATERIAL_TYPE) newMaterialType1;
m_oMaterial.Wireframe = false;
m_oMaterial.Lighting = false;
m_oMaterial.AntiAliasing = EAAM_OFF;
m_oMaterial.MaterialTypeParam = irr::video::pack_textureBlendFunc(irr::video::EBF_SRC_ALPHA, irr::video::EBF_ONE_MINUS_SRC_ALPHA, irr::video::EMFN_MODULATE_1X, irr::video::EAS_TEXTURE);
m_oMaterial.setFlag(EMF_BLEND_OPERATION, true);
-
hybrid
- Admin
- Posts: 14144
- Joined: Wed Apr 19, 2006 9:20 pm
- Location: Oldenburg(Oldb), Germany
- Contact:
Re: png texture alpha blending without any alpha cutoff
This setting for the material should be equivalent to ALPHA_TEXTURE. You have to have the BLEND_OP true for both material types, though. One texture blend is merely for altering the blend settings to different factors or mixing texture and vertex alpha.