Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Cuting an area out depending on another texture  (Read 1844 times)

0 Members and 1 Guest are viewing this topic.

Karleon

  • Newbie
  • *
  • Posts: 18
    • View Profile
Cuting an area out depending on another texture
« on: March 22, 2013, 10:57:01 pm »
Hello,

I have a problem that is giving me hard time.



Here you can see the scenario (sorry for the eye-hurting textures), and at the bottom, the field of view applied on the scenario.
As you can see, the wall that should be visible, are not, giving a really weird look to the scene. I need to cut from the shadow texture the area of the visible walls.

One solution that I thought about its the following:

The idea should be to check the pixel just below the walls. If the pixels are NOT darkened by the shadow, the area above should be deleted from the shadow texture.

Pretty much, if the checked area (ONLY check for the pixels just below walls) in the shadow texture is not obscured, then make the X pixels above that point transparent.

I'm really lost and I don't know how to deal with this.. I though that shaders may be useful here, but I have no experience with them, and I don't really know if they fit this task.


Do you guys have any ideas?


Thanks,

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Cuting an area out depending on another texture
« Reply #1 on: March 23, 2013, 08:50:33 am »
I don't know how you handle your shadows, but wouldn't it be simpler if you cast the shadow from the top of the wall directly, so that you wouldn't have to correct it afterwards?
Laurent Gomila - SFML developer

Karleon

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Cuting an area out depending on another texture
« Reply #2 on: March 23, 2013, 03:10:47 pm »
I have tried that solution.

Everything is 2d in the map. If I cast the shadow from the top of the wall I get undesirable results like incorrect field of view over corners.

I have been fiddling with shaders (never used them before), and I think I already know how to solve it.
If I manage to do solve this problem using shaders I will post the result in case anyone is curious/need a similar solution.

I'll let you know once I'm done.

Karleon

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: Cuting an area out depending on another texture
« Reply #3 on: March 24, 2013, 02:19:19 am »
Ok, here is the solution I came up with.
Not claiming is the best solution, since its the first time I ever use shaders and I have been extremelly confused in the last couple of hours:



First of all I created a mask (the colored lines) that pretty much locates of all the candidates for shadow to be removed: Walls that are just above an empty cell.

The purple line indicates how tall the wall is, you can put this like higher or lower depending of the type of cell, so it won't mess up different walls depending on their height.

When I draw the walls I use the following shader:

uniform sampler2D texture;                //Texture to draw
uniform sampler2D filterTexture;        //Texture of the masks
uniform vec2 textureSize;                   //Size of the texture
uniform float cellSize;                         //Size of a cell in pixels
uniform sampler2D shadowTexture;  //Texture were the shadows are drawn



void main()
{
        vec2 position;
        vec4 filterPixel;
        vec4 shadowPixel;

        bool aboveRed=false;
        bool belowPurple=false;


        vec4 pixel = texture2D(texture, gl_TexCoord[0].xy );

       
       
        for( float i=0 ; i<=cellSize*2 ; i++)
        {
                position = gl_TexCoord[0].xy;
                position.y = position.y - (i/textureSize.y);
                filterPixel = texture2D( filterTexture, position );
               
                position.y = position.y + (1/textureSize.y);
                shadowPixel = texture2D( shadowTexture, position );
               
                if (shadowPixel == 0){
                        if( filterPixel.r == 1.0 && filterPixel.b == 0.0 )
                        {
                                aboveRed=true;
                        }
                }
               
                position = gl_TexCoord[0].xy;
                position.y = position.y + (i/textureSize.y);
                filterPixel = texture2D( filterTexture, position );
               
                if(filterPixel.r == 1.0 && filterPixel.b == 1.0)
                {
                        belowPurple = true;
                }
                if(belowPurple && aboveRed){
                        pixel.a = 0;
                        break;
                }
        }              
        gl_FragColor = pixel;
               
}

 

This shader pretty much looks for a red pixel (in the mask) bellow the current pixel within a cellSize*2 range. If it finds the red line, it check the shadow in the pixel just below it.
It also looks for a purple pixel above the current pixel within the same range.

If the current pixel meets this two conditions, the current pixel is drawn on the screen.


I don't know if this is a really dirty way to solve the problem, since, as I said, I never used shaders and i'm still pretty ignorant of it's usage.

If someone more knowledgeable on SLGL can comment on the shader, and also point me in the right direction for a good tutorial which could be useful for SFML users, that would be awesome!