Skip to content

Instantly share code, notes, and snippets.

@jonbro
Created September 1, 2010 23:45
Show Gist options
  • Save jonbro/561589 to your computer and use it in GitHub Desktop.
Save jonbro/561589 to your computer and use it in GitHub Desktop.
// 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;
}
}
@jonbro
Copy link
Author

jonbro commented Sep 2, 2010

added a far clip plane, make it run slightly faster.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment