Jump to content
  • Advertisement
Sign in to follow this  
Servant of the Lord

OpenGL OpenGL using one texture as the alpha mask of another

This topic is 1666 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

If I'm drawing one texture, and I want to use another texture as the alpha channel for it, and permit the alpha mask texture to be rotated 90 degrees and flipped horizontally or vertically, how would I go about doing that?

 

I can pass in the mask texture to the fragment shader, and pass in a float with the 90 degree rotations in it, and manually rotate in the GLSL shader like this:

vec2 RotateTexCoord(vec2 pos, vec2 rotation, bool flipHorizontally, bool flipVertically)
{
    //Mirror (horizontally, vertically, or both).
    if(flipHorizontally)
    {
        pos.x = (1.0 - pos.x);
    }
    if(flipVertically)
    {
        pos.y = (1.0 - pos.y);
    }

    //Rotate in 90 degree increments.
    
    if(rotation > (270 - 45))
    {
        //Swap x and y (same reason as above).
        float temp = pos.y;
        pos.y = pos.x;
        pos.x = temp;

        pos.x = (1.0 - pos.x);
    }
    else if(rotation > (180 - 45))
    {
        pos.x = (1.0 - pos.x);
        pos.y = (1.0 - pos.y);
    }
    if(rotation > (90 - 45))
    {
        //Swap width and height (since image is turned on side)
        //int alteredWidth = this->GetHeight();
        //int alteredHeight = this->GetWidth();

        float temp = pos.x;
        pos.x = pos.y;
        pos.y = temp;

        pos.y = (1.0 - pos.y);
    }
}

Questions:

A) Does OpenGL already have functionality built-in for using one texture as the alpha mask of another?

B) When passing in a second texture to GLSL, are there features built in for rotating the texture coordinate for the second texture separate from the texture coordinate of the first texture?

C) This simple RotateTexCoord() function has 5 if() statements... that's 5 branches per fragment drawn for a trivial operation. How could it be optimized?

Share this post


Link to post
Share on other sites
Advertisement


A) Does OpenGL already have functionality built-in for using one texture as the alpha mask of another?

B) When passing in a second texture to GLSL, are there features built in for rotating the texture coordinate for the second texture separate from the texture coordinate of the first texture?

C) This simple RotateTexCoord() function has 5 if() statements... that's 5 branches per fragment drawn for a trivial operation. How could it be optimized?

 

A) Don't think so

B) Don't think so

C) Use a matrix to represent the transformation. Calculate the 3x2 transformation matrix on the CPU and pass it into the vertex shader as a couple of vec3's, transforming the UVs should boil down to a couple of dot products. If you're not already doing so, make sure you do the transformation on the UVs in the vertex shader, not in the pixel shader.

Share this post


Link to post
Share on other sites

C) Use a matrix to represent the transformation. Calculate the 3x2 transformation matrix on the CPU and pass it into the vertex shader as a couple of vec3's, transforming the UVs should boil down to a couple of dot products.

 

I don't know matrix math yet - what's the matrix for a 180 degree rotation (around the Z axis I guess, since they are texture coordinates)? Can matrices be used for flipping horizontally or vertically as well? Is that a 180 rotation around the X axis for vertical flipping and 180 around Y axis for horizontal?

 

If you're not already doing so, make sure you do the transformation on the UVs in the vertex shader, not in the pixel shader.

 

Well, the texture being drawn is already rotated by OpenGL - I don't yet have a need for a vertex shader. Are you saying rotate the texture coordinates of the alpha mask image in the vertex shader? So the vertex shader would rotate two separate textures at once?

Edited by Servant of the Lord

Share this post


Link to post
Share on other sites

I don't know matrix math yet


I can't stress enough how much you should stop everything you're doing and learn this. A game developer that doesn't have at least a decent grasp of linear algebra in Euclidean space is much akin to a surgeon who doesn't know how to hold a scalpel. smile.png
 

what's the matrix for a 180 degree rotation (around the Z axis I guess, since they are texture coordinates)?


Assuming 2D texture coordinates and no need to apply an offset, you can use a 2x2 matrix here (offsets would require a 3x3 affine transformation matrix):

| -1, 0 |
| 0, -1 |
 

Can matrices be used for flipping horizontally or vertically as well? Is that a 180 rotation around the X axis for vertical flipping and 180 around Y axis for horizontal?


Yes.

vertical mirror:
| 1 0 |
| 0 -1 |

or

horizontal mirror:
| -1 0 |
| 0 1 |

You can perform a great many operations with linear transformations which is what a matrix models.
 

Well, the texture being drawn is already rotated by OpenGL - I don't yet have a need for a vertex shader. Are you saying rotate the texture coordinates of the alpha mask image in the vertex shader? So the vertex shader would rotate two separate textures at once?


You must have a vertex shader to use a pixel shader. Your vertex shader is likely just doing passthru (copying its inputs directly to the outputs). The pixel shader is then receiving the original UVs post-interpolation and rotating them. There's usually no reason you can't do that rotation in the vertex shader so that you don't have to re-evaluate the rotation for every pixel fragment.

The vertex shader can use whatever vertex attributes it wants so there's no reason it couldn't rotate both or either of the incoming UVs (assuming they're separate). If the source texture and mask are both rotated the same then you only need a single UV attribute.

Vertex shader pseudocode:

vsout_position = vsin_position
vsout_texcoord0 = rotate(vsin_texcoord0)
vsout_texcoord1 = rotate(vsin_texcoord1)

Pixel shader pseudocode:

psout_color = sample(source_texture, psin_texcoord0)
psout_color *= sample(mask_texture, psin_texcoord1)

Again, just using a single texcoord if both textures use the same coordinates.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!