texture2D and Mipmaps in Vertex Shader

I loaded a 2D Mipmap texture into OpenGL.

When I try to access using:

“texture2D(nTexture, nTexCoord)” I get a vertex shader compilation error saying -> “unable to find compatible overloaded function texture2D”.

I understand that the lod value is unavailabe in the vertex shader so I also tried using the function “texture2DLod(nTexture, nTexCoord, 0.0)”
but I still get the same error.

I am using NVIDIA Quadro FX500.


Vertex Texturing (which is a part of NV40 feature set) is AFAIK not yet implemented in nVidia drivers.

Yes, it works. I’m using 66.28 drivers with hardware vertex textures. Do you have 65+ series drivers? It doesn’t sound like it. I had a brief look at the Quadro FX500 on NVIDIA’s website - it seems to be an NV40 part. If it is and you have 65+ drivers it should work.

Are you using 66.28 driver on Quadro FX500 ? If so where did you get it ?

Also on the NVIDIA website I see only 3 drivers for the Quadro series,

Current NVIDIA (XP / 2000) 61.76
Current NVIDIA (NT) 61.76
Quadro FX 4000 (XP / 2000) 65.90

Currently I am using 61.76.

Can I use the 65.90 for my graphics card Quadro FX500 ?

Is “nTexCoord” a vec2 ?

Because if you accidentally used a wrong type instead this is the error message you get.

Quadro FX 500 is not an NV40 part. I believe it uses an NV34 chip, like the GeForce FX 5200, and so it simply cannot support vertex shader texture reads.

– Tom

Mmm, NVIDIA’s website sort of indicated that all the FX Quadros were DX9.0c parts, so I assumed NV40 based. The specs were a bit off, though. Re the drivers - 66.28 is a beta driver, but I’m using a 6800 so the 65.90 isn’t for me anyway. I forgot about the 65.90 Quadro driver - you could install that but from Tom’s reply you’re out of luck anyway.

I guess there isn’t much I can do. I was trying to do Reflective bump mapping and below is the code for Cube mapping and Reflective BummpMapping:


Vertex Shader:

varying vec3 N;
varying vec3 V;

void main(void)
gl_Position = ftransform();

vec3 vertex = vec3 (gl_ModelViewMatrix * gl_Vertex);

V = normalize(-vertex);

N = vec3 (gl_NormalMatrix * gl_Normal);


Fragment Shader:

uniform samplerCube cubeMapTexture;

varying vec3 N;
varying vec3 V;

void main(void)
vec3 view = normalize(V);
vec3 normal = normalize(N);

vec3 refVector = normalize(reflect(-view, normal));

vec3 refColor = vec3 (textureCube(cubeMapTexture, refVector));

gl_FragColor = vec4 (vec3(refColor), 1.0);


Reflective BumpMapping:_

Vertex Shader:

uniform vec3 light;
uniform vec3 camera;

attribute vec2 bumpMapTexCoord;
attribute vec3 tangent;
attribute vec3 binormal;

varying vec2 texCoord;

varying vec3 T, B, N;
varying vec3 V, L;
varying vec3 cmV;

void main(void)
gl_Position = ftransform();

vec3 vertex = vec3 (gl_Vertex);

vec3 lvec = normalize(light - vertex);

vec3 view = normalize(camera - vertex);

T = tangent;
B = binormal;
N = gl_Normal;

V = view;
L = lvec;

cmV = vec3 (gl_ModelViewMatrix * gl_Vertex);
cmV = normalize(-cmV);

texCoord = bumpMapTexCoord;


Fragment Shader:

uniform sampler2D decalTexture;
uniform sampler2D bumpMapTexture;
uniform samplerCube cubeMapTexture;

varying vec2 texCoord;

varying vec3 T, B, N;
varying vec3 V, L;
varying vec3 cmV;

void main(void)
T = normalize(T);
B = normalize(B);
N = normalize(N);

V = normalize(V);
L = normalize(L);

cmV = normalize(cmV);

vec3 view, light, half;

view.x = dot(T, V);
view.y = dot(B, V);
view.z = dot(N, V);

light.x = dot(T, L);
light.y = dot(B, L);
light.z = dot(N, L);

half = normalize(light + view);

vec3 decal  = vec3 (texture2D(decalTexture, texCoord));
vec3 normal = vec3 (texture2D(bumpMapTexture, texCoord));

normal.x = 2.0 * normal.x - 1.0;
normal.y = 2.0 * normal.y - 1.0;
normal.z = 2.0 * normal.z - 1.0;

float ndotl = max(dot(normal, light), 0.0);
float ndoth = pow(max(dot(normal, half), 0.0), 60.0);

vec3 t = vec3(T.x, B.x, N.x);
vec3 b = vec3(T.y, B.y, N.y);
vec3 n = vec3(T.z, B.z, N.z);

t = normalize(t);
b = normalize(b);
n = normalize(n);

vec3 cmNormal;
cmNormal.x = dot(t, normal);
cmNormal.y = dot(b, normal);
cmNormal.z = dot(n, normal);

cmNormal = vec3 (gl_NormalMatrix * cmNormal);
cmNormal = normalize(cmNormal);

vec3 refVector = normalize(reflect(-cmV, cmNormal));

vec3 refColor = vec3 (textureCube(cubeMapTexture, refVector));

vec3 fColor;

fColor.x = ndotl * (decal.x + refColor.x) + ndoth;
fColor.y = ndotl * (decal.y + refColor.y) + ndoth;
fColor.z = ndotl * (decal.z + refColor.z) + ndoth;

gl_FragColor = vec4 (vec3(fColor), 1.0);


The Cube Mapping works perfect but the Reflective Bump Mapping doesn’t work well. Can some body look at the code and suggest something ?

Just had a quick look…

I don’t know what your specific problem is but here are some suggestions:

-You seem a bit “normalize” happy. You are calling normalize in a lot of places where it is not necessary. (ie. the reflection vector does not need to be normalized when looking up into cube map)

  • Your non-bump reflection mapping looks like it is doing much more in the fragment shader than it needs to. (the reflection vector could probably be calculated in the vertex shader)

  • The bump reflection should be a simple (psudo code)

    cubeSpaceNormal = tangentToCubeSpaceMatrix * texBumpNormal;

    reflectTexCoord = reflect(cubeSpaceEye ,cubeSpaceNormal)

    //Look up cube map

-If you are going for accuracy with all the normalizes, I would normalize the bump map look up (once it has been *2 and -1) as it is probably comming from a 8-bit source

Since I am not able to access the BumpMap texture inside the vertex shader, I have to pass the texcoord, T, B, N to the fragment shader as “varying variables”. Now inside the fragment shader I fetch the BumpMap normal and using the “interpolated (varying variable)” T, B, N to I transform this normal from tangent space to world space. Then I transform this world space normal to cubemap space using the gl_NormalMatrix. Here I think the gl_NormalMatrix doesn’t seem to produce any effect. what is the word on using gl_NormalMatrix and gl_ModelViewMatrix inside a fragment shader ?


I still don’t see why you can’t use vertex textures. I can use 1D and 2D with no problem. There might be a trick to getting it to work with software emulation on your card? Dunno. Anyway, here’s the relevant setup code for some simple displacement mapping:

	// Displacement texture.
	glBindTexture(GL_TEXTURE_1D, hTex[1]);
	glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA_FLOAT32_ATI, NODES, 0, GL_RGBA, GL_FLOAT, (const GLvoid *)pDisps);

// ...

	GLint texLoc = glGetUniformLocationARB(NodeProgram, "Disp");
	glUniform1iARB(texLoc, 1);

The 1D texture holds a displacement value for each vertex in a VBO. The VBO holds a vertex position and displacement texture index. Here’s the vertex shader:

extern const GLcharARB *nodeVertStr =
	// Total nodes in the mesh.
	"uniform float NODES;"
	// Displacement texture.
	"uniform sampler1D Disp;"

	"void main()"
		// gl_Vertex.w holds texture lookup index.
		"const float index = gl_Vertex.w / NODES;"
		// Get displacement value for this vertex.
		"vec4 disp = texture1D(Disp, index);"
		"gl_FrontColor = gl_Color;"
		// Displace the vertex.
		"vec4 position = gl_Vertex + disp;"
		// Identity perspective division.
		"position.w = 1.0;"
		// Transform displaced vertex to clip space.
		"gl_Position = gl_ModelViewProjectionMatrix * position;"

This works with no problems for me. As to your question about accessing the built-in uniform state in frag shaders, the 1.10 spec is kind of vague but implies you can. The orange book specifically says you can access them from either vertex or fragment shaders.

Yes, the orange books says you can access (texture units and uniform state variables like gl_NormalMatrix /gl_ModelViewMatrix / glTextureMatrix[x]) from both vertex and fragment shaders but for some reason I could not access the texture units from the vertex shader and the above mentioned state variables donesn’t seem to have any transformation effects when used inside the fragment shaders to transform vectors or points.

Any clues would be of good help. Thank you!

Pick the uniform matrix you’re interested in. glLoadMatrix a permutation matrix, e.g.:

    GLfloat perm[16] = {
        0.0f, 1.0f, 0.0f, 0.0f,
        1.0f, 0.0f, 0.0f, 0.0f,
        0.0f, 0.0f, 1.0f, 0.0f,
        0.0f, 0.0f, 0.0f, 1.0f

Then in your fragment shader something like:

    vec4 colour = vec4(1.0, 0.0, 0.0, 1.0);
    gl_FragColor = gl_WhateverMatrix * colour;

and see if you get red or green coloured objects.

You don’t want to transform to world space inside the fragment shader, as that will slow down rasterization. Instead, transform T, B and N to world space in the vertex shader, and you’ll magically get the right value after tangent space transform in the pixel shader.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.