Created
September 1, 2010 23:45
-
-
Save jonbro/561589 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// working on this: http://code4k.blogspot.com/1009/10/potatro-and-raymarching-story-of.html | |
PImage img; | |
Sphere[] s = new Sphere[10]; | |
// move through the screen points | |
Vector3d cameraCenter; | |
float screenDistance; | |
Vector3d rayPosition, lightPos; | |
int currentSphere; | |
void setup(){ | |
size(640, 480); | |
img = createImage(width, height, RGB); | |
for(int i=0;i<10;i++){ | |
s[i] = new Sphere(new Vector3d(width/2.0, 0+i*height/10, 10.0), 30); | |
} | |
lightPos = new Vector3d(width/2.0-10, height/2.0-10, -10); | |
cameraCenter = new Vector3d(width/2, height/2, -100); | |
screenDistance = 5; | |
rayPosition = new Vector3d(cameraCenter); | |
currentSphere = 0; | |
} | |
void updateSpheres(){ | |
for(int i=0;i<10;i++){ | |
s[i].center.z = sin(millis()/100.0+i*10)*10+15; | |
s[i].center.x = sin(millis()/300.0+i*15)*10+width/2.0; | |
} | |
} | |
float minDistance(Vector3d ray){ | |
float minDist = s[0].distance(ray); | |
currentSphere = 0; | |
for(int i=0;i<10;i++){ | |
if(minDist > s[i].distance(ray)){ | |
currentSphere = i; | |
minDist = min(s[i].distance(ray), minDist); | |
} | |
} | |
return minDist; | |
} | |
void draw(){ | |
background(#505050); | |
// update the position of the sphere | |
updateSpheres(); | |
for(int h = 0;h<height;h++){ | |
for(int w = 0; w<width;w++){ | |
float d = 10; | |
float test = 64; | |
Vector3d screenPoint = new Vector3d(w, h, screenDistance); | |
rayPosition = new Vector3d(cameraCenter); | |
Vector3d ray = screenPoint.sub(cameraCenter); | |
while(d>0.005&&test>0&&rayPosition.z<200){ | |
ray.normalize(); | |
// will need to do this in a loop if there is more than one sphere | |
float sphereDistance = minDistance(rayPosition); | |
//println(sphereDistance); | |
ray.mult(sphereDistance); | |
rayPosition.add(ray); | |
d = minDistance(rayPosition); | |
test--; | |
} | |
if(d<=0.005){ | |
Vector3d n = rayPosition.sub(s[currentSphere].center); | |
Vector3d ln = lightPos.sub(s[currentSphere].center); | |
n.normalize(); | |
ln.normalize(); | |
float lightMult = n.dot(ln); | |
color front = color(#CCBB51); | |
color black = color(#000000); | |
set(w, h, lerpColor(black, front, max(lightMult, 0))); | |
} | |
} | |
if(h%height/10==0){ | |
println((float)h/(float)height*100.0); | |
} | |
} | |
} | |
// wish I didn't have to write this over and over. | |
class Vector3d{ | |
float x, y, z; | |
Vector3d(float _x, float _y, float _z){ | |
x = _x; | |
y = _y; | |
z = _z; | |
} | |
Vector3d(Vector3d _v){ | |
x = _v.x; | |
y = _v.y; | |
z = _v.z; | |
} | |
float distance(Vector3d _v){ | |
float xd = x - _v.x; | |
float yd = y - _v.y; | |
float zd = z - _v.z; | |
return sqrt(xd*xd + yd*yd + zd*zd); | |
} | |
void normalize(){ | |
Vector3d zeroVector = new Vector3d(0, 0, 0); | |
float length = distance(zeroVector); | |
x /= length; | |
y /= length; | |
z /= length; | |
} | |
void add(Vector3d _v){ | |
x+=_v.x; | |
y+=_v.y; | |
z+=_v.z; | |
} | |
Vector3d sub(Vector3d _v){ | |
return new Vector3d(x-_v.x, y-_v.y, z-_v.z); | |
} | |
void mult(float _c){ | |
x*=_c; | |
y*=_c; | |
z*=_c; | |
} | |
float dot(Vector3d _v){ | |
return x*_v.x + y*_v.y + z*_v.z; | |
} | |
} | |
class Sphere{ | |
Vector3d center; | |
float radius; | |
Sphere(Vector3d _c, float _r){ | |
center = _c; | |
radius = _r; | |
} | |
float distance(Vector3d ray){ | |
return ray.distance(center)-radius; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
added a far clip plane, make it run slightly faster.