From b175aa37621c65931fba11420f5e00246caa5cf2 Mon Sep 17 00:00:00 2001 From: tabathah Date: Tue, 28 Feb 2017 15:00:46 -0500 Subject: [PATCH] slow but working --- README.md | 71 +------ robot1.PNG | Bin 0 -> 43012 bytes robot2.PNG | Bin 0 -> 46852 bytes src/glsl/pass-vert.glsl | 5 + src/glsl/rayMarch-frag.glsl | 413 +++++++++++++++++++++++++++++++++++- src/main.js | 2 +- src/rayMarching.js | 49 +++++ 7 files changed, 469 insertions(+), 71 deletions(-) create mode 100644 robot1.PNG create mode 100644 robot2.PNG diff --git a/README.md b/README.md index 27b5336..f3f4344 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,17 @@ # HW 6: Ray marching and SDFs -## Goal -In this assignment, you will be implementing SDF operators on various primitives and use a ray marcher to render them. Ray marching is a technique for rendering implicit surfaces where the ray-primitive intersection equation cannot be solved analytically. +I used ray-marching and sine distance fields to create an animated robot. The final project can be found at https://tabathah.github.io/Project6-RayMarching-Implicit-Surfaces. Here are some pictures of the final product: -**Warning**: this assignment diverges significantly from marching cubes, so switching options midway can be costly for your time and effort. +![](./robot1.PNG) ![](./robot2.PNG) -## Base code framework +For every fragment in the scene, I cast a ray from the camera position to the fragment. I then march down this ray, evaluating how far I should I march by the closest value based on sine distance fields of the objects in my scene, until I reach a sine distance field value less than a certain epsilon value. -We have provided a preview scene, and a toggle for the ray marcher rendering. When you correctly implement the ray marcher, the image should match the preview scene containing the simple geometry. Your ray marching calculation should be performed in the fragment shader. +I implemented the following primitive shapes and operators for sine distance fields, using IQ's SDF notes (http://iquilezles.org/www/articles/distfunctions/distfunctions.htm) as a reference. -### Ray Marcher (25 pts) +I wrote SDF methods for Sphere, Box, Cone, Cylinder, and Torus. I also wrote operators, union, intersection, and subtraction, to combine them. I also wrote a function that took in a point and a matrix that included translation and rotation (scale was dealt with manually in the parameters of the SDFs), and applied the inverse of these transformations on the point to put it in world space, rather than local object space. -The ray marcher should generate a ray direction, and march through the scene using the distances computed from sphere tracing. +I also wrote a function to compute the normal of the point using the SDFs, and computed a simple Lambertian shader. -**Note**: Your scene won't be rendered until you have implemented the SDFs for primitives below. +To animate my robot, I passed time in as a uniform, and translated the neck/head, the arms, and the legs based on the time value. -- Generate Rays (15 pts): for each fragment inside the fragment shader, compute a ray direction for the ray marcher -- Sphere Tracing (10 pts): compute the nearest distance from the scene SDFs and update the ray marching's step size. - -### SDF (50 pts) -##### Implement primitive SDFs (15pts): -These are simple primitives with well-defined SDFs. We encourage trying other SDFs not listed here, they are interesting! - - Sphere (3pts) - - Box (3pts) - - Cone (3pts) - - Torus (3pts) - - Cylinder (3pts) - -##### Useful Operators (15pts) -To create constructive geometry, and interesting shapes (such as holes, bumps, etc.), implement the following operators to combine your primitive SDFs. - - Intersection (2pts) - - Subtraction (3pts) - - Union (2pts) - - Transformation (8pts) - - translation and scaling -##### Compute normals based on gradient (15 pts) - -Compute the normals to use for shading your surface. -- Read Chapter 13 of [Morgan McGuire's notes](http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf) -##### Material (5pts) -Implement a simple Lambert material. Additional materials can earn extra points. - -### Custom Scene (25 pts) -##### Create a mechanical device or a scene of your choice using all operators - - intersection, subtraction, union, transformation (20pts) -##### Animate the scene (5pts) -Use time as an input to some of your functions to animate your scene! - -## Extra credits (Up to 30 pts) -- Implement SDF for [Mandelbulb](https://www.shadertoy.com/view/XsXXWS) (10pts) - - You need to implement naive raymarching (not sphere tracing) to get this to work -- Lighting effects - - Soft shadowing using secondary rays (5pts) - - Ambient occlusion (10pts) -- Additional materials besides Lambert. (5pts each) -- Additional SDFs besides the listed primitive. (5pts each) - -## Resources -http://graphics.cs.williams.edu/courses/cs371/f14/reading/implicit.pdf - -## Submission -- Update `README.md` to contain a solid description of your project -- Publish your project to gh-pages. `npm run deploy`. It should now be visible at http://username.github.io/repo-name -- Create a [pull request](https://help.github.com/articles/creating-a-pull-request/) to this repository, and in the comment, include a link to your published project. -- Submit the link to your pull request on Canvas. - -## Deploy -- `npm run build` -- Add and commit all changes -- `npm run deploy` -- If you're having problems with assets not linking correctly, make sure you wrap you're filepaths in `require()`. This will make the bundler package and your static assets as well. So, instead of `loadTexture('./images/thing.bmp')`, do `loadTexture(require('./images/thing.bmp'))`. \ No newline at end of file +The program runs very slow right now. I created bounding volumes to optimize the SDF computing, but this didn't seem to do much. I suspect the problem is in my ray casting, as I was having trouble doing camera computations in the CPU, so I do them in the GPU. I hope to fix this in the near future. \ No newline at end of file diff --git a/robot1.PNG b/robot1.PNG new file mode 100644 index 0000000000000000000000000000000000000000..c993c1989f4063fc7413e128fb021f6c373f0ea8 GIT binary patch literal 43012 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 NpM%{&+Zr5+_CL^hfEfS) literal 0 HcmV?d00001 diff --git a/robot2.PNG b/robot2.PNG new file mode 100644 index 0000000000000000000000000000000000000000..2763313449edb4855c47553b089c8e8c65c209c6 GIT binary patch literal 46852 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%0A6NiT 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 u_count) { - break; - } +//returns direction of ray from camera to this fragment +vec3 createRay() +{ + vec3 F = normalize(vec3(cameraTransform * vec4(0.0, 0.0, -1.0, 0.0))); + vec3 R = normalize(cross(F, vec3(0.0, 1.0, 0.0))); + vec3 U = normalize(cross(R, F)); + vec3 ref = cameraPos + 0.1*F; + float len = length(ref - cameraPos); + vec3 p = ref + ((2.0*f_uv.x-1.0) * (R*len*aspRatio*tanAlpha)) + ((2.0*f_uv.y-1.0) * (U*len*tanAlpha)); + return normalize(p-cameraPos); +} + +//returns transformed point based on rotation and translation matrix of shape +vec3 transform(vec3 point, mat4 trans) +{ + //columns of the rotation matrix transpose + vec3 col1 = vec3(trans[0][0], trans[1][0], trans[2][0]); + vec3 col2 = vec3(trans[0][1], trans[1][1], trans[2][1]); + vec3 col3 = vec3(trans[0][2], trans[1][2], trans[2][2]); + + mat3 rotTranspose = mat3(col1, col2, col3); + + vec3 col4 = -1.0*rotTranspose*vec3(trans[3]); + + mat4 newTrans = mat4(vec4(col1, 0.0), vec4(col2, 0.0), vec4(col3, 0.0), vec4(col4, 1.0)); + + return vec3(newTrans * vec4(point, 1.0)); +} + +//SDFS: + +float sphereSDF(vec3 point, mat4 trans, float radius) { + vec3 p = transform(point, trans); //puts point in local object space + return length(p) - radius; +} + +//diagonal is the vector from the center of the box to the first quadrant corner +float boxSDF(vec3 point, mat4 trans, vec3 diagonal) { + vec3 p = transform(point, trans); //puts point in local object space + vec3 d = abs(p) - diagonal; + return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0)); +} + +//first value in param is radius, second value is, third value is the height +float coneSDF(vec3 point, mat4 trans, vec3 param) +{ + vec3 p = transform(point, trans); //puts point in local object space + vec2 q = vec2( length(p.xz), p.y ); + vec2 v = vec2( param.z*param.y/param.x, -param.z ); + vec2 w = v - q; + vec2 vv = vec2( dot(v,v), v.x*v.x ); + vec2 qv = vec2( dot(v,w), v.x*w.x ); + vec2 d = max(qv,0.0)*qv/vv; + return sqrt( dot(w,w) - max(d.x,d.y) ) * sign(max(q.y*v.x-q.x*v.y,w.y)); +} + +//first value in param is inner radius, second value is the thickness +float torusSDF(vec3 point, mat4 trans, vec2 param) { + vec3 p = transform(point, trans); //puts point in local object space + vec2 q = vec2(length(p.xz)-param.x,p.y); + return length(q)-param.y; +} + +//first value in param is radius, second value is the height +float cylinderSDF(vec3 point, mat4 trans, vec2 param) { + vec3 p = transform(point, trans); //puts point in local object space + vec2 d = abs(vec2(length(p.xz),p.y)) - param; + return min(max(d.x,d.y),0.0) + length(max(d,0.0)); +} + +//Operators: + +float intersection(float d1, float d2) +{ + return max(d1,d2); +} + +float subtraction( float d1, float d2 ) +{ + return max(-d1,d2); +} + +float un(float d1, float d2) +{ + return min(d1,d2); +} + +float getMod(int num1, int num2) +{ + int div = num1/num2; + return float(num1 - div*num2); +} + +//returns the new step size for the sphere marching, holds the info for the scene +float sphereTrace(vec3 point) +{ + //bounding volume for body + float bbb = boxSDF(point, mat4(1.0), vec3(2.0,2.0,1.5)); + + float fullbody; + if(bbb < .015) + { + //body cube of robot, centered at origin, scaled + float body = boxSDF(point, mat4(1.0), vec3(2.0,2.0,1.0)); + + //sphere buttons on robots chest + mat4 b1Mat = mat4(1.0); b1Mat[3][0] = -1.5; b1Mat[3][1] = 1.5; b1Mat[3][2] = 1.0; + float b1 = sphereSDF(point, b1Mat, 0.25); + + mat4 b2Mat = mat4(1.0); b2Mat[3][0] = -0.75; b2Mat[3][1] = 1.5; b2Mat[3][2] = 1.0; + float b2 = sphereSDF(point, b2Mat, 0.25); + + mat4 b3Mat = mat4(1.0); b3Mat[3][0] = -1.5; b3Mat[3][1] = 0.75; b3Mat[3][2] = 1.0; + float b3 = sphereSDF(point, b3Mat, 0.25); + + mat4 b4Mat = mat4(1.0); b4Mat[3][0] = -0.75; b4Mat[3][1] = 0.75; b4Mat[3][2] = 1.0; + float b4 = sphereSDF(point, b4Mat, 0.25); + + fullbody = un(body, un(b1, un(b2, un(b3, b4)))); + } + else + { + fullbody = bbb; + } + + + + float animHeight; //height change for animation + float mod = getMod(time, 120); + if(mod < 61.0) {animHeight = mod/60.0;} + else {animHeight = (120.0-mod)/60.0;} + + + + //bounding volume for neck + mat4 bbnMat = mat4(1.0); bbnMat[3][1] = 2.0 + animHeight; + float bbn = boxSDF(point, bbnMat, vec3(1.0,1.0,1.25)); + + float fullneck; + if(bbn < 0.015) + { + //neck cylinder, placed at top of box body, scaled so that it goes inside body box for animation purposes + mat4 neckMat = mat4(1.0); neckMat[3][1] = 2.0 + animHeight; + float neck = cylinderSDF(point, neckMat, vec2(0.5, 2.0)); + + //neck attachment torus, will be intersected with box to create interesting shape + mat4 ntMat = mat4(1.0); ntMat[3][1] = 2.0; + float nt = torusSDF(point, ntMat, vec2(0.75, 0.5)); + + //neck attachment box, will be intersected with torus to create interesting shape + mat4 nbMat = mat4(1.0); nbMat[3][1] = 2.0; + float nb = boxSDF(point, ntMat, vec3(0.8, 0.5, 0.8)); + + fullneck = un(neck, intersection(nt, nb)); + } + else + { + fullneck = bbn; + } + + + + //bounding volume for head + mat4 bbhMat = mat4(1.0); bbhMat[3][1] = 4.0 + animHeight; + float bbh = boxSDF(point, bbhMat, vec3(1.0,1.0,1.5)); + + float fullhead; + if(bbh < 0.015) + { + //head box, placed at top of neck cylinder, moves up and down in animation + mat4 headMat = mat4(1.0); headMat[3][1] = 4.0 + animHeight; + float head = boxSDF(point, headMat, vec3(1.0)); + + //outer mouth box + mat4 omMat = mat4(1.0); omMat[3][1] = 3.5 + animHeight; omMat[3][2] = 1.0; + float oMouth = boxSDF(point, omMat, vec3(0.75, 0.2, 0.5)); + + //inner mouth box, to be subtracted + mat4 imMat = mat4(1.0); imMat[3][1] = 3.5 + animHeight; imMat[3][2] = 1.2; + float iMouth = boxSDF(point, imMat, vec3(0.5, 0.1, 0.5)); + + //outer left eye + mat4 oe1Mat = mat4(1.0); oe1Mat[3][0] = -0.5; oe1Mat[3][1] = 4.5 + animHeight; oe1Mat[3][2] = 1.0; + float oe1 = sphereSDF(point, oe1Mat, 0.4); + + //inner left eye + mat4 ie1Mat = mat4(1.0); ie1Mat[3][0] = -0.5; ie1Mat[3][1] = 4.5 + animHeight; ie1Mat[3][2] = 1.25; + ie1Mat[1][1] = 0.0; ie1Mat[1][2] = 1.0; ie1Mat[2][1] = -1.0; ie1Mat[2][2] = 0.0; //rotating by 90 degrees about x axis + float ie1 = cylinderSDF(point, ie1Mat, vec2(0.2, 0.4)); + + //outer right eye + mat4 oe2Mat = mat4(1.0); oe2Mat[3][0] = 0.5; oe2Mat[3][1] = 4.5 + animHeight; oe2Mat[3][2] = 1.0; + float oe2 = sphereSDF(point, oe2Mat, 0.4); + + //inner right eye + mat4 ie2Mat = mat4(1.0); ie2Mat[3][0] = 0.5; ie2Mat[3][1] = 4.5 + animHeight; ie2Mat[3][2] = 1.25; + ie2Mat[1][1] = 0.0; ie2Mat[1][2] = 1.0; ie2Mat[2][1] = -1.0; ie2Mat[2][2] = 0.0; //rotating by 90 degrees about x axis + float ie2 = cylinderSDF(point, ie2Mat, vec2(0.2, 0.4)); + + fullhead = un(head, un(subtraction(iMouth, oMouth), un(subtraction(ie1, oe1), subtraction(ie2, oe2)))); + } + else + { + fullhead = bbh; + } + + + + //bounding volume for antenna + mat4 bbaMat = mat4(1.0); bbaMat[3][1] = 5.5 + animHeight; + float bba = boxSDF(point, bbaMat, vec3(0.2 + 0.2*animHeight,0.8 + 0.2*animHeight,0.2 + 0.2*animHeight)); + + float antenna; + if(bba < 0.015) + { + //antenna cone piece, will be intersected with box for interesting shape + mat4 acMat = mat4(1.0); acMat[3][1] = 5.5 + animHeight; + float ac = coneSDF(point, acMat, vec3(0.5, 0.5, 0.5)); + + //antenna box piece, will be intersected with cone for interesting shape + mat4 abMat = mat4(1.0); abMat[3][1] = 5.5 + animHeight; + float ab = boxSDF(point, abMat, vec3(0.15, 0.5, 0.15)); + + //antenna sphere, will animate in scale + mat4 asMat = mat4(1.0); asMat[3][1] = 5.75 + animHeight; + float as = sphereSDF(point, asMat, 0.2 + 0.2*animHeight); + + antenna = un(as, intersection(ac, ab)); + } + else + { + antenna = bba; + } + + + + //bounding volume for left arm + mat4 bba1Mat = mat4(1.0); bba1Mat[3][0] = 4.0 - 2.0*animHeight; bba1Mat[3][1] = 0.75; + float bba1 = boxSDF(point, bba1Mat, vec3(3.0, 1.0, 1.0)); + + float leftArm; + if(bba1 < 0.015) + { + //left arm cylinder, moves in and out in animation + mat4 arm1Mat = mat4(1.0); arm1Mat[3][0] = 4.0 - 2.0*animHeight; arm1Mat[3][1] = 0.75; + arm1Mat[0][0] = 0.0; arm1Mat[0][1] = 1.0; arm1Mat[1][0] = -1.0; arm1Mat[1][1] = 0.0; //rotating by 90 degrees about z axis + float arm1 = cylinderSDF(point, arm1Mat, vec2(0.5, 2.0)); + + //hand sphere + mat4 hand1Mat = mat4(1.0); hand1Mat[3][0] = 6.25 - 2.0*animHeight; hand1Mat[3][1] = 0.75; + float hand1 = sphereSDF(point, hand1Mat, 0.75); + + //inner hand box, to be subtracted in order to create claw + mat4 ihand1Mat = mat4(1.0); ihand1Mat[3][0] = 6.75 - 2.0*animHeight; ihand1Mat[3][1] = 0.75; + float ihand1 = boxSDF(point, ihand1Mat, vec3(0.5, 0.3, 1.0)); + + leftArm = un(subtraction(ihand1, hand1), arm1); } + else + { + leftArm = bba1; + } + + + + //bounding volume for left arm + mat4 bba2Mat = mat4(1.0); bba2Mat[3][0] = -2.0 - 2.0*animHeight; bba2Mat[3][1] = 0.75; + float bba2 = boxSDF(point, bba2Mat, vec3(3.0, 1.0, 1.0)); + + float rightArm; + if(bba2 < 0.015) + { + //left arm cylinder, moves in and out in animation + mat4 arm2Mat = mat4(1.0); arm2Mat[3][0] = -2.0 - 2.0*animHeight; arm2Mat[3][1] = 0.75; + arm2Mat[0][0] = 0.0; arm2Mat[0][1] = 1.0; arm2Mat[1][0] = -1.0; arm2Mat[1][1] = 0.0; //rotating by 90 degrees about z axis + float arm2 = cylinderSDF(point, arm2Mat, vec2(0.5, 2.0)); + + //hand sphere + mat4 hand2Mat = mat4(1.0); hand2Mat[3][0] = -4.25 - 2.0*animHeight; hand2Mat[3][1] = 0.75; + float hand2 = sphereSDF(point, hand2Mat, 0.75); + + //inner hand box, to be subtracted in order to create claw + mat4 ihand2Mat = mat4(1.0); ihand2Mat[3][0] = -4.75 - 2.0*animHeight; ihand2Mat[3][1] = 0.75; + float ihand2 = boxSDF(point, ihand2Mat, vec3(0.5, 0.3, 1.0)); + + rightArm = un(subtraction(ihand2, hand2), arm2); + } + else + { + rightArm = bba2; + } + + + + //bounding volume for left leg + mat4 bbl1Mat = mat4(1.0); bbl1Mat[3][0] = 1.0; bbl1Mat[3][1] = -2.0 - 2.0*animHeight; + float bbl1 = boxSDF(point, bbl1Mat, vec3(1.0, 2.0, 1.0)); + + float leftLeg; + if(bbl1 < 0.015) + { + //left leg cylinder, placed at bottom of body box, moves up and down in animation + mat4 leg1Mat = mat4(1.0); leg1Mat[3][0] = 1.0; leg1Mat[3][1] = -2.0 - 2.0*animHeight; + float leg1 = cylinderSDF(point, leg1Mat, vec2(0.5, 2.0)); + + //left leg top torus, placed a third of the way down left leg, subtracted to create indentation + mat4 ll1Mat = mat4(1.0); ll1Mat[3][0] = 1.0; ll1Mat[3][1] = -1.0 - 2.0*animHeight; + float ll1 = torusSDF(point, ll1Mat, vec2(0.75, 0.5)); + + //left leg top torus, placed a third of the way down left leg, subtracted to create indentation + mat4 ll2Mat = mat4(1.0); ll2Mat[3][0] = 1.0; ll2Mat[3][1] = -3.0 - 2.0*animHeight; + float ll2 = torusSDF(point, ll2Mat, vec2(0.75, 0.5)); + + //left foot cone, placed under leg such that point is inside the cylinder and hidden + mat4 foot1Mat = mat4(1.0); foot1Mat[3][0] = 1.0; foot1Mat[3][1] = -3.0 - 2.0*animHeight; + float foot1 = coneSDF(point, foot1Mat, vec3(1.0, 1.0, 1.0)); + + leftLeg = un(foot1, subtraction(ll1, subtraction(ll2, leg1))); + } + else + { + leftLeg = bbl1; + } + + + + //bounding volume for right leg + mat4 bbl2Mat = mat4(1.0); bbl2Mat[3][0] = -1.0; bbl2Mat[3][1] = -4.0 + 2.0*animHeight; + float bbl2 = boxSDF(point, bbl2Mat, vec3(1.0, 2.0, 1.0)); + + float rightLeg; + if(bbl2 < 0.015) + { + //right leg cylinder, placed at bottom of body box, moves up and down in animation + mat4 leg2Mat = mat4(1.0); leg2Mat[3][0] = -1.0; leg2Mat[3][1] = -4.0 + 2.0*animHeight; + float leg2 = cylinderSDF(point, leg2Mat, vec2(0.5, 2.0)); + + //left leg top torus, placed a third of the way down left leg, subtracted to create indentation + mat4 rl1Mat = mat4(1.0); rl1Mat[3][0] = -1.0; rl1Mat[3][1] = -3.0 + 2.0*animHeight; + float rl1 = torusSDF(point, rl1Mat, vec2(0.75, 0.5)); + + //left leg top torus, placed a third of the way down left leg, subtracted to create indentation + mat4 rl2Mat = mat4(1.0); rl2Mat[3][0] = -1.0; rl2Mat[3][1] = -5.0 + 2.0*animHeight; + float rl2 = torusSDF(point, rl2Mat, vec2(0.75, 0.5)); + + //right foot cone, placed under leg such that point is inside the cylinder and hidden + mat4 foot2Mat = mat4(1.0); foot2Mat[3][0] = -1.0; foot2Mat[3][1] = -5.0 + 2.0*animHeight; + float foot2 = coneSDF(point, foot2Mat, vec3(1.0, 1.0, 1.0)); + + rightLeg = un(foot2, subtraction(rl1, subtraction(rl2, leg2))); + } + else + { + rightLeg = bbl2; + } + + return un(fullbody, un(fullneck, un(fullhead, un(antenna, un(leftArm, un(rightArm, un(leftLeg, rightLeg))))))); +} + +vec3 getNormal(vec3 point) +{ + float epsilon = 0.1; + float x = sphereTrace(vec3(point.x+epsilon, point.y, point.z)) - sphereTrace(vec3(point.x-epsilon, point.y, point.z)); + float y = sphereTrace(vec3(point.x, point.y+epsilon, point.z)) - sphereTrace(vec3(point.x, point.y-epsilon, point.z)); + float z = sphereTrace(vec3(point.x, point.y, point.z+epsilon)) - sphereTrace(vec3(point.x, point.y, point.z-epsilon)); + return normalize(vec3(x, y, z)); +} + +vec3 lambert(vec3 norm) +{ + vec3 light = -1.0 * normalize(vec3(2.0, -3.0, -6.0)); + return clamp(dot(light, norm), 0.0, 1.0)*vec3(0.5, 0.5, 0.7); +} + +vec4 traceRay() +{ + vec3 ray = createRay(); + vec3 currPt = cameraPos; + float t = 0.0; + int count = 0; + for(int i = 0; i < MAX_ITER; i++) + { + currPt = cameraPos + ray * t; + float offset = sphereTrace(currPt); + + if (abs(offset) < 0.01) { + break; + } + t += offset; + ++count; + } + + //return vec4(vec3(float(count)/float(MAX_ITER)), 1.0); + return vec4(lambert(getNormal(currPt)), 1.0); +} + +void main() { + + vec4 color = traceRay(); - gl_FragColor = vec4(f_uv, 0, 1); + gl_FragColor = color; } \ No newline at end of file diff --git a/src/main.js b/src/main.js index ade21ee..2ebd674 100644 --- a/src/main.js +++ b/src/main.js @@ -44,7 +44,7 @@ window.addEventListener('load', function() { var gui = new DAT.GUI(); var options = { - strategy: 'Proxy Geometry' + strategy: 'Ray Marching' } gui.add(options, 'strategy', ['Proxy Geometry', 'Ray Marching']); diff --git a/src/rayMarching.js b/src/rayMarching.js index 03c3680..2e3d293 100644 --- a/src/rayMarching.js +++ b/src/rayMarching.js @@ -3,6 +3,10 @@ const EffectComposer = require('three-effectcomposer')(THREE) import {PROXY_BUFFER_SIZE} from './proxy_geometry' +var options = { + time: 0 +} + export default function RayMarcher(renderer, scene, camera) { var composer = new EffectComposer(renderer); var shaderPass = new EffectComposer.ShaderPass({ @@ -15,6 +19,30 @@ export default function RayMarcher(renderer, scene, camera) { type: 'i', value: 0 }, + cameraPos: { + type: '3fv', + value: camera.position + }, + cameraTransform: + { + type: 'm4', + value: camera.matrix + }, + tanAlpha: + { + type: 'f', + value: Math.tan(camera.fov/2.0 * Math.PI/180.0) + }, + aspRatio: + { + type: 'f', + value: window.innerWidth/window.innerHeight + }, + time: + { + type: 'i', + value: options.time + }, }, vertexShader: require('./glsl/pass-vert.glsl'), fragmentShader: require('./glsl/rayMarch-frag.glsl') @@ -27,7 +55,28 @@ export default function RayMarcher(renderer, scene, camera) { shaderPass.material.uniforms.u_buffer.value = buffer; shaderPass.material.uniforms.u_count.value = buffer.length / PROXY_BUFFER_SIZE; + camera.updateMatrixWorld(); + + // var tempF = new THREE.Vector4(0.0, 0.0, -1.0, 0.0); + // var temp = tempF.applyMatrix4(camera.matrix); + // var F = new THREE.Vector3(temp[0], temp[1], temp[2]); console.log(F);F.normalize(); + // var R = (F.cross(THREE.Vector3(0.0, 1.0, 0.0))).normalize(); + // var U = R.cross(F).normalize(); + // var ref = camera.position + 0.1*F; + // var len = THREE.Vector3(ref - cameraPos).length(); + // var tanAlpha = Math.tan(camera.fov/2.0 * Math.PI/180.0); + // var p = ref + ((2.0*f_uv.x-1.0) * (R*len*camera.aspect*tanAlpha)) + ((2.0*f_uv.y-1.0) * (U*len*tanAlpha)); + + shaderPass.material.uniforms.cameraTransform.value = camera.matrix; + shaderPass.material.uniforms.cameraPos.value = camera.position; + options.time++; + shaderPass.material.uniforms.time.value = options.time; + composer.render(); + }, + + update: function() { + } } } \ No newline at end of file