Jump to content

My ray-tracing algorithm

Richard Baker

Recommended Posts

I have an implicit surface given by s(x,y,z)=c where c is a constant.

I take a square let's say 16 pixels high by 16 pixels wide 

Each of the four corners of the square, I do this: 

Send a ray passing through the pixel into the scene 

Use Harts sphere-tracing algorithm to determine the point on the ray that is closest to the level set f=c 

Now instead of applying Phong Blinn I just calculate the first order partial derivatives fx, fy and fz but I also calculate the second order partial derivatives fxx, fyy, fzz, fxy, fyz and fzx.

I use theses derivatives to calculate the coefficients of a quadric surface that is essentially a three-variable Taylor series truncated to the first ten terms.

Now, for all the pixels inside the square 256 pixels I calculate the weighted average bilinearly interpolated values of the coefficients. 

The point for doing all this is that quadric surfaces are easy to ray-trace and an analytic solution exists using the quadratic formula.  This is way faster than using Moller-Trombore on thousands of triangles. 

But there are two solutions to the quadratic formula and sometimes the other solution pops up as a false hit resulting in random specks of surface in space.  My question is how do I weed out these false hits? 

Thank you

PS I have already implemented third-order approximation and used Cardano's formula.  

Link to comment
Share on other sites

On 5/18/2022 at 9:24 PM, Richard Baker said:

Now, for all the pixels inside the square 256 pixels I calculate the weighted average bilinearly interpolated values of the coefficients. 

...that is very very strange statement... ray-tracing happens in 3D world space.. then these vertices are projected to 2D screen space.. and then they are on the screen ("pixels").. when you do ray-tracing, there is no such thing as "pixels"..


Edited by Sensei
Link to comment
Share on other sites

I am using bi-quadratic interpolation but the coefficients of the interpolating quadric surface are weighted according to the position in screen-space.  I know it seems unorthodox but it seems like a real viable method.  If anybody has ever ray-traced a sphere (a quadric surface) they would know that no meshes are required; you simply find the ray-sphere intersection using the quadratic formula. 

My solution didn't work for weeding out the false hits. What I currently do is calculate the local Lipschitz constant and divide the value of f at the surface of the quadric where the intersection of the ray occurs.  Then subtract c, and divide that difference by the Lipschitz constant.  This doesn't work because it is overzealous; it eliminates a lot of true hits.   

Thank you for showing interest in my problem.  Specific language is difficult, my scribe is not perfect


Link to comment
Share on other sites

The way I was taught to conceptualize it on scratchapixel.com the focus point is behind the screen plane so it was probably awkward wording on my part because some people conceptualize the focus point in front of the screen plane.  My question still stands; in the case of the interpolating quadric with two intersection points how do I determine which intersection point is a valid interpolation of the implicit surface.  Thanks. 

Link to comment
Share on other sites

I am used to ray-tracing like this:

Have ray-origin vector. Can be 2D vector, or 3D vector. A simple C++ class with two or three fields and some methods which do the basic math with them.

Have ray-direction vector. It's normalized, unit vector.

Have some primitives. Can be triangles, planes, circles, spheres. Whatever. Algorithm of finding intersection changes with each primitive type (yet another C++ class with methods).

Ray-tracing procedure returns scalar output, which is distance.

hit_position = ray_origin + ray_direction * distance

(if intersection procedure finds hit_position, it has to reverse equation to return scalar i.e. distance = ( hit_position - ray_origin ) / ray_direction (careful with division by zero here))

If primitive is sphere or circle, ray can intersect in zero, one or two places. The smallest distance from ray_origin is the right one, and second one is skipped.



If you would provide the source code, it could be more fruitful discussion..

Edited by Sensei
Link to comment
Share on other sites

He has very limited access to word-processor, and handwriting is difficult for him.

For I in range 0, pixel columns, sample frequency (:enter l for j in range 0 pixel rows, sample frequency initialize ray of (i, j) --> unitvector 

for k in range numberofreflections enter findintersection (origin, unitvector) --> parameter enter parameter times unitvector plus origin --> x, y, z

evaluate derivatives (x, y, z) equals partialderivatives 

reflection (normalvector), unitvector --> unitvector

x, y, z --> origin

#now for the second pass nested within the i and j loops 

more later.



Edited by Richard Baker
Link to comment
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

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.