Transparency: Texture Alpha + Vertex alpha?
Transparency: Texture Alpha + Vertex alpha?
Is it possible to combine both transparency methods?
Everything I've found in the forum seems to do one, but not the other.
Unless maybe I'm just missing some setting somewhere...?
What I'm looking at is having billboards that use the alpha channel on the texture to define their transparency, but I want to be able to fade these billboards out over time. I was hoping to be able to do this via simply setting the vertices' alpha value, since it'll only be 4 iterations thru a loop that way.
The only other thing I can think of would be to lock the texture to get access to the bytes and manually apply the alpha value I require thru the whole texture.
Everything I've found in the forum seems to do one, but not the other.
Unless maybe I'm just missing some setting somewhere...?
What I'm looking at is having billboards that use the alpha channel on the texture to define their transparency, but I want to be able to fade these billboards out over time. I was hoping to be able to do this via simply setting the vertices' alpha value, since it'll only be 4 iterations thru a loop that way.
The only other thing I can think of would be to lock the texture to get access to the bytes and manually apply the alpha value I require thru the whole texture.
-
- Admin
- Posts: 3590
- Joined: Mon Oct 09, 2006 9:36 am
- Location: Scotland - gonnae no slag aff mah Engleesh
- Contact:
Stillborn here. I'd like to say that I'll take a look at the practicality of implementing this, but I suspect that I won't have time.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Hmm, I was afraid of that.
Okay, let's say we look at the possibility of using a shader:
I was looking at this briefly already, using a shader that somebody else posted a while back in this thread.
I managed to get this all running and such, but I came across almost the same issue. Using that shader that sio2 posted (about halfway down the thread) would only apply to the areas of the texture defined as "alpha" by the material type that was passed in as the base when the shader was loaded.
Unless maybe we just need a completely new shader as well-- is it possible to write a shader to handle alpha channel transparency without having the base material set as EMT_TRANSPARENT_ALPHA_CHANNEL? (So for example, if it was set as EMT_TRANSPARENT_VERTEX_ALPHA, as would be needed to pull off the fade effect..?)
<EDIT>
Hmm, I just found this thread- I'm going to see if maybe I can adopt this to my needs.
Okay, let's say we look at the possibility of using a shader:
I was looking at this briefly already, using a shader that somebody else posted a while back in this thread.
I managed to get this all running and such, but I came across almost the same issue. Using that shader that sio2 posted (about halfway down the thread) would only apply to the areas of the texture defined as "alpha" by the material type that was passed in as the base when the shader was loaded.
Unless maybe we just need a completely new shader as well-- is it possible to write a shader to handle alpha channel transparency without having the base material set as EMT_TRANSPARENT_ALPHA_CHANNEL? (So for example, if it was set as EMT_TRANSPARENT_VERTEX_ALPHA, as would be needed to pull off the fade effect..?)
<EDIT>
Hmm, I just found this thread- I'm going to see if maybe I can adopt this to my needs.
It is, you can use any material as a base. However they may give different results. If you gona use transparency you should use some of the transparent materials since they are rendered in different pass by Irrlicht I think. EMT_TRANSPARENT_VERTEX_ALPHA should work fine in this regard.Unless maybe we just need a completely new shader as well-- is it possible to write a shader to handle alpha channel transparency without having the base material set as EMT_TRANSPARENT_ALPHA_CHANNEL? (So for example, if it was set as EMT_TRANSPARENT_VERTEX_ALPHA, as would be needed to pull off the fade effect..?)
What is important that the render function for the transparent scene node is called at the correct time (i.e. after the solid pass) so your material needs to be one of the "transparent" materials. Which one doesn't matter since you can write any effect you want if you use shaders (vertex + texture + overall alpha as well).
Hopefully I'll find some free time to work on it but as I have never created any patches I don't know how this will work out
Hopefully I'll find some free time to work on it but as I have never created any patches I don't know how this will work out
Okay, I've finally gotten the complete desired effect- this is shader free- it's just a custom IMaterialRenderer.
I used some information from this post, but I had to modify things a bit to make it do everything properly- specifically a bunch of the SetTextureStageState() calls (I'm kinda thinking these things should have been modified this way to begin with, actually...?), and the minor adjustments to switch to D3D9.
Please note that a lot of this code is just straight copied, since it's functional the way it was, so I can't take full credit for it- but I'm definitely going to go thru and clean it up to be safer- I just wanted to get an iteration of this out there that is functional so anybody who's come across this issue as well can get things working.
Here's my custom IMaterialRenderer:
And the small bit of code to put it into place to be used by Irrlicht (unmodified from original post):
And a bit of an example of using it:
Unfortunately, as posted in the original thread, there doesn't seem to be a way to get around the need to apply the same texture to both texture layers 0 and 1. This is just because of how Irrlicht automatically calls the Direct3D function SetTexture() with each of the 4 texture layers in the material.
I don't suspect that this is enough of an issue to warrant much action on any of the devs' parts, but at least I'll put my request out there: Can we get implemented a means to define which textures get applied to which Texture Stage in Direct3D? Then we could only define the first texture, and tell Direct3D to use that texture for both Texture Stages, leaving us with our other 3 texture layers to be used as we see fit.
I used some information from this post, but I had to modify things a bit to make it do everything properly- specifically a bunch of the SetTextureStageState() calls (I'm kinda thinking these things should have been modified this way to begin with, actually...?), and the minor adjustments to switch to D3D9.
Please note that a lot of this code is just straight copied, since it's functional the way it was, so I can't take full credit for it- but I'm definitely going to go thru and clean it up to be safer- I just wanted to get an iteration of this out there that is functional so anybody who's come across this issue as well can get things working.
Here's my custom IMaterialRenderer:
Code: Select all
class irrMaterialRendererDualTransparent: virtual public IMaterialRenderer {
public:
IDirect3DDevice9 *mID3DDevice;
IVideoDriver *mDriver;
irrMaterialRendererDualTransparent(IDirect3DDevice9 *dev, IVideoDriver *driver): mID3DDevice(dev),
mDriver(driver) {}
//Wrapped functions
virtual void OnSetMaterial(const SMaterial &material, const SMaterial &lastMaterial, bool resetAllRenderstates,
IMaterialRendererServices *services) {
if (material.MaterialType != lastMaterial.MaterialType ||
material.MaterialTypeParam != lastMaterial.MaterialTypeParam ||
resetAllRenderstates) {
//Set the blend factor
s32 blendValue = (u32)(255 * material.MaterialTypeParam);
mID3DDevice->SetRenderState(D3DRS_TEXTUREFACTOR, (blendValue << 24) | 0x00000000);
//Blend the alpha channel
mID3DDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE);
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1);
mID3DDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE);
//Blend the blend factor
mID3DDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
mID3DDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_BLENDFACTORALPHA);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG1, D3DTA_CURRENT);
mID3DDevice->SetTextureStageState(1, D3DTSS_ALPHAARG2, D3DTA_TEXTURE);
mID3DDevice->SetTextureStageState(2, D3DTSS_COLOROP, D3DTOP_DISABLE);
mID3DDevice->SetTextureStageState(2, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
mID3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
mID3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
mID3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
s32 refValue = (s32)(material.MaterialTypeParam2 * 255);
if (refValue) {
mID3DDevice->SetRenderState(D3DRS_ALPHAREF, refValue);
mID3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
mID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
}
}
services->setBasicRenderStates(material, lastMaterial, resetAllRenderstates);
}
virtual void OnUnsetMaterial() {
mID3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
}
virtual bool isTransparent() const {
return true;
}
};
Code: Select all
irrMaterialRendererDualTransparent mt(driver->getExposedVideoData().D3D9.D3DDev9,driver);
s32 newMat=driver->addMaterialRenderer(&mt);
Code: Select all
IBillboardSceneNode *billMat3=smgr->addBillboardSceneNode(0,core::dimension2d<f32>(9.0f, 9.0f),core::vector3df(0,0,-0.8f));
billMat3->setMaterialType((E_MATERIAL_TYPE)newMat);
ITexture* imgLogo=driver->getTexture("logo1.png");
billMat3->setMaterialTexture(0, imgLogo);
billMat3->setMaterialTexture(1, imgLogo);
billMat3->setMaterialFlag(video::EMF_LIGHTING, false);
billMat3->getMaterial(0).MaterialTypeParam2=0; //Ref value
billMat3->getMaterial(0).MaterialTypeParam=0.5f; //Vertex alpha value
Unfortunately, as posted in the original thread, there doesn't seem to be a way to get around the need to apply the same texture to both texture layers 0 and 1. This is just because of how Irrlicht automatically calls the Direct3D function SetTexture() with each of the 4 texture layers in the material.
I don't suspect that this is enough of an issue to warrant much action on any of the devs' parts, but at least I'll put my request out there: Can we get implemented a means to define which textures get applied to which Texture Stage in Direct3D? Then we could only define the first texture, and tell Direct3D to use that texture for both Texture Stages, leaving us with our other 3 texture layers to be used as we see fit.
I might be able to take a stab at it- but don't get your hopes up, I don't typically dabble in this stuff anymore than I absolutely need for my own purposes.
First question for you tho: Which transparent material type are you referring to? There's no such thing as EMT_TRANSPARENT_ALPHA... Are you talking about perhaps one of these:?
First question for you tho: Which transparent material type are you referring to? There's no such thing as EMT_TRANSPARENT_ALPHA... Are you talking about perhaps one of these:?
- EMT_TRANSPARENT_ALPHA_CHANNEL
- EMT_TRANSPARENT_ALPHA_CHANNEL_REF
- EMT_TRANSPARENT_VERTEX_ALPHA
I have written a material that can use EMT_LIGHTMAP_M2 and EMT_TRANSPARENT_ALPHA_CHANNEL_REF at the same time.
http://irrlicht.sourceforge.net/phpBB2/ ... 641#158641
http://irrlicht.sourceforge.net/phpBB2/ ... 641#158641