Archived

This topic is now archived and is closed to further replies.

revearz

Per-pixel fresnel term

Recommended Posts

Hi, Does anyone know how to calculate per-pixel fresnel term for pixel shaders 1.x? I can do it in vertex shaders but want to try to move it to pixel shaders. Any good approximations I can use? Currently I''m using: ( 1 / ( 1 + ( normal dot eye ) ) ) ^ x in my vertex shader. I found another approximation: ( 1 - ( normal dot eye ) ) ^ x where x is any exponent power I think the eye vector ( vertex position - camera position ) has to be calculated in the vertex shader and be passed to the pixel shader but the only inputs to the pixel shaders are colour values. Any ideas? Thanks.

Share this post


Link to post
Share on other sites
Well, you could do it with a texture look up.

So, calculate (normal dot eye), then feed this in as the u coordinate to a texture lookup. Encode the rest of the function when generating the texture. eg, calculate (1/(1+u))^x for each texel of the 1d texture.

Now, to actually implement that, do this:

texcoord t0
texdp3tex t1, t0_bx2
// We have the fresnel term wherever you put it in the texture (in .a maybe?)

The vertex shader should output the normal (biased and scaled) to oT0, and the normalised eye vector to oT1.

If you wanted to use per-pixel normals, then replace the first instruction with a tex and bind the normal map to stage 0, and make sure your eye vector is in tangent space (presumably you''re doing tangent space normal mapping?)

ie:

tex t0
texdp3tex t1, t0_bx2

NB. texdp3tex is ps.1.2 or greater, so if you need ps.1.1, you''ll need to use the texm3x2pad/texm3x2tex pair and waste a texture stage.

HTH

Matt Halpin

Share this post


Link to post
Share on other sites
Hello,

Thanks for the reply. How do I convert my eye vector to tangent space?

Also for the fresnel texture, what is the range should I calculate? Between -1 and 1? Should I then convert this value to a colour value?

Share this post


Link to post
Share on other sites
quote:
Original post by revearz
Hello,

Thanks for the reply. How do I convert my eye vector to tangent space?


Well, that''s only relevant if you''re doing tangent space bump-mapping. If that''s the case, presumably you''ll have tangent space vectors somewhere in the vertex data (or partially generated in the vertex shader). Use these vectors as follows:

dp3 oT0.x, v0.xyz, r0.xyz
dp3 oT0.y, v1.xyz, r0.xyz
dp3 oT0.z, v2.xyz, r0.xyz

change v0 to be the tangent vertex component, v1 to be the bi-normal vertex component, and v2 to be the normal vertex component. Change oT0 to be whatever you need, and change r0 to be the normalised eye vector

quote:
Original post by revearz
Also for the fresnel texture, what is the range should I calculate? Between -1 and 1? Should I then convert this value to a colour value?


Well, the result of the dot-product is -1 to 1, but for values <0 (ie the fragment is pointing away from the camera) the result of both equations is >1. You could just calculate the values between 0 and 1 and clamp the uv''s. Hence fragments behind the camera would get fresnel values of 1. Not sure if that''ll be ok, but worth trying...

HTH

Matt Halpin

Share this post


Link to post
Share on other sites
Hello,

I encoded the eye dot normal vector into a texture map. It has an increasing gray scale until ( e dot n = 0 ), then it's all white. Is this correct?

Currently I have my normal map set in texture stage 0 and (1/(1+u))^x map set in texture stage 2. Here is my pixel shader code to just show the reflections but all i see is black:

tex t0
texm3x2pad t1, t0_bx2
texm3x2tex t2, t0_bx2

mov r0, t2

What should should oT0, oT1, oT2 be set to? I currently set oT0 to be my normal's uv co-ord and oT1 = (1,0,0) and oT2 = (0,1,0). Is the correct?

Thanks!


[edited by - revearz on August 4, 2003 12:18:48 AM]

[edited by - revearz on August 4, 2003 12:24:40 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by revearz
Hello,

I encoded the eye dot normal vector into a texture map. It has an increasing gray scale until ( e dot n = 0 ), then it''s all white. Is this correct?
>


ok, it should be 1 when (e dot n == 0), ie u == 0. Then it should go down to a smaller value when u == 1 (0.1 or something).

quote:
Original post by revearz
Currently I have my normal map set in texture stage 0 and (1/(1+u))^x map set in texture stage 2. Here is my pixel shader code to just show the reflections but all i see is black:

tex t0
texm3x2pad t1, t0_bx2
texm3x2tex t2, t0_bx2

mov r0, t2

What should should oT0, oT1, oT2 be set to? I currently set oT0 to be my normal''s uv co-ord and oT1 = (1,0,0) and oT2 = (0,1,0). Is the correct?



ok, the pixel shader looks correct, and you''ve got your maps set up correctly, but your oT1/2 registers are wrong. You''ve got oT0 correct, but presumably the normal map is in tangent/texture space? If that''s the case, then oT1 needs to have the normalised tangent-space eye vector in it, not (1,0,0). oT2 doesn''t really matter as you''re only using the u component - just set it to the same as oT1.

So, you need to work out the normalised eye vector in tangent space. You should probably do a search for ''tangent space'' or ''per-pixel lighting''. Read some NVidia/ATI papers to work out what tangent space is. Articles dealing with Specular bump mapping wil probably also give you shader fragments for working out the normalised eye vector.

Basically you need to have a per-vertex tangent space stored in your mesh. That''s 3 3float vectors.

HTH

Matt Halpin

Share this post


Link to post
Share on other sites