Projection-state of gl_Vertex in GLSL

  • Follow


Hi
I'm working on a small vertex shader using GLSL for my skydome. It 
affects color to vertices according their y. It makes a linear gradient 
between 2 colors.

The problem is:
- I am transferring 4 uniforms to pass top color (4f) and y (1f) and 
bottom color (4f) and y (1f)
- my formula to get the color according altitude is:
color4f=bottomcolor4f+(topcolor4f-bottomcolor4f)* 
(gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f)

So what bottomy1f and topy1f should I pass to the shader to be at the 
same "state of projection" than gl_Vertex.y (I guess... I am sure that 
it is not the original - by "original", I mean the one in the FBO - y of 
the top and bottom vertices) or perhaps there is something different 
from gl_Vertex to get the original 3D-coordinate in the shader.

Thanks
Cathy
0
Reply Cathy 3/13/2009 8:04:08 AM

No answer? Is that a hard question or is it hard to understand what I want?
0
Reply Cathy 3/13/2009 3:24:03 PM


Cathy wrote:

> No answer? Is that a hard question or is it hard to understand what I
> want?

This is not a immediate response hotline. Give some people a chance to read
your post. And of those people at least one wonders, why you don't simply
use a 1D texture in clamping mode and apropriate texture coordinates...

Wolfgang

-- 
OpenGL tip #42:
How to exactly map texture texels to screen pixels:
<http://preview.tinyurl.com/cgndc8>


0
Reply Wolfgang 3/13/2009 4:23:05 PM

Cathy wrote:
> Hi
> I'm working on a small vertex shader using GLSL for my skydome. It 
> affects color to vertices according their y. It makes a linear gradient 
> between 2 colors.
> 
> The problem is:
> - I am transferring 4 uniforms to pass top color (4f) and y (1f) and 
> bottom color (4f) and y (1f)
> - my formula to get the color according altitude is:
> color4f=bottomcolor4f+(topcolor4f-bottomcolor4f)* 
> (gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f)
> 
> So what bottomy1f and topy1f should I pass to the shader to be at the 
> same "state of projection" than gl_Vertex.y 

Answering your next question (next post) more than this; no, the 
question is not clear to me and I specifically don't understand the last 
part of the sentence above. But then there's a lot of OpenGL and GLSL 
not clear to me :( And now that Wolfgang has got involved, I really 
should keep quiet. On the other hand, /I/ might learn something.

Any of the following do what the first line makes explicit:

gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_Position = ftransform();

so can you pass (two?) untransformed vertices that mark the beginning 
and end of the linear interpolation, transform them, and then 
interpolate based on gl_Position.y1, gl_Position.y2?

But this would be applied only to vertices that specify primitives.

So maybe you need to work in the fragment shader?

(I guess... I am sure that
> it is not the original - by "original", I mean the one in the FBO - y of 
> the top and bottom vertices) or perhaps there is something different 
> from gl_Vertex to get the original 3D-coordinate in the shader.
> 

Best regards,

Jon C.

0
Reply Jonathan 3/13/2009 4:51:57 PM

> This is not a immediate response hotline. Give some people a chance to read
> your post.

Shame on me, Wolfgang, I am so used to have an answer within the hour 
and I was so sure that if understood, this question is an easy-to-answer 
one for those who know that I was sincerely wondering if the 
explanations of my problem were not clear enough.

> And of those people at least one wonders, why you don't simply
> use a 1D texture in clamping mode and apropriate texture coordinates...

In fact, I decided not to use texture, because I was sure it was more 
efficient with just colors and because it is really easier to change the 
gradient of the sky according the time of the day just shifting the 
values of the 2 vec4 uniforms than creating another texture.

I'm gonna wait for the answer, sorry for my impatience.

Cathy
0
Reply Cathy 3/13/2009 5:06:22 PM

Hi John and thanks to try to answer even if you are not sure, I do the 
same when I have an idea (and it is worse for me, my skill is really 
low). I do believe that's the way NGs work.

> I specifically don't understand the last 
> part of the sentence above.

As I said later on, I am quite sure that the GLSL gl_Vertex.x, 
gl_Vertex.y and gl_Vertex.z are not the values passed via the OpenGL 
glVertex3f(x,y,z), they were already transformed.
I tried with this GLSL vertex shader:
"
uniform float altmin;
uniform float altmax;
uniform vec4 colmin;
uniform vec4 colmax;
void main(void)
{
gl_Position=ftransform();
gl_BackColor=colmin+(colmax-colmin)*(gl_Vertex.y-altmin)/(altmax-altmin);
}
"
And the result is quite... psychedelic:
http://img10.imageshack.us/img10/7854/psyche.jpg

So I guess the GLSL gl_Vertex received some transformations from the 
vector passed to OpenGL via VBO or glVertex(,,) as altmin and altmax are 
respectively the y-component of the bottom and top vertices of the dome 
passed to OpenGL.

Is it clearer?

Thanks you all

Cathy
0
Reply Cathy 3/13/2009 5:39:02 PM

Cathy wrote:
> Hi John and thanks to try to answer even if you are not sure, I do the 
> same when I have an idea (and it is worse for me, my skill is really 
> low). I do believe that's the way NGs work.
> 
>> I specifically don't understand the last part of the sentence above.
> 
> As I said later on, I am quite sure that the GLSL gl_Vertex.x, 
> gl_Vertex.y and gl_Vertex.z are not the values passed via the OpenGL 
> glVertex3f(x,y,z), they were already transformed.
> I tried with this GLSL vertex shader:
> "
> uniform float altmin;
> uniform float altmax;
> uniform vec4 colmin;
> uniform vec4 colmax;
> void main(void)
> {
> gl_Position=ftransform();
> gl_BackColor=colmin+(colmax-colmin)*(gl_Vertex.y-altmin)/(altmax-altmin);
> }
> "
> And the result is quite... psychedelic:
> http://img10.imageshack.us/img10/7854/psyche.jpg
> 
> So I guess the GLSL gl_Vertex received some transformations from the 
> vector passed to OpenGL via VBO or glVertex(,,) as altmin and altmax are 
> respectively the y-component of the bottom and top vertices of the dome 
> passed to OpenGL.
> 
> Is it clearer?
> 

Maybe a little.

We've seen the vertex shader; I assume that you have loaded no fragment 
shader.

Could we see the 'display' function --- as minimal a version as possible?

Someone correct me if I'm wrong, but is not that 'main' function above 
applied to every vertex (whether specified via VBO or simple glVertex* 
call). I cannot see that the vertex (gl_Vertex) would have been 
transformed, after all that's what gl_Position=ftransform() does.

Best regards,

Jon C.
0
Reply Jonathan 3/13/2009 6:04:32 PM

Cathy wrote:

> I'm gonna wait for the answer, sorry for my impatience.

You don't have to wait. What you attemt to do is a linear interpolation.
GLSL provides a builtin function for this: mix

<http://www.opengl.org/wiki/GLSL_:_common_mistakes#Linear_Interpolation.2C_lerp.2C_mix>

Using that your code reduces to

color4f = mix(
        bottomcolor4f,
        topcolor4f,
        (gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f) );

You may like this one
<http://www.opengl.org/sdk/libs/OpenSceneGraph/glsl_quickref.pdf>

If your intention is colouring a skydome, a height depending gradient is not
very satisfying. BTDT. In my experience a very good, but easy to implement
thing to do is precalculating some cubemaps for several daytimes and put
those on the skydome.

-- 
OpenGL tip #42:
How to exactly map texture texels to screen pixels:
<http://preview.tinyurl.com/cgndc8>
0
Reply Wolfgang 3/13/2009 6:39:56 PM

> color4f = mix(
>         bottomcolor4f,
>         topcolor4f,
>         (gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f) );

I tried and as it does the same, the result is the same. So where is the 
mistake?
So you say that the OpenGL glVertex and the GLSL gl_Vertex hold the same 
coordinates?

> If your intention is colouring a skydome, a height depending gradient is not
> very satisfying. BTDT. In my experience a very good, but easy to implement
> thing to do is precalculating some cubemaps for several daytimes and put
> those on the skydome.

Ok I start looking at it right now, I would like to make the previous 
shader work, just to understand the mistake.

Thanks again Wolfgang
0
Reply Cathy 3/13/2009 7:28:07 PM

Cathy wrote:

>> color4f = mix(
>>         bottomcolor4f,
>>         topcolor4f,
>>         (gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f) );
> 
> I tried and as it does the same, the result is the same. So where is the
> mistake?

Hard to tell, without seeing the rest of the picture.

> So you say that the OpenGL glVertex and the GLSL gl_Vertex hold the same
> coordinates?

Yes.

-- 
OpenGL tip #42:
How to exactly map texture texels to screen pixels:
<http://preview.tinyurl.com/cgndc8>
0
Reply Wolfgang 3/13/2009 8:00:46 PM

Cathy wrote:
> As I said later on, I am quite sure that the GLSL gl_Vertex.x, 
> gl_Vertex.y and gl_Vertex.z are not the values passed via the OpenGL 
> glVertex3f(x,y,z), they were already transformed.
> I tried with this GLSL vertex shader:
> "
> uniform float altmin;
> uniform float altmax;
> uniform vec4 colmin;
> uniform vec4 colmax;
> void main(void)
> {
> gl_Position=ftransform();
> gl_BackColor=colmin+(colmax-colmin)*(gl_Vertex.y-altmin)/(altmax-altmin);
> }
> "
> And the result is quite... psychedelic:
> http://img10.imageshack.us/img10/7854/psyche.jpg
> 
> So I guess the GLSL gl_Vertex received some transformations from the 
> vector passed to OpenGL via VBO or glVertex(,,) as altmin and altmax are 
> respectively the y-component of the bottom and top vertices of the dome 
> passed to OpenGL.
> 
> Is it clearer?
> 
> Thanks you all
> 
> Cathy

Hello Cathy:

I'm an amateur when it comes to GLSL but I took your code into ATI 
RenderMonkey rewrote the vertex shader as follows:

uniform float altmin;
uniform float altmax;
uniform vec4 colmin;
uniform vec4 colmax;
varying vec4 frag_color;
void main(void)
{
gl_Position=ftransform();
frag_color=colmin+(colmax-colmin)*(gl_Vertex.y-altmin)/(altmax-altmin);
}

added a fragment shader as follows:

varying vec4 frag_color;
void main(void)
{
    gl_FragColor = frag_color;
}

Set the uniforms to altmin = -50, altmax = 50, colmin = blue, colmax = 
red.  And ran the shader against the default sphere object.

The sphere displayed a smooth transition from blue on the bottom to red 
on the top with a nice blue red gradient in the middle.  So, the formula 
you are using works but being that I'm an amateur, I don't know if 
gl_BackColor you're using is appropriate in this situation so I avoided 
using it in my code above.

Michael
0
Reply Michael 3/14/2009 2:33:22 AM

> uniform float altmin;
> uniform float altmax;
> uniform vec4 colmin;
> uniform vec4 colmax;
> varying vec4 frag_color;
> void main(void)
> {
> gl_Position=ftransform();
> frag_color=colmin+(colmax-colmin)*(gl_Vertex.y-altmin)/(altmax-altmin);
> }
> 
> added a fragment shader as follows:
> 
> varying vec4 frag_color;
> void main(void)
> {
>    gl_FragColor = frag_color;
> }

Hello Michael

That's the solution, it works quite well now, here is the result from 
clear blue to dark blue:
http://img17.imageshack.us/img17/7757/nicep.jpg

Strange that gl_BackColor is not what expected!

I'm Gonna have a look at that rendermonkey.

Thanks

Cathy
0
Reply Cathy 3/14/2009 7:13:21 AM

On Mar 13, 6:06=A0pm, Cathy <n...@no.fr> wrote:
> In fact, I decided not to use texture, because I was sure it was more
> efficient with just colors and because it is really easier to change the
> gradient of the sky according the time of the day just shifting the
> values of the 2 vec4 uniforms than creating another texture.

If you change your mind about using textures, have a look at (http://
www.geocities.com/ngdash/whitepapers/skydomecolor.html). It's a very
simple and efficient approach that can produce surprisingly good
results. The idea is to encode the gradients in a 2D texture, with
altitude indexing into one axis (CLAMP), and time of day into the
other axis (REPEAT). Compute the altitude into a varying, send the
time of day from your application into a uniform, and sample the
skycolor in the fragment shader with bilinear filtering. It looks
great and you don't have to update uniforms across the sky dome (can
be expensive). You can get with using very small textures so
performance will be excellent (I guess, as fast as your arithmetic
approach if the sampling latency can be hidden by other ALU
instructions). Another idea to extend this approach could be to use a
cubemap where each face stores the skycolors for a specific season (2
months).

regards,
Nicolai de Haan Br=F8gger
0
Reply ndhb78 3/14/2009 1:33:25 PM

> If you change your mind about using textures, have a look at (http://
> www.geocities.com/ngdash/whitepapers/skydomecolor.html). It's a very
> simple and efficient approach that can produce surprisingly good
> results. The idea is to encode the gradients in a 2D texture, with
> altitude indexing into one axis (CLAMP), and time of day into the
> other axis (REPEAT). Compute the altitude into a varying, send the
> time of day from your application into a uniform, and sample the
> skycolor in the fragment shader with bilinear filtering. It looks
> great and you don't have to update uniforms across the sky dome (can
> be expensive). You can get with using very small textures so
> performance will be excellent (I guess, as fast as your arithmetic
> approach if the sampling latency can be hidden by other ALU
> instructions). Another idea to extend this approach could be to use a
> cubemap where each face stores the skycolors for a specific season (2
> months).
> 
> regards,
> Nicolai de Haan Br�gger

Thanks Nicolai, it seems realistic and efficient.
I will try that.
Friendly
Cathy
0
Reply Cathy 3/14/2009 6:47:27 PM

Cathy wrote:
>> color4f = mix(
>>         bottomcolor4f,
>>         topcolor4f,
>>         (gl_Vertex.y-bottomy1f)/(topy1f-bottomy1f) );
> 
> I tried and as it does the same, the result is the same. So where is the 
> mistake?

You may have solved it already, but with shaders, I debug mostly using 
visual cues. So add a fragment shader so you can visualize variables as 
colors.
For example, if you're really paranoid, in the fragment shader, output 
the pure bottomcolor4f or topcolor4f, to make sure they are what you 
expect them. Then, visualize the division in the color4f=... expression 
above.

At some point, one of the variables you're using (and with GLSL shaders, 
it's almost never too many) isn't behaving as expected. Break things 
down to all the different inputs, visualize those, and one of them will 
be the cue.

Ruud
0
Reply Ruud 3/18/2009 9:55:17 AM

> You may have solved it already, but with shaders, I debug mostly using 
> visual cues. So add a fragment shader so you can visualize variables as 
> colors.

Thanks Ruud I keep the hint
Cathy
0
Reply Cathy 3/18/2009 3:23:34 PM

15 Replies
384 Views

(page loaded in 1.029 seconds)

Similiar Articles:












7/25/2012 3:10:39 PM


Reply: