Author Topic: Raymarching Beginners' Thread  (Read 19799 times)

0 Members and 1 Guest are viewing this topic.

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Raymarching Beginners' Thread
« on: March 09, 2011 »
Here a project page for everyone to start learning raymarching with distance fields or also called sphere tracing.

This thread is inspired on pouet page with same name, where beginners already made great progress.

Well, I'm also a beginner on this subject but I was managed to understand it's principle reading a great article by @lx:
http://code4k.blogspot.com/2009/10/potatro-and-raymarching-story-of.html#more

So, I've made an example using RenderMonkey 1.82 that use opengl and directx for you to start, it's a colorful rotated cube :).

Also there's an exe with my current progress.

Our function tool box (all code came from pouet):
Code: [Select]
float3 RotateXAxis(float3 p, float angle)
{
    return float3(p.x, p.y * cos(angle) + p.z * sin(angle), p.z * cos(angle) - p.y * sin(angle));
}

float3 RotateYAxis(float3 p, float angle)
{
    return float3(p.x * cos(angle) + p.z * sin(angle), p.y, p.z * cos(angle) - p.x * sin(angle));
}

float3 RotateZAxis(float3 p, float angle)
{
    return float3(p.x * cos(angle) + p.y * sin(angle), p.y * cos(angle) - p.x * sin(angle), p.z);
}

float capsule(float3 p, float r, float c) {
   return lerp(length(p.xz)-r, length(float3(p.x,abs(p.y)-c,p.z))-r, step(c,abs(p.y)));
}

float plane(float3 p)
{
   return abs(p.y);
}

float sphere(float3 p, float r)
{
   return length(p) - r;
}

float cube(float3 p, float r)
{
   return max(max(abs(p.x) - r, abs(p.y) - r), abs(p.z) - r);
}

//distance to a rounded cube:
float distToCBox( float3 p, float3 box, float rad )
{
   return length( max( abs(p) - box + float3(rad,rad,rad), 0.0 ) ) - rad;
}

float3 GetNormal(float3 p)
{
   float eps = 0.1f;

   return
      normalize(
         float3(
            distance(p + float3(eps, 0, 0)) - distance(p - float3(eps, 0, 0)),
            distance(p + float3(0, eps, 0)) - distance(p - float3(0, eps, 0)),
            distance(p + float3(0, 0, eps)) - distance(p - float3(0, 0, eps))));
}

//negative d -> sss, positive d -> ao
float ao(vec3 p, vec3 n, float d, float i) {
   float o,s=sign(d);
   for (o=s*.5+.5;i>0.;i--) {
      o-=(i*d-f(p+n*i*d*s))/exp2(i);
   }
   return o;
}

// p pos, l direction to light - normalized, d stepwidth, i number of steps
float shadow(vec3 p, vec3 l, float d, float i) {
   float o;
   for (o = 0.; i > 0.; i--) {
      o += f(p+l*i*d);
   }
   return clamp(o, 0.0, 1.0);
}

float perlin(vec3 p) {
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
a.xy = mix(a.xz, a.yw, f.y);
return mix(a.x, a.y, f.z);
}



Choose your preferred api (dx9 or ogl) and start raymarching!

« Last Edit: March 11, 2011 by rbz »
Challenge Trophies Won:

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17407
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Raymarching Beginners' Thread
« Reply #1 on: March 09, 2011 »
That looks great, the twister looks like it's made out of plastacine. :)

I've been reading the Pouet thread a bit, it would be cool if some other people here got interested in this.
Shockwave ^ Codigos
Challenge Trophies Won:

Offline efecto

  • C= 64
  • **
  • Posts: 90
  • Karma: 4
    • View Profile
Re: Raymarching Beginners' Thread
« Reply #2 on: March 09, 2011 »
Interesting stuff and I've been trying meself, but somehow I'm limited to planes, spheres and cylinders.
Cubes just don't work :(
Probably something in the calling code before the shader.

It's on my todo list but first concentrate on destruction entry


Offline Xetick

  • Atari ST
  • ***
  • Posts: 132
  • Karma: 80
    • View Profile
    • Plane9
Re: Raymarching Beginners' Thread
« Reply #3 on: March 09, 2011 »
The pouet thread(s) are a wealth of information when it comes to raymarching.

For the ones that want to see some example of what can be done with raymarching


The following two are essentially a bunch of sin/cos values and thats the fun part with it. The work/reward ration is really good with raymarching. Once you have something working it requires very little work to make interesting scenes.



This isn't realtime though, 1fps I heard. But has global illumination. I really like the design and how this is synced to the music.
[youtube]http://www.youtube.com/watch?v=BtEQ2cz-NfM[/youtube]

Haven't looked into it that much but it's certainly on my list of things to do
Plane9 - Home of the Plane9 3d screensaver/music visualizer
Challenge Trophies Won:

Offline combatking0

  • JavaScript lives!
  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4569
  • Karma: 235
  • Retroman!
    • View Profile
    • Combat King's Barcode Battler Home
Re: Raymarching Beginners' Thread
« Reply #4 on: March 09, 2011 »
I've always wanted to try 3D rendering software, but found the big contenders (including "Maya") to be too processor intensive and fiddly to use.

I think I'll give RenderMonkey a try.

Does the term raymarching refer to a lighting effect or a distortion effect?
You are our 9001st visitor.
Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #5 on: March 09, 2011 »
@combatking0: the basic concept is constructing a ray from your camera position into your scene, from that point you will be "marching" in steps until you hit a surface and then you can extract information from this surface like colors etc.

Btw, I've managed to add shadows and ambient occlusion, this code was kinda provided by las/mercury on here, I'll post an image and perhaps an .exe tomorrow :)

Code: [Select]
//negative d -> sss, positive d -> ao
float ao(vec3 p, vec3 n, float d, float i) {
float o,s=sign(d);
for (o=s*.5+.5;i>0.;i--) {
o-=(i*d-f(p+n*i*d*s))/exp2(i);
}
return o;
}

// p pos, l direction to light - normalized, d stepwidth, i number of steps
float shadow(vec3 p, vec3 l, float d, float i) {
float o;
for (o = 0.; i > 0.; i--) {
o += f(p+l*i*d);
}
return clamp(o, 0.0, 1.0);
}
« Last Edit: March 09, 2011 by rbz »
Challenge Trophies Won:

Offline Kirl

  • Senior Member
  • Pentium
  • ********
  • Posts: 1217
  • Karma: 230
    • View Profile
    • Homepage
Re: Raymarching Beginners' Thread
« Reply #6 on: March 10, 2011 »
Great stuff rbz, hope to get started as well someday, love the movie you posted!

CK, have a look at Cinema4d by Maxon. It's one of the more user friendly, fully featured 3d software packages around. I'm somewhat of an expert on it, so you can shoot me mail whenever you get stuck.
www.kirl.nl
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Raymarching Beginners' Thread
« Reply #7 on: March 10, 2011 »
K+ for rounding up this info, This is exactly what I've been needing for my voxel engine. I was planning on going down the Sparse Octree Voxel Traversal meathod but I really hated the idea of stepping forward finding a voxel that was full and backing up only to step forward by half the original step size. With this meathod the ray is constantly moving forward. You never have to take a step backwards and you still have a step size that will accellerate vast empty expanses spending more time in densely populated areas.

At the moment I am testing my voxel engine at a resolution of 640x480 in an environment of 256x256x256 so long as most of the visible voxels are close by I can even push the resolution up to 1024x768 with no obvious slow down, but once you enter into an open area its far too slow to even think of any resolution higher than 640x480.

Thanks for gathering all of this info into one post.

Edit - Hehehe It worked like a dream worth some extra karma to rbz
 Resolution=1024x768
 Environment=128x128x128
 Framerate is acceptable
« Last Edit: March 10, 2011 by rain_storm »

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #8 on: March 10, 2011 »
Well done Rain_storm, it works pretty well here on 1280x1024 res and I believe it's software rendered?

Here's an image with shadows added.
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Raymarching Beginners' Thread
« Reply #9 on: March 10, 2011 »
Yup thats all software rendered. The best thing is:
rgba == 0, distance != 0 (empty voxels)
rgba != 0, distance == 0 (filled voxels)
looks like a marriage made in heaven

I've been playing around with the cube distance function from your first post. Its starting to look like a morphed square but still aint got anything 3D yet. Will keep at this.

Do you think it would be possible to model a SuperShape as a distance function? That would be awesome.

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #10 on: March 10, 2011 »
Quote
Do you think it would be possible to model a SuperShape as a distance function? That would be awesome.
I also don't know, need try more of those math formulas.

But I think you can do some nice things with just sin and cos while distorting basic shapes like a sphere.
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Raymarching Beginners' Thread
« Reply #11 on: March 11, 2011 »
Okay I got the cube distance function to work, quite slow but its working nonetheless, My GFX card (is card the right word when its the internal built into the motherboard variety) is ancient technology, without the benefit of shaders, so this is all done in software.

Next I'll be moving on to GetNormal...
Code: [Select]
float3 GetNormal(float3 p)
{
   float eps = 0.1f;
   return
      normalize(
         float3(
            distance(p + float3(eps, 0, 0)) - distance(p - float3(eps, 0, 0)),
            distance(p + float3(0, eps, 0)) - distance(p - float3(0, eps, 0)),
            distance(p + float3(0, 0, eps)) - distance(p - float3(0, 0, eps))));
}

This is awesome stuff, I'm like a child on Christmas morning here.


Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #12 on: March 11, 2011 »
Nice work!

Here's a "domain repetition", a trick with "mod(p,1.0)" (glsl) or "fmod(p,1.0)" (hlsl), thanks iq/rgba for that :), added "ao + noise" which was provided by las/mercury once again :).

Code: [Select]
float perlin(vec3 p) {
vec3 i = floor(p);
vec4 a = dot(i, vec3(1., 57., 21.)) + vec4(0., 57., 21., 78.);
vec3 f = cos((p-i)*acos(-1.))*(-.5)+.5;
a = mix(sin(cos(a)*a),sin(cos(1.+a)*(1.+a)), f.x);
a.xy = mix(a.xz, a.yw, f.y);
return mix(a.x, a.y, f.z);
}
Challenge Trophies Won:

Offline combatking0

  • JavaScript lives!
  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4569
  • Karma: 235
  • Retroman!
    • View Profile
    • Combat King's Barcode Battler Home
Re: Raymarching Beginners' Thread
« Reply #13 on: March 11, 2011 »
Thanks Kirl and Rbz. K+'s there for explaining how it works and for suggesting some 3D software for beginners. I'll have a look at it.
You are our 9001st visitor.
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Raymarching Beginners' Thread
« Reply #14 on: March 11, 2011 »
How do you take the intersection / union of two objects?
Here I am trying to break out of the ray traversal loop if
the ray is intersecting the cube but outside the sphere. This should give the intersection (a cube with a sphere cut out of its center) but instead Im getting the union (a sphere and cube overlapping)

Code: [Select]
    real d1 = cube(ray, 8.0);
    real d2 = sphere(ray, 10.0);
    if ((d1 < 0.0) && (d2 > 0.0)) {
        break;
    }
    real d = min(d1, d2);

Edit : I figured it out it was the distance that I was taking for the step sometimes it was less than the minimum step size and it ended up breaking out of the loop because of that

« Last Edit: March 11, 2011 by rain_storm »

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #15 on: March 11, 2011 »
Try it using "max" instead and negating d1 or d2:, you should get same results without "if" statement:
max(d1, d2);
max(-d1, d2);
max(d1, -d2);
Challenge Trophies Won:

Offline rain_storm

  • Here comes the Rain
  • DBF Aficionado
  • ******
  • Posts: 3088
  • Karma: 182
  • Rain never hurt nobody
    • View Profile
    • org_100h
Re: Raymarching Beginners' Thread
« Reply #16 on: March 11, 2011 »
Thanks rbz thats much more efficient and cleaner, but now I have another problem with the capsule function. It uses lerp and step.
Code: [Select]
float capsule(float3 p, float r, float c) {
   return lerp(length(p.xz)-r, length(float3(p.x,abs(p.y)-c,p.z))-r, step(c,abs(p.y)));
}

I figured out that lerp is just a linear interpolation, o it should be the exact same as taking the average, is this correct?
Code: [Select]
lerpx = (ax+bx)/2
lerpy = (ay+by)/2
lerpz = (az+bz)/2

But what is the step function? Does anyone know how I translate that into c?
Code: [Select]
step(c,abs(p.y))

Challenge Trophies Won:

Offline Rbz

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 2756
  • Karma: 493
    • View Profile
    • https://www.rbraz.com/
Re: Raymarching Beginners' Thread
« Reply #17 on: March 11, 2011 »
"lerp(a,b,s)" (hlsl) or "mix(a,b,s)" (glsl) linearly interpolate between a and b.
Code: [Select]
return a+s*(b-a);
And step(a,x) returns (x >=a ) ? 1 : 0
Code: [Select]
if(x>=a) return 1;
else return 0;


« Last Edit: March 11, 2011 by rbz »
Challenge Trophies Won:

Offline Xetick

  • Atari ST
  • ***
  • Posts: 132
  • Karma: 80
    • View Profile
    • Plane9
Re: Raymarching Beginners' Thread
« Reply #18 on: March 12, 2011 »
I think I'll give RenderMonkey a try.

Depending on what you want to do. Plane9 might be worth looking at for experimentation projects.

The good
  • It comes with few demo scene intros (Raymarching and otherwise) to get you going very quickly
  • Shader editor works in realtime. That is, you dont have to press a key to compile
  • Contains a few very good helper functions ready to use
  • Shader has a expression that can be used to precalc frame values
  • It has access to objects. Check the Android scene for example. large optimization by splitting up the shader to two objects. One background. One foreground.
  • When your done you can use your scene as a sound responsive screensaver or a music visualizer in winamp/wmp
  • Most unneeded things are removed. You have your vertex and pixel shader. No need to define texture sampler formats and all that. It's handled for you

The bad
  • Shader errors are only shown in the log file
  • Uses CG so very similary to HSLS. If you use GLSL a bit of conversion is needed mainly vec4->float4 kind of things
  • The intelisence doesn't work that well
  • No way to debug/single step a shader
  • Since the shader is compiled in realtime if you do a infinite loop you will lockup your graphics card. Nvidia handles this well. Not sure what happens on a ATI card.

I haven't tried render monkey though so I'm not sure of its advantages
Plane9 - Home of the Plane9 3d screensaver/music visualizer
Challenge Trophies Won:

Offline benny!

  • Senior Member
  • DBF Aficionado
  • ********
  • Posts: 4384
  • Karma: 228
  • in this place forever!
    • View Profile
    • bennyschuetz.com - mycroBlog
Re: Raymarching Beginners' Thread
« Reply #19 on: March 26, 2011 »
Awesome thread. Needs to have a deeper look at in soon!
[ mycroBLOG - POUET :: whatever keeps us longing - for another breath of air - is getting rare ]

Challenge Trophies Won: