Texture projection

  • Follow


Hi Guys,

I'm not sure if the subject title is the correct term for what I am
trying to achieve.. and I don't even know if what I am trying to
achieve is possible.. but I think it should be! I will try to explain
what I am trying to do as clearly as I can but apologise now if it's
not very clear :)

I have a textured quad in model space and I have some vertices also in
model space. They are both orientated towards the eye point and the
textured quad is infront of the vertices.

What I want to do is blend/project the texture colours from the quad
on to the vertices behind it.

Now I have used a stencil to ensure only the areas of the screen where
the vertices are present get drawn and everything looks fine whilst I
don't move my eye position.

The problem is of course that once I move the eye position this all
goes horribly wrong as the vertices no longer fall behind the quad in
question that is providing the colour information.

The effect I am aiming for is to ideally never draw the quad itself
but use the colour information from it to project the colours on to
the vertices behind where the textured quad would be. So say the
texture is simply red on the left side and blue on the right side, I
want any vertices behind the left side of the quad to be red.. even if
my current viewing position does not place the vertex directly behind
the quad.

I will always know these 4 things:

1) The model coordinates of the vertices.
2) The model coordinates of the quad.
3) The model coordinates of the eye point to allow the vertices to be
aligned behind the quad (this is the important one!)
4) The model coordinates of the current eye point.

Anybody have any pointers or am I trying to achieve the impossible?

I guess the question is can I blend two things from one view vector
and then display those results despite currently looking from a
completely different view vector?

Cheers

Mark
0
Reply mark.christyuk (6) 2/2/2010 12:02:41 PM

mchristyuk wrote:

> Anybody have any pointers or am I trying to achieve the impossible?

You don't need the intermediate quad, you just project the texture on the 
target geometry. The technique is very old. So old, that the tutorial on 
opengl.org still show screenshots using MWM :)

http://www.opengl.org/resources/code/samples/mjktips/projtex/index.html

Wolfgang


0
Reply Wolfgang 2/2/2010 12:36:48 PM


Hi Wolfgang,

Thanks for the quick reply. I guess the problem in searching these
things out is the "correct terminology" for what I was trying to
achieve.

I will take a dig around the site and see what I can come up with.

Many thanks once again.

Mark
0
Reply mchristyuk 2/2/2010 1:24:43 PM

Hi Wolfgang,

I've got that working now many thanks. But it does lead me of course
on to another question :)

The issue I have is that the vertices I wanted to project on to are
GL_POINTS which when textured only apply a single colour across the
whole of their surface. If I use GL_POINT_SPRITES then the texture
gets shrunk down so that it fits on to the vertex as a whole.

Is there no way to get GL_POINT_SPRITES to behave like a small quad
that would only get textured with a subset of your texture?

Is my only alternative to give in to geometry shaders and get the card
to send out a camera aligned quad in place of the GL_POINT?

Before I was using the textured quad, a stencil and depth buffering
turned off to effectively apply a portion of a texture to a large
GL_POINT.. do you think that can be combined with the texture
projection approach?

Many Thanks

Mark
0
Reply mchristyuk 2/2/2010 2:29:32 PM

mchristyuk wrote:

> Hi Wolfgang,
> 
> I've got that working now many thanks. But it does lead me of course
> on to another question :)
> 
> The issue I have is that the vertices I wanted to project on to are
> GL_POINTS which when textured only apply a single colour across the
> whole of their surface. If I use GL_POINT_SPRITES then the texture
> gets shrunk down so that it fits on to the vertex as a whole.
> 
> Is there no way to get GL_POINT_SPRITES to behave like a small quad
> that would only get textured with a subset of your texture?
> 
> Is my only alternative to give in to geometry shaders and get the card
> to send out a camera aligned quad in place of the GL_POINT?
> 
> Before I was using the textured quad, a stencil and depth buffering
> turned off to effectively apply a portion of a texture to a large
> GL_POINT.. do you think that can be combined with the texture
> projection approach?

Points are not really suited for projective texturing. They lack something 
more important than area, namely a directed surface. You could project the 
texture from anywhere, so how to decide in which direction to apply on a 
point.

Simply drawing screen aligned quads won't help either. Try to imagine what 
happens if the projective point of origin is in the plane defined by the 
quad: This situation actually has no solution.

So you need to rethink your concept a little bit. I think you want to draw 
spheres instead of points, and this is, what I suggest you do. Don't worry 
about the vertex count. As long as you stay under a million and turn back 
face culling on you should be just fine :)


Wolfgang
-- 
OpenGL tip #42:
How to exactly map texture texels to screen pixels: 
<http://preview.tinyurl.com/cgndc8>
0
Reply Wolfgang 2/2/2010 8:53:08 PM

Hi Wolfgang,

Yes points are a problem. The issue I have is that I am dealing with
point clouds in the 10's of millions numbers which is why I was keen
on a solution to points. The direction of the surface is not an issue
with the application I am working on..

I'm going to investigate your sphere suggestion as I will only be
wanting to implement this "texturing" when at very close quarters to
the vertices so the number count should be much lower.

Many thanks once again for the hints and guidance :)

Cheers

Mark
0
Reply mchristyuk 2/2/2010 9:02:52 PM

On Feb 2, 10:02=A0pm, mchristyuk <mark.christ...@gmail.com> wrote:
> Hi Wolfgang,
>
> Yes points are a problem. The issue I have is that I am dealing with
> point clouds in the 10's of millions numbers which is why I was keen
> on a solution to points. The direction of the surface is not an issue
> with the application I am working on..
>

Stencil should work. Draw your points with
stencil enabled and write a stencil value
there (eg. '1').

Now switch to 2d and draw a quad with write
enabled only where stencil value is 1


--
<\___/>
/ O O \
\_____/  FTB.

http://www.topaz3d.com/  - New 3D editor for real time simulation
0
Reply fungus 2/4/2010 11:23:57 AM

Hi Fungus,

Thanks for the pointer there. I've got it working now with the spheres
but as you can expect performance is a little poor.

I'm hoping to move the rendering over to quads at some point in the
future so this seems like a good enough time to start that process.

Cheers

Mark
0
Reply mchristyuk 2/4/2010 9:02:17 PM

Hi Fungus,

I've had the texture projection working well in the fixed pipe line
but wanted to move it over to the shaders to allow me a little more
versatility. I know this is possible as there are plenty of examples
and talk from people who have done this. However despite following
these examples to the letter my rendering doesn't seem to work out
right.. I think I know where the problem is but I'm unsure of how to
solve it and was hoping you could again give me a pointer with your
greater knowledge of all things OpenGL? :)

With my fixed pipeline I do the following:

   gl.glMatrixMode(GL.GL_TEXTURE);
   gl.glLoadIdentity();
   gl.glTranslatef(0.5f, 0.5f, 0.0f); //Bias
   gl.glScalef(0.25f, -0.25f, 1.0f); //Scale
   glu.gluPerspective(45, frameX / frameY, 0.1f, distance * 2.0f);
 
glu.gluLookAt(0,0,0,imageCentre.x,imageCentre.y,imageCentre.z,up.x,up.y,up.z);

   float eyePlaneS[] = new float[]{1.0f, 0.0f, 0.0f, 0.0f};
   float eyePlaneT[] = new float[]{0.0f, 1.0f, 0.0f, 0.0f};
   float eyePlaneR[] = new float[]{0.0f, 0.0f, 1.0f, 0.0f};
   float eyePlaneQ[] = new float[]{0.0f, 0.0f, 0.0f, 1.0f};

   //set up texture generation mode and set the corresponding planes
   gl.glTexGeni(GL.GL_S, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_S, GL.GL_EYE_PLANE, eyePlaneS, 0);
   gl.glTexGeni(GL.GL_T, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_T, GL.GL_EYE_PLANE, eyePlaneT, 0);
   gl.glTexGeni(GL.GL_R, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_R, GL.GL_EYE_PLANE, eyePlaneR, 0);
   gl.glTexGeni(GL.GL_Q, GL.GL_TEXTURE_GEN_MODE, GL.GL_EYE_LINEAR);
   gl.glTexGenfv(GL.GL_Q, GL.GL_EYE_PLANE, eyePlaneQ, 0);

   gl.glEnable(GL.GL_TEXTURE_GEN_S);
   gl.glEnable(GL.GL_TEXTURE_GEN_T);
   gl.glEnable(GL.GL_TEXTURE_GEN_R);
   gl.glEnable(GL.GL_TEXTURE_GEN_Q);

As I said this works fine.. from my understanding to achieve the same
in the shaders I have to:
1) Access the texture matrix that I setup in the above code
2) Transform the texture coordinates in the vertex shader
3) Apply the texture in the fragment shader

I think it is my step 2 that is going wrong.. and I can see what's
wrong.. but can't quite get my head round why or what to do.

Here is the code for my fragment shader:

   uniform sampler2D	tex;
   void main()
   {
       // Suppress the reverse projection.
       if( gl_TexCoord[0].q>0.0 )
       {
	gl_FragColor = texture2DProj(tex,gl_TexCoord[0]);
       }
   }

And here is my vertex shader:

   void main()
   {
	vec4 ecPosition=  gl_Vertex * gl_ModelViewMatrix;
                 gl_Position = ftransform();
                 gl_TexCoord[0] = gl_TextureMatrix[0] * ecPosition;
   }

The data I am displaying is in an Octree and I glTranslate to each
node before rendering it. The shader is setup before the Octree is
rendered.

1) If I use this vertex shader then I have a weird local projection
problem applied on each node of the Octree and the texture is repeated
across each node rather than across the whole tree as one texture.
2) If I substitute gl_Position for ecPosition then the texture is
applied in a global fashion to the Octree (correct) but moves and
rotates with the camera movement.
3) If I substitue gl_Vertex for ecPosition then the texture is visible
in the correct projection.. but applied to each node locally rather
than over the whole data set globally.. e.g. I have the same texture
repeating again and again at a fraction of its correct size on each
Node.

All the examples I have seen generate the TexCoord[0] value using
gl_Vertex * gl_ModelViewMatrix.. but it just doesn't work for me...

What's the obvious thing I appear to have missed?

Cheers

Mark
0
Reply mchristyuk 2/9/2010 3:41:09 PM

8 Replies
525 Views

(page loaded in 0.132 seconds)

Similiar Articles:













7/25/2012 9:04:53 AM


Reply: