I have a point ray_start_pos in world coordinates. I add the vector (reflection_dir * ray_length) to get ray_end_pos, which is then transferred to screen coordinates by multiplying the pvm matrix with ray_end_pos.
My PROBLEM: when ray_length is small, around 100, then ray_end_pos_on_screen.xyz is as expected. When ray_length is larger, around 1000, then ray_end_pos_on_screen.xyz seems to ‘wrap around’, in the sense that (in tests especially) ray_end_pos_on_screen.x is suddenly much too large, or has other odd values.
For debugging, the only action done with ray_end_pos_on_screen is to examine its values by deriving the current fragment’s color from it:
[...] (see initial post)
out_col = vec4(ray_end_pos_on_screen.x, ray_end_pos_on_screen.y, 0.0, 1.0); // set the fragment shader's output color
For a small ray_length, e.g. 100.0, the scene gets more intensively red from the screen’s left to right border, as expected. For the very same ray_start_pos and reflection_dir I get odd red/yellow/green patterns if ray_length is greater than around 200.0, e.g. if ray_length = 1000.0.
I just wanted to know if there are things to attend when involving the pvm matrix. In university we were told that “clipping in normalized coordinates will not work due to non linear transformation in z”. I wonder if this could somehow explain my odd ray_end_pos_on_screen content?!?
Bear in mind that if the result is outside of the unsigned unit cube, each component will be clamped separately, meaning that the direction (i.e. hue) won’t be preserved.
[QUOTE=JasonRay;1280817]
I just wanted to know if there are things to attend when involving the pvm matrix. In university we were told that “clipping in normalized coordinates will not work due to non linear transformation in z”. I wonder if this could somehow explain my odd ray_end_pos_on_screen content?!?[/QUOTE]
Clipping isn’t a factor here, although the lack of clipping may be. If eye-space Z is positive (behind the viewpoint), clip-space W will be negative, resulting in normalised X,Y,Z all being flipped. Clipping exists largely to prevent that situation from occurring; even without the near-plane test, the geometry which remains after clipping will be in front of the viewpoint.
Provided that ray_end_pos lies within the view frustum, ray_end_pos_on_screen.xyz is calculated correctly. If ray_end_pos is outside of the view frustum, the result will be wrong. In particular, if the reflection of ray_end_pos in the viewpoint is inside of the view frustum, ray_end_pos_on_screen.xyz will correspond to that reflection. You might want to explicitly test for ray_end_pos_on_screen.w<0 before dividing by it and discard (or set a constant colour) for that case. And also test whether any of abs(ray_end_pos_on_screen.xyz/ray_end_pos_on_screen.w) are greater than one.
One more question: I have a point in world space, e.g. ray_start_pos, and from there a vector that points into some arbitrary direction (in world space), e.g. reflection_dir, and the length of reflection_dir, e.g. ray_length (just as in the example of my initial post).
Is there an easy way at all to determine ray_length so that ray_end_pos = ray_start_pos + reflection_dir * ray_length is located at the (nearest) screen border? I mean is there an easy way to do correct clipping in the given case? ‘Easy way’ shall mean around 5 to 10 or so lines of shader code, in any case easier than the whole Cohen-Sutherland machinery.
[QUOTE=JasonRay;1280830]
One more question: I have a point in world space, e.g. ray_start_pos, and from there a vector that points into some arbitrary direction (in world space), e.g. reflection_dir, and the length of reflection_dir, e.g. ray_length (just as in the example of my initial post).
Is there an easy way at all to determine ray_length so that ray_end_pos = ray_start_pos + reflection_dir * ray_length is located at the (nearest) screen border? I mean is there an easy way to do correct clipping in the given case? ‘Easy way’ shall mean around 5 to 10 or so lines of shader code, in any case easier than the whole Cohen-Sutherland machinery.[/QUOTE]
It’s much simpler if you transform both ray_start_pos and reflection_dir to clip space. In that situation, and provided that ray_start_pos lies within the view frustum, then you can use:
The vector l0 contains the lengths at which the ray will coincide with the x=-w, y=-w and z=-w planes. The vector l1 contains the lengths at which the ray will coincide with the x=w, y=w and z=w planes. You want the smallest positive value. Provided that ray_start_pos is within the view frustum, each component (x, y or z) will be negative in one vector and positive in the other, so max(l0,l1) will choose the positive value for each component.
[QUOTE=GClements;1280833]It’s much simpler if you transform both ray_start_pos and reflection_dir to clip space. In that situation, and provided that ray_start_pos lies within the view frustum, then you can use: