PDA

View Full Version : cubemap reflection...again



Nowhere-01
06-03-2011, 12:16 PM
hey, sorry for raising the same problem that already was on the forum...but it looks like i'm damned when it goes to glsl.

i'm trying to do reflection of cubemap i've got from framebuffer;
so the problem is if i rotate camera or move it - "reflected" image...of course, does move too. if i rotate camera left or right, texture moves in inverse direction, over-compensating camera movement. rotating camera up-down makes it move in same direction, but "faster" than needed, so again, it overcompensates camera rotation. same with camera movement. also reflection scale is a bit bigger than it should.

V:

#version 110
attribute vec3 Tangent;
varying vec4 Add;
varying vec4 ld;
varying vec4 eye;
varying vec4 N;

void main()
{
vec4 V = gl_ModelViewMatrix * gl_Vertex;
gl_Position = gl_ProjectionMatrix * V;

gl_TexCoord[0] = gl_MultiTexCoord0;

vec4 T = -normalize(vec4(gl_NormalMatrix * Tangent, 1.0));
N = normalize(vec4(gl_NormalMatrix * gl_Normal, 1.0));
vec4 B = vec4(cross(N.xyz, T.xyz), 1.0);

mat3 TBN = mat3(vec3(B.x, T.x, N.x), vec3(B.y, T.y, N.y), vec3(B.z, T.z, N.z));

ld = normalize(vec4(TBN * (gl_LightSource[0].position - V).xyz, 1.0));

eye = normalize(vec4(TBN * (-V).xyz, 1.0));
gl_TexCoord[7] = V;

Add = gl_Color;
}

F:

#version 110
uniform sampler2D colorMap;
uniform sampler2D bumpMap;
uniform samplerCube Refl;
uniform vec4 Ambient;
uniform vec4 Material;
uniform vec4 Cam;
varying vec4 Add;
varying vec4 ld;
varying vec4 eye;

void main (void)
{
vec4 Spec = Add + Ambient;
vec4 Color = texture2D(colorMap, gl_TexCoord[0].st);

vec4 bump = (texture2D(bumpMap, gl_TexCoord[0].st) * 2.0) - 1.0;

float Lambert = dot(ld, bump) * gl_LightSource[0].position.w;

float Nhalf = pow(max(dot(reflect(-ld, bump), eye), 0.0), Material.x) * Material.z;

Spec = (Nhalf * gl_LightSource[0].diffuse) + Spec;

vec4 Diffuse = Ambient + ((Lambert * gl_LightSource[0].diffuse) * gl_LightSource[0].diffuse.w);

vec4 RCoord = reflect(gl_TexCoord[7], bump);
vec4 Ref = textureCube(Shadow, RCoord.xyz);

gl_FragColor = Ref;
}

I've tried solutions found on this forum and others, but they just made things worse. I think, there's something wrong outside shaders, in my program. Or why else i was forced to switch TBN axes and inverse tangent for normal mapping. I did it by brute-force, would love to read what can cause weird reflections\switched TBN.
My weakness: Matrices/Transformation spaces, matrix stack management. -Really hight chances i screwed up there.

Alfonse Reinheart
06-03-2011, 12:45 PM
There are a lot of weird things in your shader here.

First, if you're trying to get reflections to work, focus on that alone. Take out all your bump-mapping code, so that you minimize the number of things that can be interfering. Once you get reflections working, then add it back in, so that you can see where things are going wrong.

Second, your bump mapping code is... suspect. The binormal is not the cross-product of the tangent and normal. The whole point of tangent space is to allow the tangent and binormal to not have an orthonormal space. They have to match the texture coordinates, so doing it this way doesn't make sense.

Also, I'm not convinced that doing the NBT transform in the vertex shader is a good idea. You're interpolating tangent-space normals, except that tangent-space normals will change quite a bit over the surface of a triangle, since each vertex has it's own separate tangent space. You'll get fewer interpolation issues if you interpolate the NBT and do the transform in the fragment shader.

Nowhere-01
06-04-2011, 03:00 AM
That's why i posted it(normal map part)... Thought wrong calculation can cause such behaviour.

So i guess, if just cross product is wrong, i should calculate it like this:

<div class="ubbcode-block"><div class="ubbcode-header">Click to reveal.. <input type="button" class="form-button" value="Show me!" onclick="toggle_spoiler(this, 'Yikes, my eyes!', 'Show me!')" />]<div style="display: none;">
generateNormalAndTangent(float3 v1, float3 v2, text2 st1, text2 st2)
{
float3 normal = v1.crossProduct(v2);

float coef = 1/ (st1.u * st2.v - st2.u * st1.v);
float3 tangent;

tangent.x = coef * ((v1.x * st2.v) + (v2.x * -st1.v));
tangent.y = coef * ((v1.y * st2.v) + (v2.y * -st1.v));
tangent.z = coef * ((v1.z * st2.v) + (v2.z * -st1.v));

float3 binormal = normal.crossProduct(tangent);
}[/QUOTE]</div>

in my program and pass binormal as a vertex attribute?

Alfonse Reinheart
06-04-2011, 03:40 AM
i should calculate it like this:

No. You don't calculate them at all. The Normal, Binormal and Tangent vectors are all vertex attributes that you pass in. You cannot compute one from the others, as they are dependent on independent things.

Nowhere-01
06-04-2011, 06:53 AM
Ok, but before i pass them, i still need to calculate them somehow outside shader. If my way is wrong, could you, please, show me right way of calculating binormal? According to google search for NTB calculation, Binormal = Normal cross Tangent; I've seen mentions it's a hack and it's approximate, but couldn't find something better.

My vertex attributes look like this now: Vertex, Normal, UV, Tangent;

Also, if in my fragment shader i replace bump with normal - reflection reacts on camera the same way, except it's x-inverse, and scaled same way.

So problem may be cut to:

V

void main(void)
{
vec4 V = gl_ModelViewMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[1] = normalize(V);
gl_Position = gl_ProjectionMatrix * V;
}

F

uniform sampler2D bumpMap;
uniform samplerCube Reflection;
void main (void)
{
vec4 bump = (texture2D(bumpMap, gl_TexCoord[0].st) * 2.0) - 1.0;
vec4 RCoord = normalize(reflect(gl_TexCoord[1], bump));
vec4 Ref = textureCube(Reflection, RCoord.xyz);

gl_FragColor = Ref;
}

Nowhere-01
06-05-2011, 02:39 AM
Ok, i've replaced "reflect(gl_TexCoord[1], bump)" with "-reflect(bump, gl_TexCoord[1])" and that fixed scaling.


uniform sampler2D bumpMap;
uniform samplerCube Reflection;
void main (void)
{
vec4 bump = (texture2D(bumpMap, gl_TexCoord[0].st) * 2.0) - 1.0;
vec4 RCoord = normalize(-reflect(bump, gl_TexCoord[1]));
RCoord.x = -RCoord.x; //To make it react on camera rotation as it should.
vec4 Ref = textureCube(Reflection, RCoord.xyz);

gl_FragColor = Ref;
}

But it looks more like refraction without depth-testing. Because with Y coordinates inversion, reflection itself looks Y-inverse. So i should find out how to flip it(keeping it reaction on camera right), and i don't know how yet. Or i need to find out what causes that inversion.