Page 1 of 3

4-day Multi-threaded Interactive Ray Tracer

Posted: Thu Dec 04, 2008 11:16 pm
by nullsquared
Edit:
I kind of ditched this project, never figured out what caused the BSOD. Anyways, if anyone wants the source, here: http://www.MegaShare.com/607586

It requires Newton 2.0, SDL or the Corona image library, (depends on whether you want the "interactive" one or a series of images), the Configurable Math Library (CML), and boost (with a compiled Boost.Thread library).

Edit:
Alright, up to 4 days. Now it's not only multi-threaded, but interactive! Well, it really depends on your settings. On my Athlon64 X2 3800+, with 4 threads, it does 128x128 very fluidly with ~50 spheres and 2 levels of reflections. I'd love to see how this runs on a quad-core machine with a higher resolution! :D

<snip until fix blue screen>

Old:
I made myself a quick ray tracer in 2 days, just as a nice little challenge and to have fun...

Then I used a third day to add physics animation to it. It was already physics-based, so all I need to do was make it run in a loop and call world::tick() after each iteration.

Some nice results:
Image
Image

A short video (overnight render, 108 frames at 2048x2048 with 2 threads on my X2 3800+): http://www.youtube.com/watch?v=j6-lR5cBYuY&fmt=18

Basically, it just uses Newton Game Dynamics combined with Boost.Thread to ray trace using a user-defined amount of threads. It also uses this number of threads for the actual physics simulation. Uses corona to save the images to a .png, and Portalized engine's phys:: subsystem to wrap NewtonGD (configurable math library replaces Portalized's default math library, which is Ogre :D). The ray tracer itself is a single main.cpp file, only about 200 lines.

I'm making a new demo shortly, will upload. I'm interested on how it runs on one of those fast quad (or even octo) cores... According to Julio, it rendered 1024x1024 in 3 seconds, which is pretty cool :D

Posted: Thu Dec 04, 2008 11:42 pm
by betajaen
Dude; only child prodigies make ray-tracers for fun. :D

Seriously though. 200 lines? I would love to see that.

Posted: Fri Dec 05, 2008 2:50 am
by nullsquared
betajaen wrote:Dude; only child prodigies make ray-tracers for fun. :D

Seriously though. 200 lines? I would love to see that.
If you count blanks and comments, it's exactly 381 for 100% of the ray tracer itself, including image loading/saving, pixel access, ray calculation, and all that:

Code: Select all

#include <iostream>
#include <string>
#include <list>
#include <cstdlib>
#include <numeric>
#include <ctime>
#include <vector>
#include <algorithm>
#include <ctime>
#include <cmath>

#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <boost/optional.hpp>
#include <boost/any.hpp>
//#include <boost/thread.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>

#include <corona.h>

#include <cml/cml.h>

#include "phys/body.hpp"
#include "phys/ray.hpp"
#include "phys/world.hpp"
#include "phys/mesh.hpp"
#include "types.hpp"
#include "rand.hpp"

using namespace engine;

class entity: public phys::body
{
    private:

    public:

        entity(const phys::world &w):
            phys::body(w)
        {
            misc = this;
        }

        struct material_t
        {
            float reflectivity;
            vec3 diffuse, specular;

            material_t(): reflectivity(0), diffuse(1, 1, 1), specular(1, 1, 1) {}
        } material;
};

struct light
{
    vec3 diffuse;
    vec3 specular;
    vec3 position;
    float radius;

    light(const vec3 &d = vec3(1, 1, 1), const vec3 &s = vec3(1, 1, 1), const vec3 &p = vec3(0, 0, 0), float r = 10):
        diffuse(d), specular(s), position(p), radius(r) {}
};

typedef boost::shared_ptr<entity> entityPtr;
typedef std::list<entityPtr> entityList;
typedef std::list<light> lightList;

mat4 lookAt(const vec3 &p, const vec3 &dir, const vec3 &up)
{
    mat4 ret;
    cml::matrix_look_at_RH(ret, p, dir, up);
    return ret;
}

struct ray_t
{
    vec3 origin, dir;

    ray_t(const vec3 &o, const vec3 &d):
        origin(o), dir(d) {}

    ray_t():
        origin(0, 0, 0), dir(0, 0, -1) {}
};

ray_t screenRay(float x, float y, const mat4 &camMat, const float FOCAL_DIST = 1) // normalized screen coords
{
    x = x * 2 - 1;
    y = y * 2 - 1;

    vec3 orig(camMat(0, 3), camMat(1, 3), camMat(2, 3));
    vec4 dest(x, y, -FOCAL_DIST, 1);
    //orig = mat * orig;
    dest = camMat * dest;
    return ray_t(orig, normalize(vec3(dest[0], dest[1], dest[2]) - orig));
}

//vec3 calcDirect(vec3 p, vec3 n, const light &l, const entity::material_t &mat)
//{
//    vec3 distv3 = l.position - p;
//    float dist = length(distv3);
//    distv3 /= dist; // normalize
//
//    float att = 1.0 - saturate(dist / l.radius);
//
//    vec3 illum(0, 0, 0);
//    { // NdotL
//        float NdotL = saturate(dot(n, distv3));
//        illum += mul(mat.diffuse, l.diffuse) * NdotL * att;
//    }
//    { // specular
//    }
//    return illum;
//}

boost::optional<phys::ray::hitInfo> rayTrace(const ray_t &start, const phys::world &w, float dist = 1.e3)
{
    phys::ray ray(w);
    if (ray(start.origin, start.origin + start.dir * dist))
        return ray.result;
    return boost::optional<phys::ray::hitInfo>();
}

size_t maxIterations = 10;

boost::optional<vec3> colourFromRay(const ray_t &start, const phys::world &w, const mat4 &invViewMat,
    const lightList &lights, size_t iter = 0)
{
    if (iter > maxIterations)
        return boost::optional<vec3>();

    vec3 cameraPos(invViewMat(0, 3), invViewMat(1, 3), invViewMat(2, 3));

    boost::optional<phys::ray::hitInfo> ret = rayTrace(start, w);
    if (ret)
    {
        phys::ray::hitInfo info = ret.get();
        entity *ent = boost::any_cast<entity*>(info.b->misc);

        vec3 eyePos(invViewMat(0, 3), invViewMat(1, 3), invViewMat(2, 3));
        vec3 eyeDir = normalize(eyePos - info.p);

        vec3 illum(0, 0, 0);

        BOOST_FOREACH(const light &l, lights)
        {
            vec3 distv3 = l.position - info.p;

            // raw NdotL, just to figure out whether we should compute lighting
            float NdotLRaw = dot(info.n, distv3);
            if (NdotLRaw > 0)
            {
                float dist = length(distv3);
                distv3 /= dist; // normalize
                // take 'real' NdotL
                float NdotL = dot(info.n, distv3);

                float att = 1.0 - saturate(dist / l.radius);

                vec3 diffuse = mul(ent->material.diffuse, l.diffuse) * NdotL * att;
                vec3 specular(0, 0, 0);

                vec3 hv = normalize(distv3 + eyeDir);
                float NdotH = dot(info.n, hv);
                if (NdotH > 0)
                {
                    specular = /*mul(ent->material.specular, l.specular)*/vec3(1, 1, 1) * std::pow(NdotH, 64);
                }

                ray_t shadowRay(info.p, normalize(l.position - info.p));
                illum += (diffuse + specular) * !rayTrace(shadowRay, w, l.radius);
            }
        }

        if (ent->material.reflectivity > 0.01)
        {
            boost::optional<vec3> c = colourFromRay(ray_t(info.p, reflect(start.dir, info.n)), w, invViewMat, lights, ++iter);
            if (c)
                illum += mul(ent->material.specular, c.get()) * ent->material.reflectivity;
        }

        return illum;
    }
    float sky = /*std::abs(*/dot(start.dir, vec3(0, 1, 0))/*)*/;
    if (sky <= 0)
        return boost::optional<vec3>();
    return boost::optional<vec3>(vec3(223.0 / 255.0, 151.0 / 255.0, 0) * sky);
}

void createScene(entityList &scene, phys::world &world, size_t numObjects = 250)
{
    for (size_t i = 0; i < numObjects; ++i)
    {
        entityPtr ent(new entity(world));

        vec3 p(randUnit() * 25, rand01() * 50, randUnit() * 25);
        vec3 d(10, 10, 10);
        ent->collision(phys::mesh::ball(world, d));
        ent->pos(p);
        ent->mass(10);

        entity::material_t &m = ent->material;
        m.reflectivity = 1;
        m.diffuse = m.specular = randUnitVec() * 0.5 + vec3(0.5, 0.5, 0.5);
        //m.specular = randUnitVec() * 0.5 + vec3(0.5, 0.5, 0.5);

        scene.push_back(ent);
    }
    // ent
    {
        entityPtr ent(new entity(world));

        vec3 d(150, 1, 150);
        ent->collision(phys::mesh::box(world, d));
        ent->pos(vec3(0, d[1] * -0.5, 0));
        ent->mass(0);
        ent->material.reflectivity = 1;
        ent->material.diffuse = ent->material.specular = vec3(1, 1, 1);

        scene.push_back(ent);
    }
}

void createLights(lightList &lights)
{
    lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(0, 50, 0), 100));
    //lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(0, 15, 0), 25));
    //lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(-50, 75, 50), 150));
    //lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(-50, 75, -50), 150));
    //lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(50, 75, 50), 150));
    //lights.push_back(light(vec3(1, 1, 1), vec3(1, 1, 1), vec3(50, 75, -50), 150));
}

mat4 createViewMat()
{
    return lookAt(vec3(25, 25, 25), vec3(0, 0, 0), vec3(0, 1, 0));
}

struct pixel
{
    float x, y;
    engine::byte *p;
    pixel(float x, float y, engine::byte *p):
        x(x), y(y), p(p) {}
};

void tracePixel(const pixel &p, const mat4 &viewMat, const mat4 &invViewMat, const phys::world &w, const lightList &lights)
{
    // y goes from bottom to top
    ray_t r = screenRay(p.x, p.y, invViewMat);
    vec3 c = saturate(colourFromRay(r, w, invViewMat, lights).get_value_or(vec3(0, 0, 0)));

    for (size_t j = 0; j < 3; ++j)
        p.p[j] = engine::byte(c[j] * 255.0);
    p.p[3] = 255;
}

void tracePixels(const std::vector<pixel> &pixels, const mat4 &viewMat, const mat4 &invViewMat,
    const phys::world &w, const lightList &lights)
{
    for (size_t i = 0; i < pixels.size(); ++i)
        tracePixel(pixels[i], viewMat, invViewMat, w, lights);
}

struct tracer
{
    std::vector<pixel> pixels;
    mat4 viewMat, invViewMat;
    const phys::world &world;
    const lightList &lights;

    tracer(const std::vector<pixel> &pixels, const mat4 &viewMat, const mat4 &invViewMat,
        const phys::world &w, const lightList &lights):
        pixels(pixels), viewMat(viewMat), invViewMat(invViewMat), world(w), lights(lights) {}

    inline void operator()() { tracePixels(pixels, viewMat, invViewMat, world, lights); }
};

typedef boost::shared_ptr<corona::Image> imagePtr;

inline imagePtr create(size_t w, size_t h) { return imagePtr(corona::CreateImage(w, h, corona::PF_R8G8B8A8)); }
inline void save(const imagePtr &img, size_t i = 0)
{
    corona::SaveImage(("out" + boost::lexical_cast<engine::string>(i) + ".png").c_str(), corona::FF_AUTODETECT, img.get());
}

void go(const mat4 &viewMat, const mat4 &invViewMat,
    const phys::world &world, const lightList &lights, std::vector<pixel> &pixels, size_t numThreads)
{
    size_t numPixels = pixels.size();
    size_t pixelsPerThread = numPixels / numThreads;

    std::vector<std::vector<pixel> > threadPixels(numThreads);

    for (size_t i = 0; i < threadPixels.size(); ++i)
    {
        std::vector<pixel> &v = threadPixels[i];
        v = std::vector<pixel>(pixels.begin() + i * pixelsPerThread, pixels.begin() + (i + 1) * pixelsPerThread);
    }

    typedef boost::shared_ptr<boost::thread> threadPtr;
    std::vector<threadPtr > threads;

    for (size_t i = 1; i < threadPixels.size(); ++i)
        threads.push_back(threadPtr(new boost::thread(tracer(threadPixels[i], viewMat, invViewMat, world, lights))));

    // use the current thread, too
    tracePixels(threadPixels[0], viewMat, invViewMat, world, lights);

    // wait for other threads
    for (size_t i = 0; i < threads.size(); ++i)
        threads[i]->join();
}

int main(int argc, char **argv)
{
    seedRand();

    size_t width = 512, height = 512, numThreads = 1;

    std::cout << "size: ";
    std::cin >> width;
    if (width < 4)
        width = 4;
    height = width;

    std::cout << "number of threads: ";
    std::cin >> numThreads;

    std::cout << "number of frames: ";
    size_t numFrames = 1;
    std::cin >> numFrames;

    std::cout << "delta time (seconds) (big if you're not rendering loads of frames): ";
    double deltaTime = 0.25;
    std::cin >> deltaTime;

    std::cout << "number of objects (phys time is pretty low usually): ";
    size_t numObjects = 250;
    std::cin >> numObjects;

    std::cout << "max number of reflections: ";
    std::cin >> maxIterations;

    imagePtr screen = create(width, height);
    engine::byte *data = (engine::byte*)screen->getPixels();

    std::vector<pixel> pixels;
    pixels.reserve(width * height);
    for (size_t i = 0; i < pixels.capacity(); ++i)
    {
        size_t x = i % width;
        size_t y = i / width;
        pixels.push_back(pixel(float(x) / width, 1.0 - float(y) / height, data + i * 4));
    }

    mat4 viewMat = createViewMat();
    mat4 invViewMat = inverse(viewMat);

    phys::world world;
    world.threads(numThreads);

    entityList scene;
    createScene(scene, world, numObjects);

    lightList lights;
    createLights(lights);

    for (size_t i = 0; i < numFrames; ++i)
    {
        go(viewMat, invViewMat, world, lights, pixels, numThreads);
        world.tick(deltaTime);

        save(screen, i);

        std::cout << "done with frame " << i << "\n";
    }

    return 0;
}

Posted: Fri Dec 05, 2008 3:19 am
by Kojack
Dude; only child prodigies make ray-tracers for fun.
I've made them for fun, and I'm not a child. :)

I made a fun little one as a university project. Various shapes (spheres, cylinders, planes, rectangular solids, lightwave mesh importing, etc), procedural texturing plugins (my perlin turbulence plugin got the most use, but I also made mathematical wood, marble and other surfaces), spherical panorama rendering, stereogram and red/blue anaglyph 3d rendering, fog, and distributed network rendering.

I really should work on a new one some day. It's far more fun than shader coding. :)

Posted: Fri Dec 05, 2008 9:35 am
by Azgur
Aah, the fun of ray tracing. Only to be misunderstood later when you say you like shiny balls.
It's looking good :)

I'll share my balls as well, including the most fun thing I ever did: constructive solid geometry.

Image

(In case gamedev doesn't allow hotlinking, http://www.gamedev.net/community/forums ... _id=515750, it's the one labeled Remco van Oosterhout)

Posted: Fri Dec 05, 2008 9:44 am
by Kojack
I might as well join in the spherical fun. :)

Image

Posted: Fri Dec 05, 2008 9:53 am
by tuan kuranes
It's far more fun than shader coding
well, if you'll end coding shaders anyway...
cuda raytrace 10x speed up...(exe+source)

Btw, as all rt expert people here, we might as well try to comment on NVidia interactive ray tracing and how we could plan an hybrid (raster/raytrace) rendersystem in Ogre ?

Posted: Fri Dec 05, 2008 12:11 pm
by _tommo_
Wow, really cool screens! :D
How many hours it required to have 108 fps? :P

I especially liked azgur's one... it hasn't that sharp, artificial and cold look that is so strong in raytraced images... instead is soft and somewhat warm.

anyway, I also want to write one :D
I have only to get a CUDA or OpenCL GPU... any news on the latter?
It would be cool to test a OpenCL raytracer on a 2TFlops HD4870... it could even be real-time!

Posted: Fri Dec 05, 2008 1:57 pm
by Azgur
No need for CUDA to get fast ray tracing.
Arauna already gets somewhat real-time speeds on today's systems using just the CPU. Imagine how it performs when Larrabee hits the market :)
http://igad.nhtv.nl/~bikker/

I doubt it'll be a doable task to implement a ray tracing rendering system in Ogre though. At least without dismissing alot of features.

nullsquared: Next step now would be a path tracer :) They're loads of fun aswell.

Posted: Fri Dec 05, 2008 2:06 pm
by buckED
Man Nullsquared. You are nuts.

You know there was a time I actually believed you were human... :lol:

Posted: Fri Dec 05, 2008 4:47 pm
by Kencho
He actually is. Or rather, his race once was. Nullsquared, I assume we survived the global warming effect. How's life going on the 30th century?

Posted: Sat Dec 06, 2008 8:06 am
by Vectrex
Nice... Now it's onto to realtime radiosity for Ogre like www.geomerics.com :D

Posted: Sat Dec 06, 2008 10:59 am
by Kojack
Nice... Now it's onto to realtime radiosity for Ogre like www.geomerics.com
It's that word "realtime" that takes all the fun out of writing a renderer. There's so much more you can do with simpler code when you don't care about a frame rate. :)

Posted: Sat Dec 06, 2008 2:45 pm
by nullsquared
Vectrex wrote:Nice... Now it's onto to realtime radiosity for Ogre like www.geomerics.com :D
The thing with that product is that the environment is always simple. Just look at the screenshots. It's just so ... empty. Crysis didn't have real-time radiosity, yet its environment 'changed drastically in the day-to-night cycle' (as one of the screenshots of that product shows).

And about the real-time ray tracing ... The thing is, of course it's possible. But it cannot surpass rasterization. I don't care if some ray tracer can do normal mapping, specular, diffuse, per-pixel shadows, etc, at 20 FPS on a quad-core. You can do all of that and way more just by using rasterization with a modern GPU and some shaders - at above 100 FPS.

Once you start adding in complex reflections and refractions, correct soft shadows, ambient occlusion, global illumination, and the rest of the stuff that ray tracing is really meant for, it's not going to be real-time anymore.

Posted: Sat Dec 06, 2008 2:59 pm
by Azgur
Don't dismiss real-time ray tracing so easily :)
Arauna, which is developed internally at our school is quite close to doing real-time global illumination and all related shinyness.
Ofcourse, there's quite some tricks involved to do this, but the results I've seen internally so far are quite spectacular.
Don't assume the stuff Intel and nVidia shows is as fast as it gets. We're faster, alot faster :)

Alright, it doesn't get the desired performance on current hardware. It's getting the bare minimum in FPS. (Though, current projects using it don't mind throwing in a million triangles).
But once Larrabee hits the market, that'll change drastically. The entire design of it just screams ray tracing.

Posted: Sat Dec 06, 2008 4:19 pm
by jjp
Why? Larrabee screams "better configurable rasterization pipeline" I think ;)

Posted: Sat Dec 06, 2008 4:22 pm
by nullsquared
Azgur wrote:Don't dismiss real-time ray tracing so easily :)
Arauna, which is developed internally at our school is quite close to doing real-time global illumination and all related shinyness.
Ofcourse, there's quite some tricks involved to do this, but the results I've seen internally so far are quite spectacular.
Don't assume the stuff Intel and nVidia shows is as fast as it gets. We're faster, alot faster :)

Alright, it doesn't get the desired performance on current hardware. It's getting the bare minimum in FPS. (Though, current projects using it don't mind throwing in a million triangles).
But once Larrabee hits the market, that'll change drastically. The entire design of it just screams ray tracing.
Don't get me wrong, I'm not saying Arauna is crappy. In fact, it's rather awesome that it runs in real-time, especially with all of those features. Yes, I've checked out the demo, and it runs interactively even on my X2 4800+.

But once you think about what it actually gives you over a rasterizer ... well, nothing. Except a speed decrease ;) Very, very few people are going to have Larrabees. And even then, what is the ray tracer going to offer over the rasterizer?

In all of the screenshots I see, it's all about some simple phong and hard shadows. Alright, say you add in some global illumination and keep it completely real-time on Larrabee. It still doesn't offer anything significant over a rasterizer, which will run so much faster on so much more hardware.
Arauna wrote: The sphere code in Arauna is efficient, and does not reduce the performance of scenes that have no spheres.
The way that is written, I understand it as 'add in a few reflective spheres and you've got a big performance problem.' One of the primitive problems solved by ray tracing, reflections, is pretty much dismissed.

And it's not just Arauna (really, I'm not picking on Arauna itself). Take QuakeIV ray-traced (using OpenRT). Ok, so you get real-time ray tracing for QuakeIV. Does it make QuakeIV look any better? No. It makes it look horrible. What do you get in return? A giant speed decrease.

Ray tracing is not going to replace rasterization any time soon. Or any time not-so-soon, either. All of the benefits it offers over rasterization - reflections, refractions, physically correct shadows, global illumination, and all of that 'good stuff' - are always going to be extremely slow - even on Larrabee's, which practically no one will actually have to begin with. So what does real-time ray tracing actually offer over rasterization? Nothing.

Posted: Sat Dec 06, 2008 4:39 pm
by Azgur
Arauna does do reflections (just not on spheres atm which were only very recently added) and if used correctly in your scene, the performance impact isn't that bad at all.
The implementation of global illumination that is currently being made won't need a larrabee to run in real-time. It'll run on performance similar to the demo's already shown. (There are some neat tricks behind it)

Research into real-time ray tracing is still pretty fresh and new techniques are discovered to reduce the gap between rasterizing.
Give it a few years :)

Posted: Sat Dec 06, 2008 5:06 pm
by nullsquared
Still, see my point of "it has nothing over rasterization."

Anyways, all of this 'real-time' talk has gotten me to go real-time, too :D. Well, interactive. Can't really compete with Arauna, but I'm working on an SDL demo that ray traces at 4 FPS! :twisted:



... :oops:


But still, :twisted:

Posted: Sat Dec 06, 2008 5:11 pm
by Azgur
"it has nothing over rasterization".
Perfect reflections on complex surfaces are dead sexy kthnx :) I don't see a rasterizer do that.
As it is now, reflections are quite expensive on a rasterizer aswell and they're pretty much restricted to flat surfaces.

But I get your point. Currently there's little ray tracing has to offer for games.
Kinda the reason our team picked up Ogre instead of Arauna for our current project.

Posted: Sat Dec 06, 2008 5:30 pm
by _tommo_
nullsquared wrote: Don't get me wrong, I'm not saying Arauna is crappy. In fact, it's rather awesome that it runs in real-time, especially with all of those features. Yes, I've checked out the demo, and it runs interactively even on my X2 4800+.

But once you think about what it actually gives you over a rasterizer ... well, nothing. Except a speed decrease ;) Very, very few people are going to have Larrabees. And even then, what is the ray tracer going to offer over the rasterizer?

In all of the screenshots I see, it's all about some simple phong and hard shadows. Alright, say you add in some global illumination and keep it completely real-time on Larrabee. It still doesn't offer anything significant over a rasterizer, which will run so much faster on so much more hardware.

The way that is written, I understand it as 'add in a few reflective spheres and you've got a big performance problem.' One of the primitive problems solved by ray tracing, reflections, is pretty much dismissed.

And it's not just Arauna (really, I'm not picking on Arauna itself). Take QuakeIV ray-traced (using OpenRT). Ok, so you get real-time ray tracing for QuakeIV. Does it make QuakeIV look any better? No. It makes it look horrible. What do you get in return? A giant speed decrease.

Ray tracing is not going to replace rasterization any time soon. Or any time not-so-soon, either. All of the benefits it offers over rasterization - reflections, refractions, physically correct shadows, global illumination, and all of that 'good stuff' - are always going to be extremely slow - even on Larrabee's, which practically no one will actually have to begin with. So what does real-time ray tracing actually offer over rasterization? Nothing.
Yes, it's exactly what I think.

And, we must add that RT is a total let down on the artistic side: it kills any NPR effect, kills the artist interpretation, kills near everything in the name of a perfect physically simulated light.
And noboy needs that in an entertainment thing...

Did you see Cars, or Wall-E, by Pixar? That incredibily good graphics were almost completely rasterized... with RT used only on shiny surfaces.
IMHO, if a rich and techinologically advanced team like pixar still prefers old-style rasterizing, RT has to have some nasty limits... at least on the "beauty" of the image.

I still have to see a raytraced image that doesn't look cold and artificial...

Posted: Sat Dec 06, 2008 5:36 pm
by nullsquared
This 'interactive' thing is really cool :D

Total of 4 days working on a ray tracer, and it traces at >4 FPS at 512x512 on 4 threads on an X2 3800+, and it simulates physics, too!

Posted: Sat Dec 06, 2008 6:19 pm
by jjp
_tommo_ wrote:And, we must add that RT is a total let down on the artistic side: it kills any NPR effect, kills the artist interpretation, kills near everything in the name of a perfect physically simulated light.
And noboy needs that in an entertainment thing...

Did you see Cars, or Wall-E, by Pixar? That incredibily good graphics were almost completely rasterized... with RT used only on shiny surfaces.
IMHO, if a rich and techinologically advanced team like pixar still prefers old-style rasterizing, RT has to have some nasty limits... at least on the "beauty" of the image.

I still have to see a raytraced image that doesn't look cold and artificial...
E.g. go to the website of mentalray and look at some images over there. "Ray tracing" doesn't exclude NPR nor does it actually provide a perfect physical simulation of light.

Further, while Pixar movies are a great example for how much can be done without doing a lot of ray tracing there is one difference to real time graphics: for a movie every shot can be hand-tweaked and skilled lighting artists are very good at faking things like global illumination. For a game this doesn't work.

Which doesn't mean rasterization can't be used for real time graphics with effects a lot more complex than we see today. But the analogy between movies and games only holds true up to a certain point.

Posted: Sat Dec 06, 2008 9:05 pm
by _tommo_
jjp wrote: E.g. go to the website of mentalray and look at some images over there. "Ray tracing" doesn't exclude NPR nor does it actually provide a perfect physical simulation of light.

Further, while Pixar movies are a great example for how much can be done without doing a lot of ray tracing there is one difference to real time graphics: for a movie every shot can be hand-tweaked and skilled lighting artists are very good at faking things like global illumination. For a game this doesn't work.

Which doesn't mean rasterization can't be used for real time graphics with effects a lot more complex than we see today. But the analogy between movies and games only holds true up to a certain point.
Well, a skilled artist can tweak reasterization as much as mental ray, so your initial example isn't so fitting :)
Anyway it's true that the analogy works only until a certain point, but think at Bioshock, Half Life 2 or Crysis. While being realistic, they have very distinct looks...
i'm afraid that, instead, using a raytracer everything would look like a screenshot of the same game.

Just look at the screenshots in this thread, 3 completely different RT engines, based on different algorithms and skills produce nearly the same result, visually speaking.
So, for me RT can be tweaked, but not very much... in fact pixar would use it if a skilled artist could tweak it to improve an image :roll:

Posted: Sat Dec 06, 2008 11:18 pm
by Bekas
_tommo_ wrote:Did you see Cars, or Wall-E, by Pixar? That incredibily good graphics were almost completely rasterized... with RT used only on shiny surfaces.
IMHO, if a rich and techinologically advanced team like pixar still prefers old-style rasterizing, RT has to have some nasty limits... at least on the "beauty" of the image.
That's a very interesting point.

_tommo_ is talking about the ideal situation for RT, no real-time requirements, lots of powerful workstations with all the offline time in the world to produce RT images, and still they choose rasterization.

I don't think it's because they don't know how to fully utilize RT..