PDA

View Full Version : Accessing primitive data in FS



lordmule
09-06-2010, 01:10 AM
Hi all,

My main problem is computing the tangent/bitangent in GLSL shaders. I am doing this because I use glTexGen...so I can't compute tangent on application side. To find the tangent, one needs the plane of the polygon and the texture coordinates (at least 3 vert coords and 3 tex coords).

How can I access the data for the same primitive in the shader?

thinks
09-06-2010, 01:43 AM
You could use a geometry shader to access primitive information. Another option is to pass triangle vertices as texture coordinates (or generic vertex attributes). The idea is that each vertex knows about the other two vertices in the triangle. This works fine, if you are willing to accept an overhead in uploading data to the GPU.

lordmule
09-06-2010, 10:20 PM
You could use a geometry shader to access primitive information.
Does this mean tracking of the vertex data? most certainly be useful, I have never used geom shader before though.


Another option is to pass triangle vertices as texture coordinates (or generic vertex attributes). The idea is that each vertex knows about the other two vertices in the triangle. This works fine, if you are willing to accept an overhead in uploading data to the GPU.
I don't mind the overhead, but since I am generating texture coordinates for some models like that of glutSolid* I won't be able to specify additional attributes.

very good ideas thank you!

lordmule
09-06-2010, 10:30 PM
I found an old post from lian Dinev:
http://www.opengl.org/discussion_boards/ubbthreads.php?ubb=showflat&Number=268143#Post2681 43

I've PM'd lian and I have graciously received a response and a snippet of code to solve this problem in FS.



/=================[[ Create tangent and binormal ]]==========================================[
// gotten from http://www.pouet.net/topic.php?which=6266
// Use like this:
// mat3 TBN = computeTangentFrame(gl_Normal, varPos,texCoord);
// normal = normalize(TBN * normalFromTexture);


mat3 computeTangentFrame(vec3 normal, vec3 position, vec2 texCoord){
vec3 dpx = dFdx(position);
vec3 dpy = dFdy(position);
vec2 dtx = dFdx(texCoord);
vec2 dty = dFdy(texCoord);

vec3 tangent = normalize(dpx * dty.t - dpy * dtx.t +0.001);
vec3 binormal = normalize(-dpx * dty.s + dpy * dtx.s + 0.001);

return mat3(tangent, binormal, normal);
}

//================================================== ==========================================/


The function dFdx is as close as one can get to accessing the other vertex data for the same polygon. For a given point position, the derivative in x/y axes is returned. I looked up the GLSL spec and section 8.10.1 says that a desirable but not required property is:

4. Functions should be evaluated within the interior of a primitive (interpolated, not extrapolated).

This is actually what is needed for the tangent computation, not the actual positions themselves.

dFdx is one of those functions that a noob like me wouldn't know about :D

Thank you all