glsl shader for affecting color based on geometry
hello,
i'm trying to change the saturation of a texture based on the z value of a given geometry using a glsl shader. namely, i'd like the texture to be black and white where the z-value of the geometry is 0., and then become progressively more colored as points are displaced.
as i understand it, i need to pass the vertex coordinates from the vertext to the fragment programs. i attempt to do so with a varying variable but i'm not getting what i expect in the fragment shader. has any one a hint about what i'm doing wrong?
script and patch are below.
_______________script "grooves-in-surf-01.jxs"
Textured glass-like material lit with a point light w/ two specular components calculated per pixel.
Position of Light Source
Position
Tangent
Primary Specular Color
Secondary Specular Color
Base Color
Primary Specular Multiplier
Secondary Specular Multiplier
Specularity Adjustment
_______________________________patch
Hi Ali,
>
> Position
>
...
> attribute vec3 position;
> varying vec3 mypos;
...
> gl_Position = gl_ModelViewProjectionMatrix*gl_Vertex;
> mypos = position;
This position is all zero unfortunately. I've never used this means
of binding the position as a vertex attribute, so there may be issues
or it may not be supported within the context of our GLSL shaders
(may be relevant for Cg). I guess I need to investigate this further,
but regardless, in GLSL I would recommend you simply use the built-in
GLSL attribute "gl_Vertex" (transformed or untransformed as you
choose). This is equivalent to what position would be.
The following line is probably what you want to do (use the vertex
values untransofrmed by the world transformation). However, as you
probably noticed, based on your comments, it gives you an error.
> mypos = gl_Vertex;
"ERROR: 0:18: 'assign' : cannot convert from 'attribute 4-component
vector of float' to 'varying 3-component vector of float'"
If you see errors like the above, it means that you are trying to
work with incompatible types that need to be resolved one way or
another. Please read the OpenGL orange book for GLSL type values. In
this case, this means that you are trying to assign a vec4 to a vec3.
This is not permitted without an explicit cast. Why is gl_Vertex a
vec4? Because OpenGL internally uses homogenous coordinates for
applying transforms to values. A 3D position vector (x,y,z)
represented in homogenous coordinates is a 4 element value (x,y,z,w)
where w is a scaling factor, typically 1 (no scaling). This is useful
for the matrix multiplication that will translate, rotate, scale, etc
all points. For more information about homogenous coordinates, please
check out any of the OpenGL documentation (red book, orange book,
etc.), and/or search online.
So, the following line works as you would expect.
mypos = vec3(gl_Vertex);
Or another solution is to change the mypos variable to a vec4 in both
the vertex and fragment shader.
I would also recommend that you eliminate varying values which are
not used in both shaders, and that you approach debugging your
shaders by setting the output fragment color to some value that you
wish to monitor. For example if you set gl_FragColor = vec4
(mypos.z); you will see what its value is.
-Joshua
Also, before continuing to bang your head against the wall with this
stuff. I'd recommend taking an afternoon or two to slowly walk
through some GLSL tutorials such as those found at the following web
sites. This is a general technology (not jitter specific) and there
are lots of great resources out there to help you learn how to use it.
http://www.lighthouse3d.com/opengl/glsl/
http://www.clockworkcoders.com/oglsl/tutorials.html
http://nehe.gamedev.net/data/articles/article.asp?article=21
-Joshua
To add to that list, this one is quite nice as well:
http://www.ozone3d.net/tutorials/glsl_texturing.php
wes
hello,
not a whole lot of head banging going on over here as i indeed started with 2 afternoons of tutorials, namely the first two of josh's three. so i'm well aware of the differenc between a vec3 and vec4, so i wasn't getting a compiler error when i tried filling my varying variable with gl_Vertex; i must have had some other stupid bug in my code cuz for whatever reason, i can get it working now.
as for the 1st way of filling the 'mypos' variable, which was with the binding of 'position' to gl_Position, that definitely works in other cases. i got it from the patch/shader that wes posted 2 days ago as a vertext-displacement example. however, i can't get it to work in this instance...
on the otherhand, i'd also found this tutorial from the site that wes mentioned:
this seems to suggest that accessing textures in the vertex program is indeed possible, whereas wes was saying that'll only going be availble in glsl 2.0. which is it i wonder.
thanks,
a
I saw that too, but there's a gotcha:
The displacement mapping involves a graphics controller that supports
Shader Model 3.0 norm. Currently, all nVidia Geforce 6xxx and higher
based graphics controllers are SM 3.0 complient as well as the latest
ATI Radeons X1800 and X1900. To be more accurate, we have to access at
least to one texture inside the vertex shader in order to make
displacement mapping working. The access to a texture inside the
vertex shader is called Vertex Texture Fetching. The shader model 3.0
imposes that at least 4 texture units are accessible inside the vertex
shader.
This information can be get in OpenGL using the constant:
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB.
If I run the OpenGL profile (assuming you're on OSX) in
Developer/Applications/Graphics Toos/ and go to Monitors->Renderer
Info and look under my graphics card's rendere->OpenGL limits, I see
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = 0. I think that's pretty
definitive. If you're on windows, I'm sure there's a tool that can
tell you what this limit is on your machine or you can compile a
simple OpenGL test application and query this value yourself. At this
point in time you need some really bad ass hardware to do Vertex
Texture Fetching. I personally have not come across a machine that
does this yet, but it will be a fine day when I do.
Also, my current version of GLSL is 1.10 and
GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB is only > 0 for GLSL 1.2 or
higher.
best,
wes
On 8/28/06, Ali Momeni wrote:
>
>
> hello,
> not a whole lot of head banging going on over here as i indeed started with 2 afternoons of tutorials, namely the first two of josh's three. so i'm well aware of the differenc between a vec3 and vec4, so i wasn't getting a compiler error when i tried filling my varying variable with gl_Vertex; i must have had some other stupid bug in my code cuz for whatever reason, i can get it working now.
>
> as for the 1st way of filling the 'mypos' variable, which was with the binding of 'position' to gl_Position, that definitely works in other cases. i got it from the patch/shader that wes posted 2 days ago as a vertext-displacement example. however, i can't get it to work in this instance...
>
> on the otherhand, i'd also found this tutorial from the site that wes mentioned:
>
> http://ozone3d.net/tutorials/vertex_displacement_mapping.php
>
> this seems to suggest that accessing textures in the vertex program is indeed possible, whereas wes was saying that'll only going be availble in glsl 2.0. which is it i wonder.
>
> thanks,
> a
>
>
>
PS If you're on windows, download this tool:
http://ozone3d.net/hardware_infos.php
It will tell you what you need to know.
wes
On 8/28/06, Wesley Smith wrote:
> I saw that too, but there's a gotcha:
>
> The displacement mapping involves a graphics controller that supports
> Shader Model 3.0 norm. Currently, all nVidia Geforce 6xxx and higher
> based graphics controllers are SM 3.0 complient as well as the latest
> ATI Radeons X1800 and X1900. To be more accurate, we have to access at
> least to one texture inside the vertex shader in order to make
> displacement mapping working. The access to a texture inside the
> vertex shader is called Vertex Texture Fetching. The shader model 3.0
> imposes that at least 4 texture units are accessible inside the vertex
> shader.
>
> This information can be get in OpenGL using the constant:
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB.
>
> If I run the OpenGL profile (assuming you're on OSX) in
> Developer/Applications/Graphics Toos/ and go to Monitors->Renderer
> Info and look under my graphics card's rendere->OpenGL limits, I see
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB = 0. I think that's pretty
> definitive. If you're on windows, I'm sure there's a tool that can
> tell you what this limit is on your machine or you can compile a
> simple OpenGL test application and query this value yourself. At this
> point in time you need some really bad ass hardware to do Vertex
> Texture Fetching. I personally have not come across a machine that
> does this yet, but it will be a fine day when I do.
>
> Also, my current version of GLSL is 1.10 and
> GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB is only > 0 for GLSL 1.2 or
> higher.
>
> best,
> wes
>
> On 8/28/06, Ali Momeni wrote:
> >
> >
> > hello,
> > not a whole lot of head banging going on over here as i indeed started with 2 afternoons of tutorials, namely the first two of josh's three. so i'm well aware of the differenc between a vec3 and vec4, so i wasn't getting a compiler error when i tried filling my varying variable with gl_Vertex; i must have had some other stupid bug in my code cuz for whatever reason, i can get it working now.
> >
> > as for the 1st way of filling the 'mypos' variable, which was with the binding of 'position' to gl_Position, that definitely works in other cases. i got it from the patch/shader that wes posted 2 days ago as a vertext-displacement example. however, i can't get it to work in this instance...
> >
> > on the otherhand, i'd also found this tutorial from the site that wes mentioned:
> >
> > http://ozone3d.net/tutorials/vertex_displacement_mapping.php
> >
> > this seems to suggest that accessing textures in the vertex program is indeed possible, whereas wes was saying that'll only going be availble in glsl 2.0. which is it i wonder.
> >
> > thanks,
> > a
> >
> >
> >
>