Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 11

Thread: GPU Gems Texture Bomb Shader

  1. #1
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    GPU Gems Texture Bomb Shader

    Hi,

    I've been working on a GLSL version of the GPU Gems Texture Bomb shader, and have run into a slight problem. Here is my Fragment Shader code:

    Code :
    uniform sampler2D Texture;
    uniform sampler2D RandomTexture;
    uniform vec2 Scale;
     
    void main()
    {
    	vec2 xy =  gl_TexCoord[0].xy;
    	vec4 px = texture2D(Texture, xy);
     
    	vec2 scaledUV = xy * Scale;
    	vec2 cell = floor(scaledUV);
    	vec2 offset = scaledUV - cell;
     
    	vec2 randomUV;
    	vec4 random, image;
     
    	for (int i = -1; i <= 0; i++) {
    		for (int j = -1; j <= 0; j++) {
    			vec2 cell_t = cell + vec2(i, j);
    			vec2 offset_t = offset - vec2(i, j);
    			randomUV = cell_t.xy * vec2(0.037, 0.119);
    			random = texture2D(RandomTexture, randomUV);
    			image = texture2D(Texture, offset_t - random.xy);
    			if (image.a > 0.0) {
    				gl_FragColor = image;
    			} else {
    				gl_FragColor = vec4(0.0);
    			}
    		}
    	}
    }

    I'm currently on section '20-1. Extending the Sampling to Four Cells'

    This is what I'm getting (the star glyph has a transparent background):



    Can anyone spot any obvious mistakes in my code?

    Cheers guys,

    a|x
    http://machinesdontcare.wordpress.com


    PS
    Here's the star glyph (it's very hard to see because it's white, on a white background, but it IS there, honestly):




  2. #2
    Intern Contributor
    Join Date
    Feb 2000
    Location
    Germany
    Posts
    95

    Re: GPU Gems Texture Bomb Shader

    You shouldn't output a black pixel (gl_FragColor = vec4(0.0) when you actually want to discard it.
    So use discard instead.

  3. #3
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: GPU Gems Texture Bomb Shader

    Hi Inquisitor,

    thanks for getting back to me!
    Good point. I've changed the code as you suggest, but oddly it still doesn't work (although now in a slightly different way).

    I now get:


    Any ideas?

    a|x

  4. #4
    Intern Newbie
    Join Date
    Nov 2007
    Location
    Scotland
    Posts
    30

    Re: GPU Gems Texture Bomb Shader

    I don't have time to have an in depth look at it at the moment but reading the next section "20.1.4 Image Priority" starts with it saying:
    There's something not quite right.
    Have you simply tried moving on to the next section "Example 20-2. Adding Image Priority" where everything looks a lot better?

  5. #5
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: GPU Gems Texture Bomb Shader

    Good point 4fingers.

    I have tried the next bit too, but this doesn't seem to help either.

    Hmm...

    a|x

  6. #6
    Intern Newbie
    Join Date
    Nov 2007
    Location
    Scotland
    Posts
    30

    Re: GPU Gems Texture Bomb Shader

    One of the main things you have to remember to do is set the wrap parameter for texture coordinates to GL_CLAMP.
    Code :
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    You should be able to check this by setting the scale to 1 allowing just one grid to be seen. There should then be one star visible with the shape being cut off at the edges.
    Annoyingly it doesn't mention this till half way down the page at the "20.2 Technical Considerations" section:
    The wrap mode for the texture image should be set to CLAMP. Otherwise, we'll see ghost samples where we shouldn't. Alternatively, we can clamp the coordinates to the range [0..1]. Most GPUs have hardware to do this at no cost.
    Does that help at all?

  7. #7
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: GPU Gems Texture Bomb Shader

    Hi 4fingers,

    ah.. I missed that bit! I can't actually change the texture mode in the app I'm using, but I can clamp the sample position to the 0>1 range and see if that sorts things out.

    Thanks for the tip,

    a|x

  8. #8
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: GPU Gems Texture Bomb Shader

    Just tried the following code, which still doesn't work:

    Code :
    uniform sampler2D Texture;
    uniform sampler2D RandomTexture;
    uniform vec2 Scale;
     
    void main()
    {
    	vec2 xy =  gl_TexCoord[0].xy;
    	vec4 px = texture2D(Texture, xy);
     
    	vec2 scaledUV = xy * Scale;
    	vec2 cell = floor(scaledUV);
    	vec2 offset = scaledUV - cell;
     
    	vec2 randomUV, randomPlusOffset;
    	vec4 random, image;
    	float priority = -1.0;
     
    	for (int i = -1; i <= 0; i++) {
    		for (int j = -1; j <= 0; j++) {
    			vec2 cell_t = cell + vec2(i, j);
    			vec2 offset_t = offset - vec2(i, j);
    			randomUV = cell_t.xy * vec2(0.037, 0.119);
    			random = texture2D(RandomTexture, randomUV);
    			randomPlusOffset = offset_t - random.xy;
    			randomPlusOffset.x = clamp(0.0,1.0,randomPlusOffset.x);
    			randomPlusOffset.y = clamp(0.0,1.0,randomPlusOffset.y);
    			image = texture2D(Texture, randomPlusOffset);
    			if (random.a > priority &amp;&amp; image.a > 0.0) {
    				gl_FragColor = image;
    				priority = random.w;
    			} else {
    				gl_FragColor = vec4(0.0);
    				//discard;
    			}
    		}
    	}
    }

    I may just give up on this implementation, and try adapting the Orange Book texture bomb shader. I'm really interesting in the Voronoi implementation mentioned later on on the page, which I guess could be tweaked to fit in with the Orange Book method.

    a|x

  9. #9
    Junior Member Regular Contributor
    Join Date
    Nov 2007
    Location
    London UK
    Posts
    242

    Re: GPU Gems Texture Bomb Shader

    I've just found someone else's GLSL adaptation of the same code. This works nicely, so all is now cool.

    Code :
    // This is a fragment shader to show texture bombing.  It uses
    //   a random texture to place 3D polka dots of random color
    //   in random locations on the model.  For more information
    //   on Texture Bombing techniques see the following books:
    //      1.  Texturing and Modeling - A Procedural Approach
    //         Copyright 1998 by Ebert et al.
    //      2.  GPU Gems Copyright 2005 
    //         Edited by Randima Fernando
    //
    // author(s): Joshua Doss
    //
    // Copyright (C) 2002-2006  3Dlabs Inc. Ltd.
    //
    // See 3Dlabs-License.txt for license information
    //
     
    varying vec3 MCPosition;
     
    //Create uniform variables so dots can be spaced and scaled by user
    uniform float Scale, DotSize;
    uniform sampler2D RandomTex;
     
    // Create colors as uniform variables so they can be easily changed
    uniform vec4 BGColor, PolkaDotColor;
    uniform vec3 DotOffset;
    uniform vec2 PositionTextureMultiplier;
     
    void main(void)
    {
    	float radius2;
    	vec2  randomXY;
    	vec3  finalcolor = BGColor.xyz;
    	vec3  dotSpacing = vec3(Scale);
    	vec3  scaledXYZ = MCPosition * dotSpacing;
    	vec3  cell = floor(scaledXYZ);
    	vec3  offset = scaledXYZ - cell;
    	vec3  currentOffset;
    	vec4  random;
     
    	float priority = -1.0;
    	for(float i = -1.0; i <= 0.0; i++)
    	{
    		for(float j = -1.0; j <= 0.0; j++)
    		{
    			for(float k = -1.0; k <= 0.0; k++)
    			{
    				vec3 currentCell = cell + vec3(i, j, k);
    				vec3 cellOffset = offset - vec3(i, j, k);
    				randomXY = currentCell.xy * PositionTextureMultiplier + currentCell.z * 0.003;
    				random = texture2D(RandomTex, randomXY);
                    	currentOffset = cellOffset - (vec3(0.5, 0.5, 0.5) + vec3(random));
     
    				radius2 = dot(currentOffset, currentOffset);
    				if(random.w > priority &amp;&amp; radius2 < DotSize)
    				{
    					finalcolor = texture2D(RandomTex, randomXY).xyz;
    					priority = random.w;
    				}
    			}
    		}
    	}
     
    	gl_FragColor = vec4(finalcolor, 1.0);
    }

    Thanks for all your advice, guys!
    The key turned out to be to create a variable for the final output color, and set it before the nested loops.

    Thanks again,

    a|x

  10. #10
    Intern Newbie
    Join Date
    Nov 2007
    Location
    Scotland
    Posts
    30

    Re: GPU Gems Texture Bomb Shader

    Yeah, that method gets rid off the texture lookup and applies a procedural texture instead. This is fine if primitive shapes is all that your want.

    In the Book "Texturing and Modeling - A Procedural Approach" it manages to use a procedural texture of a star, but creating anything with a more complex design and your better off using a texture. So before you go I thought I might share with you my implementation that prevents the texture from displaying the repeating artefacts despite having GL_TEXTURE_WRAP set to GL_REPEAT.

    Here is what you might expect to see with nothing stopping the texture from wrapping:

    Then with the added checks it looks like this:

    All it does is tell the shader to ignore placing the colour once its in the area outside the texture being placed. By doing these checks it also reduces the number of texture calls for each cell:
    Code :
    uniform sampler2D BombingTexture;
    uniform sampler2D RandomTexture;
     
    void main() {
        vec4 random, colour;
        vec2 randomUV, current, cell_t, offset_t;
        float i, j;
        bool checkX, checkY;
     
        vec2 scaledUV = gl_TexCoord[0].xy * 20.0;
        vec2 cell = floor(scaledUV);
        vec2 offset = scaledUV - cell;
     
        float priority = -1.0;
        colour = vec4(gl_TexCoord[1]);
        for (i = -1.0; i <= 0.0; i++) {
          for (j = -1.0; j <= 0.0; j++) {
                current = vec2(i, j);
                cell_t = cell + current;
                offset_t = offset - current;
     
                randomUV = cell_t * vec2(0.037, 0.119);
                random = texture2D(RandomTexture, randomUV);
     
                if(i == 0.0) checkX = (offset.x>random.x);
                else checkX = (offset.x<random.x);
                if(j == 0.0) checkY = (offset.y>random.y);
                else checkY = (offset.y<random.y);
     
                if(checkX &amp;&amp; checkY){
                    if ( texture2D(BombingTexture, offset_t - random.rg).a > 0.0 &amp;&amp; 
                        random.b > priority) {
                        colour = vec4(random.rgb, 1.0);
                        priority = random.b;
                    }
                }
            }
        }
        gl_FragColor = colour;
    }
    The only thing you need to watch out for is that you have to have the same texture cordinate system as me. This is my current set up:
    Top Left = (0,1) | Top Right = (1,1)
    Bottom Left = (0,0) | Bottom Right = (1,0)
    If you have a different set up and cant change it on the OpenGL side then you will have to change some of the code on the fragment shader to account for the different coordinate system.

    Anyway I hope this is as much use as it was for me.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •