Problem with alpha channel when rendering to ARGB texture

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Problem with alpha channel when rendering to ARGB texture

Post by helmuthschmitz »

Hi, first of all, sorry for my bad english. I will try to explain
my problem best i can.


I´m rendering all stuff to a ARGB texture using DirectX device:

Code: Select all

   //note i create a 1x1 window, cause all that i want is use the rendered texture in
   //other application... so i dont need to see irrlicht window in any moment.
   device =   createDevice(EDT_DIRECT3D9, dimension2d<u32>(1, 1), 16, false, false, true);
    
   driver = device->getVideoDriver();
   smgr = device->getSceneManager(); 
  

   rt = driver->addRenderTargetTexture(core::dimension2d<u32>(1920,1080), "RTT1", irr::video::ECF_A8R8G8B8);
   
   t1 = driver->getTexture("test1.png");   
   t2 = driver->getTexture("test3.png");      
   t3 = driver->getTexture("hello.png");   

   d1 = GetTickCount();
So, test1.png is an image with alpha channel. It have a "hole"(a transparent part) in the middle. So, i draw it with:

Code: Select all

void draw()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(10,0,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(1920,0,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(1920,1080,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(10,1080,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
        vertices[i].Color = video::SColor(255, 255, 255, 255); 
   } 

   video::SMaterial m; 
   m.setTexture(0, t1); 
   m.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);      
}
Then i renderize it to that texture called "rt", and save rt to a png file.
So, if a open generated file with gimp(for example) i got this:


Image


Ok, everything is fine until now. But if i draw the same image again, but using
a color with alpha, the background will have the same alpha value. i know all this
have something with ALPHA BLENDING. But i dont know what to do:
See whats happining when i draw the same image over the first draw, but using
a color with alpha(video::SColor(100, 255, 255, 255)):

Image


i draw the second time with:

Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(560,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(560,260,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,260,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 

        //this alpha(100) should alter only this draw, and not the render
        //target background
        vertices[i].Color = video::SColor(100, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t1); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_DST_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}

and i was expecting this:


Image


The main Loop is:

Code: Select all

while(device->run())
       {
		   driver->beginScene(true, true, video::SColor(0,255,255,255));


		   // set render target texture
		   driver->setRenderTarget(rt, true, true, video::SColor(0,255,255,255));

		   // draw whole scene into render buffer
		   smgr->drawAll();            
         
         draw();

         draw2();
        
   		
	      driver->endScene();	
         break;
      }	


      char* bits = (char*)rt->lock();
      if (bits)
      {
         //...
         Here is the part i save the "rt" texture bits to a file
	 //...

         rt->unlock();
      }
What am i doing wrong?

I hope somebody can help me.

Thanks anyway.
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

humm.... i think the images are missing....

Post by helmuthschmitz »

i think the images i did post above are missing... so ...

i´m posting the links again:



http://piczasso.com/i/bumma.png
http://piczasso.com/i/pxzxl.png
http://piczasso.com/i/pl8m8.png

I hope somebody can help me.

:D
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

This should work:

Code: Select all

pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA ... 
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

Hi bitplane,

thanks for helping me. i change "draw2()" function code to:

Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(660,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(660,460,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,460,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
        vertices[i].Color = video::SColor(100, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t1); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE | video::EAS_VERTEX_COLOR);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}

But, i´m still have same results. "draw2()" change alpha value of background.

I never noticed it, because I always used RGB textures as Render Target. So I did not see this problem. but this time using ARGB textures, I can see this problem.

This is getting me crazy.
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

I´m still got NO SUCESS with this issue.

i have been tried every possible combination for pack_texureBlendFunc, but
the results are the same.

I cant see what really is going on
Bear_130278
Posts: 237
Joined: Mon Jan 16, 2006 1:18 pm
Location: Odessa,Russian Federation

Post by Bear_130278 »

Try TGA?
Do you like VODKA???
Image
Image
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

I still haven't actually tried this code, but I imagine that the inverse source alpha and the source alpha don't add up to one because of the vertex colours. You may need to do it in two stages, so one texture blend may not work for this.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

Bear, i got same result with TGA. But, thanks for helping me anyway man.

Bitplane, you are right. What is killing me is vertex colours. Could you explain me better , what do you mean with "two stages" ?

Thanks for helping me again man.

Have a nice day
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

Hi, bitplane, how are yoU?

I was almost killing my self when i have a simple idea.

Not to use EAS_VERTEX_COLOR and EAS_TEXTURE together anymore.

Change the alpha for hole texture "outside the irrlicht"
(this new texture has alpha 100 for each pixel) and
them draw texturing using just EAS_TEXTURE.

Like this:


Code: Select all

void draw2()
{
   video::S3DVertex vertices[4]; 

   vertices[0].TCoords = core::vector2df(0.0f, 0.0f); 
   vertices[0].Pos = core::vector3df(200,100,0); 

   vertices[1].TCoords = core::vector2df(1.0f, 0.0f); 
   vertices[1].Pos = core::vector3df(660,100,0); 

   vertices[2].TCoords = core::vector2df(1.0f, 1.0f); 
   vertices[2].Pos = core::vector3df(660,460,0); 

   vertices[3].TCoords = core::vector2df(0.0f, 1.0f); 
   vertices[3].Pos = core::vector3df(200,460,0);   

   short int index[4];
   for(unsigned int i=0; i<4; i++) 
   { 
        index[i]=i; 
	
	//this dosent metter cause i will not use EAS_VERTEX_COLOR 
        vertices[i].Color = video::SColor(255, 255, 255, 255); 
   } 

    video::SMaterial m; 
    m.setTexture(0, t3); 
    m.MaterialType = EMT_ONETEXTURE_BLEND;
    m.MaterialTypeParam = pack_texureBlendFunc(video::EBF_SRC_ALPHA, video::EBF_ONE_MINUS_SRC_ALPHA,  video::EMFN_MODULATE_1X, video::EAS_TEXTURE);
    m.ZWriteEnable = false; 


   driver->setMaterial(m);    
   driver->draw2DVertexPrimitiveList(vertices, 4, index, 4-2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN);    
}
So, if the hole texture have alpha 100 for each pixel, and i´m using just
EPT_TRIANGLE_FAN for drawing this texture on the render target, everithing will
be alright, right?

No. I have the same results. Now, i think i can kill my self. hahahaha.
The fact is, dosent metter if i´am using EAS_VERTEX_COLOR or if texture has
alpha 100 for each pixel, if i draw it to a ARGB Texture as render target...
the render target will have alpha 100 for each pixel in the drawed area.

I dont know what to do.

Sometimes, i want to make my pc feel pain... a lot of pain. hahahah

So, i pray for somebody help me in this issue;

Thanks
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

hi Folks... just to help you understand better what i wrote above:

Image

Hope somebody can help me
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

the hole image with no legends:

This is what iam seeing right now:

Image
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

By that I mean two render stages in the material renderer, the first blends the alpha channels together, the second blends the vertex colours. I don't think we support this internally (we should IMO)

It would be very simple two-line vertex shader program, or quite painful to do it in the fixed-function pipeline. See this topic for D3D implementations.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
helmuthschmitz
Posts: 11
Joined: Tue Feb 15, 2011 1:56 pm

Post by helmuthschmitz »

Hi bitplane.... thanks for replay again.

I think you right!

I will try your indication.

If i get some success, i will post here.

Thanks again
Post Reply