Sign in to follow this  
JavierOltra

GLSL - Reflection and tube intersection

Recommended Posts

JavierOltra    105
Hi all,

I'm trying to port a code from executing in the CPU to the GPU.
It's supposed to render normally if the ray from camera don't collide with a tube after reflecting on a surface. So I'm rendering the surface and looking for intersection of the reflected ray with a tube passed as uniform.
This is my code for vertexshader:
[source lang="cpp"]#version 330 compatibility

out vec3 normal;
out vec3 rayDir;
out vec3 originalPos;
uniform vec3 cameraPos;

void main()
{
//we need the normal in world space, don't transform
normal = normalize(gl_Normal);

gl_FrontColor = gl_Color;
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

//we need the position in world space, don't transform. This will be the origin of the ray
originalPos = gl_Vertex.xyz;

//obtaining ray from camera
vec3 eyeDir = normalize(originalPos - cameraPos);

//reflecting the ray to get the new direction after reflection
rayDir = normalize(reflect(eyeDir, normal));
}[/source]
Code for fragmentshader:
[source lang="cpp"]#version 330 compatibility

float Dmnop(vec3 m, vec3 n, vec3 o, vec3 p)
{
return (m.x - n.x) * (o.x - p.x) + (m.y - n.y) * (o.y - p.y) + (m.z - n.z) * (o.z - p.z);
}

float d;
float d2;

vec3 ClosestPointLineLine(vec3 start0, vec3 end0, vec3 start1, vec3 end1)
{
float d0232 = Dmnop(start0, start1, end1, start1);
float d3210 = Dmnop(end1, start1, end0, start0);
float d3232 = Dmnop(end1, start1, end1, start1);
d = (d0232 * d3210 - Dmnop(start0, start1, end0, start0)*d3232) / (Dmnop(end0, start0, end0, start0) * Dmnop(end1, start1, end1, start1) - Dmnop(end1, start1, end0, start0) * Dmnop(end1, start1, end0, start0));

d2 = (d0232 + d * d3210) / d3232;

return start0 + d * (end0 - start0);
}

vec3 ClosestPointRaySegment(vec3 rayPos, vec3 rayDestination, vec3 a, vec3 b)
{
ClosestPointLineLine(a, b, rayPos, rayDestination);
d = clamp(d, 0.0, 1.0); // This is a line segment - cap both ends.

d2 = max(0.0, d2); // The other primitive is a ray - cap negative side.

return (b - a) * d + a;
}

bool IntersectTubo(vec3 rayOrigin, vec3 rayDestination, vec3 tuboA, vec3 tuboB, float tuboRadius)
{
vec3 pointRay = ClosestPointLineLine(rayOrigin, rayDestination, tuboA, tuboB);
vec3 pointTubo = ClosestPointRaySegment(tuboA, tuboB, rayOrigin, rayDestination);

return (distance(pointRay, pointTubo) <= tuboRadius);
}

in vec3 rayDir;
in vec3 originalPos;
uniform vec3 tubeA;
uniform vec3 tubeB;
uniform float radius;
uniform vec3 lightDir;
in vec3 normal;

void main()
{
if(IntersectTubo(originalPos, originalPos + rayDir, tubeA, tubeB, radius))
{
gl_FragColor= vec4(1.0, 0.0, 0.0, 1.0);
}
else
{
float diffuse_value = max(abs(dot(normal, lightDir)),0.0);

// Set the output color of our current pixel
gl_FragColor = gl_Color * diffuse_value;
}
}[/source]

The math functions are taken from [b]MathGeoLib [/b]([url="http://clb.demon.fi/MathGeoLib"]http://clb.demon.fi/MathGeoLib[/url]).

The idea on rays is taking advantage of the interpolation between vertex and fragment and I must add that model is in world position as well as tube, that's why I don't see any need to transform.

This code is working perfectly in CPU but there's something wrong in my GLSL code that is keeping me from getting a correct representation of the reflection of the tube.

I hope this post is quite self explanatory and I look forward any help you could give me.

Thanks in advance.

Share this post


Link to post
Share on other sites
JavierOltra    105
Finally found the problem, this:

[source lang="cpp"]bool IntersectTubo(vec3 rayOrigin, vec3 rayDestination, vec3 tuboA, vec3 tuboB, float tuboRadius)
{
vec3 pointRay = ClosestPointLineLine(rayOrigin, rayDestination, tuboA, tuboB);
vec3 pointTubo = ClosestPointRaySegment(tuboA, tuboB, rayOrigin, rayDestination);

return (distance(pointRay, pointTubo) <= tuboRadius);
}[/source]

Should be:

[source lang="cpp"]bool IntersectTubo(vec3 rayOrigin, vec3 rayDestination, vec3 tuboA, vec3 tuboB, float tuboRadius)
{
vec3 pointRay = ClosestPointLineLine(rayOrigin, rayDestination, tuboA, tuboB);
vec3 pointTubo = ClosestPointRaySegment(rayOrigin, rayDestination, tuboA, tuboB);

return (distance(pointRay, pointTubo) <= tuboRadius);
}[/source] Edited by JavierOltra

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this