POV-Ray : Newsgroups : povray.off-topic : Ray tracers and transformations Server Time
6 Nov 2024 20:19:33 EST (-0500)
  Ray tracers and transformations (Message 1 to 10 of 21)  
Goto Latest 10 Messages Next 10 Messages >>>
From: Severi Salminen
Subject: Ray tracers and transformations
Date: 13 Mar 2008 16:21:42
Message: <47d99ae6$1@news.povray.org>
I have a "fully" working path tracer under development. The next thing
to implement is transformations (at least translate and rotate). What is
the best (fastest) way to do it?

Let's take box for example. Now I have a method for calculating
axis-aligned box intersections. So if I rotate the box how should I
proceed?

I was thinking that maybe I should not rotate the box, but rotate the
ray so that I can use the fast AABox intersection routines. And then I
get intersection point and surface normal, which I rotate back to world
space?

Am I missing something here and is the the best way to do it?

Thanks.


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Ray tracers and transformations
Date: 13 Mar 2008 16:32:13
Message: <47d99d5d$1@news.povray.org>

> I have a "fully" working path tracer under development. The next thing
> to implement is transformations (at least translate and rotate). What is
> the best (fastest) way to do it?
> 
> Let's take box for example. Now I have a method for calculating
> axis-aligned box intersections. So if I rotate the box how should I
> proceed?
> 
> I was thinking that maybe I should not rotate the box, but rotate the
> ray so that I can use the fast AABox intersection routines. And then I
> get intersection point and surface normal, which I rotate back to world
> space?
> 
> Am I missing something here and is the the best way to do it?

As far as I know, the way POV-Ray does it (and probably most others) is 
by creating a transformation matrix of all the individual 
transformations, then inversing it, and using it to transform *rays* 
before doing the intersection calculations.

But don't trust me on this. I still haven't managed to solve the 
ray-sphere intersection equation...


Post a reply to this message

From: Orchid XP v7
Subject: Re: Ray tracers
Date: 13 Mar 2008 16:45:43
Message: <47d9a087$1@news.povray.org>
Nicolas Alvarez wrote:

> As far as I know, the way POV-Ray does it (and probably most others) is 
> by creating a transformation matrix of all the individual 
> transformations, then inversing it, and using it to transform *rays* 
> before doing the intersection calculations.

I believe that is correct. (Transforming the object equation would be 
much harder...)

> But don't trust me on this. I still haven't managed to solve the 
> ray-sphere intersection equation...

Suppose you have a sphere with center C [a vector] and radius r [a 
scalar]. The equation for this is

   (P - C)^2 - r^2 = 0

(Where squaring a vector *really* means taking the dot product of the 
vector with itself.) Here P is your unknown - but it's a vector. If we 
replace that with the ray equation

   Ray(t) = Dt + S

then we obtain

   (Dt + S - C)^2 - r^2 = 0

If we set V = S - C then we have

   (Dt + V)^2 - r^2 = 0

and expanding we find

   D^2t^2 + 2VDt + V^2 - r^2 = 0

Writing "#" to explicitly mean "dot product", what I really mean is

   (D # D) t^2 + 2 (V # D) t + (V # V) - r^2 = 0

Notice this is a quadratic in one unknown - t, a scalar. In fact, what 
we have is

   a t^2 + b t + c = 0

where

   a = D # D
   b = 2 (V # D)
   c = (V # V) - r^2

Solving this yields a value for t which satisfies the equation. If you 
substitute this t back into the original ray equation, it gives you a 
point in space for the intersection.

Notice that if you compute multiple intersections, the one with the 
lowest value for t is guaranteed to be the "front" one [assuming that S 
is the "start point" of the ray. Oh, and if t is negative, the 
intersection is "behind" the camera or whatever, and you should ignore 
that intersection...]

Any clearer? ;-)

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Severi Salminen
Subject: Re: Ray tracers
Date: 13 Mar 2008 17:01:16
Message: <47d9a42c@news.povray.org>
Orchid XP v7 wrote:

>> As far as I know, the way POV-Ray does it (and probably most others)
>> is by creating a transformation matrix of all the individual
>> transformations, then inversing it, and using it to transform *rays*
>> before doing the intersection calculations.
> 
> I believe that is correct. (Transforming the object equation would be
> much harder...)

Ok, then I was on the right tracks. I only have to transform the ray
using conventional point and vector transformations. Thanks!

>> But don't trust me on this. I still haven't managed to solve the
>> ray-sphere intersection equation...

There is neat method also Pov-Ray uses. I used almost identical but
Pov's version had (IIRC) simpler form with 1-2 less arithmetic
operations. Here is my implementation:

"position" is the center of the sphere
"origin" and "direction" specify the ray
"nearestPointDistance" is the distance from origin to a point where the
ray is closest to the sphere
"halfCord2" is the square of...well...half of the cord the ray creates
inside the sphere :)

If you draw this on a paper it is very simple approach and quite fast,
too. It returns the distance to the closest intersection point.


double Mass::intersect(Vector origin, Vector direction) const
{
    Vector relPosition = position - origin;
    double radius2 = radius * radius;
    double nearestPointDistance = relPosition*direction;

    double halfChord2 = radius2 - relPosition*relPosition +
nearestPointDistance*nearestPointDistance;

    if(halfChord2 > 0.0)
    {
        double nearPoint = nearestPointDistance - sqrt(halfChord2);
        double farPoint = nearestPointDistance + sqrt(halfChord2);
        if(nearPoint > EPSILON)
            return nearPoint;
        else
            return farPoint;
    }
    else
        return -1.0;
}


Post a reply to this message

From: Nicolas Alvarez
Subject: Re: Ray tracers
Date: 13 Mar 2008 17:14:30
Message: <47d9a746$1@news.povray.org>

> Any clearer? ;-)

Thanks; shows I'm still too noob for this kind of things.



(that's a no)


Post a reply to this message

From: Warp
Subject: Re: Ray tracers and transformations
Date: 13 Mar 2008 19:10:20
Message: <47d9c26b@news.povray.org>
Nicolas Alvarez <nic### [at] gmailisthebestcom> wrote:
> As far as I know, the way POV-Ray does it (and probably most others) is 
> by creating a transformation matrix of all the individual 
> transformations, then inversing it, and using it to transform *rays* 
> before doing the intersection calculations.

  That's the reason why you can't, for example, scale something by 0.
Inverting that matrix would result in a division by 0.

-- 
                                                          - Warp


Post a reply to this message

From: Slime
Subject: Re: Ray tracers
Date: 14 Mar 2008 02:28:22
Message: <47da2916$1@news.povray.org>
> double Mass::intersect(Vector origin, Vector direction) const
> {
>    Vector relPosition = position - origin;
>    double radius2 = radius * radius;
>    double nearestPointDistance = relPosition*direction;
>
>    double halfChord2 = radius2 - relPosition*relPosition +
> nearestPointDistance*nearestPointDistance;
>
>    if(halfChord2 > 0.0)
>    {
>        double nearPoint = nearestPointDistance - sqrt(halfChord2);
>        double farPoint = nearestPointDistance + sqrt(halfChord2);
>        if(nearPoint > EPSILON)
>            return nearPoint;
>        else
>            return farPoint;
>    }
>    else
>        return -1.0;
> }

Is this what POV-Ray actually uses for the intersection of a ray and a 
sphere? I just spent half an hour working out both the geometrical 
interpretation of this and its equivalence to the result of the quadratic 
equation with the coefficients that Andrew posted, and I'm really impressed 
at how simple it is. And annoyed at the fact that I never could have come up 
with it myself =)

 - Slime
 [ http://www.slimeland.com/ ]


Post a reply to this message

From: Warp
Subject: Re: Ray tracers
Date: 14 Mar 2008 03:52:27
Message: <47da3cca@news.povray.org>
Severi Salminen <sev### [at] notthissaunalahtifiinvalid> wrote:
>         double nearPoint = nearestPointDistance - sqrt(halfChord2);
>         double farPoint = nearestPointDistance + sqrt(halfChord2);

  Perhaps you shouldn't rely on the ability of the compiler to realize
that the exact same sqrt() is being performed here, and instead calculate
it only once into a variable. That way you remove the risk of the
code actually calculating the slow sqrt() twice for no reason.

-- 
                                                          - Warp


Post a reply to this message

From: Invisible
Subject: Re: Ray tracers and transformations
Date: 14 Mar 2008 04:30:47
Message: <47da45c7$1@news.povray.org>
Warp wrote:

>   That's the reason why you can't, for example, scale something by 0.
> Inverting that matrix would result in a division by 0.

Presumably it would also result in an invisible object too though. ;-)

Does POV-Ray actually apply all the matricies and invert only the final 
one? Or does it construct them in inverted form in the first place?

-- 
http://blog.orphi.me.uk/
http://www.zazzle.com/MathematicalOrchid*


Post a reply to this message

From: Severi Salminen
Subject: Re: Ray tracers
Date: 14 Mar 2008 04:41:36
Message: <47da4850@news.povray.org>
Warp wrote:

>   Perhaps you shouldn't rely on the ability of the compiler to realize
> that the exact same sqrt() is being performed here, and instead calculate
> it only once into a variable. That way you remove the risk of the
> code actually calculating the slow sqrt() twice for no reason.
> 

Good point, thanks for the suggestion. I checked the assembly output and
g++ produces better results with a temporary variable. Less code and
less jumps. Few questions:

1. I understand that sqrtsd takes the square root. What does "call sqrt"
do? Calls a subroutine called "sqrt"? Why on earth are they both needed?
The version with temp variable used one "call sqrt" and the original
version used 2 calls. And both had one sqrtsd.

2. What does "ucomisd %xmm0, %xmm0" effectively do? It compares the same
register.

(Last time I really programmed assembly was 10 years ago when I did a
burning flame demo program..."


Anyway, this was the best version:

        double halfChord = sqrt(halfChord2);

        double a = nearestPointDistance - halfChord;
        if(a > EPSILON)
            return a;
        else
            return nearestPointDistance + halfChord;


Post a reply to this message

Goto Latest 10 Messages Next 10 Messages >>>

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.