|
|
Doppelganger <ped### [at] netcabopt> wrote:
> even if Statler doesn't want that explanation, I'd rather like it, as I'm
> getting more and more interested in the internals of raytracing.
If one does not know how transformations should be applied to objects,
one could make the naive assumption that when you transform a mesh, all
the vertex points are just modified according to the transformations.
This could actually work (and most scanline renderers and 3D cards
probably do exactly this), but that would cause at least two problems:
1. If you want to make several instances of the mesh, naturally all
of them transformed in different ways, you'll have to make copies of
the mesh. (Another alternative is to transform all the vertex points
each time you test the intersection of the ray with the mesh instance,
but that would probably be quite slow, specially if the mesh is very
large).
2. It would work only with meshes. You can't use the same idea with
other raytraceable primitives.
The point 2 is quite important in a raytracer. Imagine you have
a box: How do you apply transformations to it?
Translate? No problem. Uniform scale? No problem. Non-uniform scale?
Uh... you probably can manage. Rotate? Uh*2... Maybe. But then...
"rotate x*30 scale <1,.1,1> rotate x*-30"... Uh! No way! The box would
not have 90 degree angles anymore...
You could get away by making the box a mesh... but then there are
the more complex primitives. For example, imagine an infinitely large
polynomial object (eg. a paraboloid). You can't convert everything to
meshes, but the raytracer works with those as well, with transformations
and all.
So obviously transformations are done in a quite different way.
In fact, transformations work with *any* raytraceable object, no matter
how complex it is. There's actually a quite ingenuous way to transform
*any* object in raytracing.
Another ingenuous thing about transformations is that it doesn't matter
how many of them you apply to an object: It will not slow down its
rendering. You can apply a thousand transformations to an object and
it will still render as fast as if you had applied only one (supposing
its size is about the same on screen, etc; the point is that the
*amount* of transformations does not affect its rendering speed).
Have you ever wondered why there's such a limited amount of different
transformations available? Only so-called linear transformations are
available. And there's a reason.
Instead of transforming the object itself (which can be quite a complex
operation, if not impossible), the ray is transformed with the inverse
transformation before testing it against the object.
That is, every transformation you think you are applying to the object
are in fact applied reversely in reverse order to the rays tested against
this object instead.
This is actually a quite simple but ingenuous idea: The object itself
does not need any support for transformations, it's enough that it's
raytraceable and that's it. This method is thus a generic way of
"transforming" *any* object, no matter what that object is.
This is how mesh duplication works: Transform the ray with the inverse
transformations of one mesh "instance" and test against the (single) mesh
data in memory. Then transform the ray with the inverse transformations
of another mesh "instance" and test against the same mesh data in memory.
And so on.
This exact same principle could be applied to any object, not just
meshes. (The reason why POV-Ray does not do exactly this are different,
and perhaps partially historical.)
This also explains why only linear transformations can be applied to
objects: It's the ray which is transformed, not the object, and the
ray must keep straight after the transformation.
Then, what about any number of transformations applied to an object
not affecting its rendering speed?
Transformations are actually all applied to a single transformation
matrix related to the object instead of kept separately.
Try googling for "transformation matrix" for tons of info if you
are interested.
--
#macro N(D)#if(D>99)cylinder{M()#local D=div(D,104);M().5,2pigment{rgb M()}}
N(D)#end#end#macro M()<mod(D,13)-6mod(div(D,13)8)-3,10>#end blob{
N(11117333955)N(4254934330)N(3900569407)N(7382340)N(3358)N(970)}// - Warp -
Post a reply to this message
|
|