Transparency, texture alpha * vertex alpha

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
grafikrobot
Posts: 44
Joined: Wed Dec 26, 2007 11:42 pm

Transparency, texture alpha * vertex alpha

Post by grafikrobot »

I've seen various discussions as to how to achieve combined texture alpha and vertex alpha. I'm not sure why this isn't supported by the EMT_TRANSPARENT_ALPHA_CHANNEL material and if the core devs think that it should support using the vertex alpha. But this is a feature that is prevalent, and assumed, in all the projects I've used a 3D engine on.

So I finally had time, and the requirement, to implement that feature. Here are the patches for D3D9, OpenGL, and OpenGL-ES1 to add vertex alpha to the alpha channel material:

Code: Select all

--- CD3D9MaterialRenderer.h
+++ CD3D9MaterialRenderer.h
@@ -307,9 +307,10 @@
 		{
 			pID3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_MODULATE );
 			pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
-			pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_CURRENT );
-			pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_SELECTARG1 );
+			pID3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG2, D3DTA_DIFFUSE );
+			pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAOP,   D3DTOP_MODULATE );
 			pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE );
+			pID3DDevice->SetTextureStageState( 0, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE );
 
 			pID3DDevice->SetTextureStageState( 1, D3DTSS_COLOROP,   D3DTOP_DISABLE );
 			pID3DDevice->SetTextureStageState( 1, D3DTSS_ALPHAOP,   D3DTOP_DISABLE );

Code: Select all

--- COpenGLMaterialRenderer.h
+++ COpenGLMaterialRenderer.h
@@ -348,12 +348,14 @@
 			|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
 		{
 			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_EXT);
+			
 			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_EXT, GL_MODULATE);
 			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_EXT, GL_TEXTURE);
 			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_EXT, GL_PREVIOUS_EXT);
 
-			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_REPLACE);
+			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA_EXT, GL_MODULATE);
 			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA_EXT, GL_TEXTURE);
+			glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_EXT, GL_PRIMARY_COLOR_EXT);
 
 			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 			glEnable(GL_BLEND);

Code: Select all

--- COGLESMaterialRenderer.h
+++ COGLESMaterialRenderer.h
@@ -306,12 +306,14 @@
 			|| material.MaterialTypeParam != lastMaterial.MaterialTypeParam )
 		{
 			glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+			
 			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
 			glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
-			glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
+			glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
 
-			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+			glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
 			glTexEnvf(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
+			glTexEnvf(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_PRIMARY_COLOR);
 
 			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 			glEnable(GL_BLEND);
NOTE: These are all based on the ogl-es branch which is what I currently use. But they should apply to the other versions equally.

Which brings up the basic question... Is adding vertex-alpha support to the alpha texture materials something people want? Or is having some separate materials preferred? I ask so that I can prepare some better patches to submit for integration.
[/code]
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Cool patch. There was some similar D3D code posted a while back.

Any idea what the performance impact of this change is? If it's not too much then I guess the transparent alpha channel renderer should do vertex alpha, but the _ref one shouldn't because it currently doesn't need to be z-sorted.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
grafikrobot
Posts: 44
Joined: Wed Dec 26, 2007 11:42 pm

Post by grafikrobot »

bitplane wrote:Any idea what the performance impact of this change is?
It should be near zero, since it's still using only the fixed function single TU. Also since the hardware is still generating the RGBA fragments for the poly it's not adding to that either. Literally the only extra is that it does the modulate operation, but the hardware likely uses the same function without the modulate anyway. From my testing there is no perceptible performance difference, but I haven't done large scale perf tests to really tell if there's an impact. My game still runs at 1200FPS on Windows, and 40FPS on the 1st-gen iPod-Touch (which is slowest of the bunch). But it's a low poly use case so I can't claim it's representative ;-)
bitplane wrote:If it's not too much then I guess the transparent alpha channel renderer should do vertex alpha, but the _ref one shouldn't because it currently doesn't need to be z-sorted.
Ah, right.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The question that I see is how we should cope with toggling the vertex alpha on and off. Yes, I know, we can use the vertex color... But since we had the alpha modes separated until now it might make sense to keep those materials untouched and add a new one combining the two. Or we use some flag to toggle the type of alpha value.
grafikrobot
Posts: 44
Joined: Wed Dec 26, 2007 11:42 pm

Post by grafikrobot »

Truthfully I think adding more materials for such small, standard, features seems like a loosing proposition. Adding a flag seems like a better medium term choice. But ideally I'd merge the two alpha materials into one plus two options: EAO_ALPHA_REF (to turn on/off the alpha ref), and EAO_ALPHA_VERTEX (to turn on/off the vertex alpha).
Post Reply