Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #version 330
- uniform vec2 resolution;
- uniform float currentTime;
- uniform vec3 camPos;
- uniform vec3 camDir;
- uniform vec3 camUp;
- uniform sampler2D tex;
- uniform bool showStepDepth;
- in vec3 pos;
- out vec3 color;
- #define PI 3.1415926535897932384626433832795
- #define RENDER_DEPTH 800
- #define CLOSE_ENOUGH 0.00001
- #define BACKGROUND -1
- #define BALL 0
- #define BASE 1
- #define GRADIENT(pt, func) vec3( \
- func(vec3(pt.x + 0.0001, pt.y, pt.z)) - func(vec3(pt.x - 0.0001, pt.y, pt.z)), \
- func(vec3(pt.x, pt.y + 0.0001, pt.z)) - func(vec3(pt.x, pt.y - 0.0001, pt.z)), \
- func(vec3(pt.x, pt.y, pt.z + 0.0001)) - func(vec3(pt.x, pt.y, pt.z - 0.0001)))
- const vec3 LIGHT_POS[] = vec3[](vec3(5, 18, 10));
- ///////////////////////////////////////////////////////////////////////////////
- vec3 getBackground(vec3 dir) {
- float u = 0.5 + atan(dir.z, -dir.x) / (2 * PI);
- float v = 0.5 - asin(dir.y) / PI;
- vec4 texColor = texture(tex, vec2(u, v));
- return texColor.rgb;
- }
- vec3 getRayDir() {
- vec3 xAxis = normalize(cross(camDir, camUp));
- return normalize(pos.x * (resolution.x / resolution.y) * xAxis + pos.y * camUp + 5 * camDir);
- }
- ///////////////////////////////////////////////////////////////////////////////
- float torusXZ(vec3 p, vec2 t) {
- vec2 q = vec2(length(p.xz) - t.x, p.y);
- return length(q) - t.y;
- }
- float torusXY(vec3 p, vec2 t) {
- vec2 q = vec2(length(p.xy) - t.x, p.z);
- return length(q) - t.y;
- }
- float torusYZ(vec3 p, vec2 t) {
- vec2 q = vec2(length(p.yz) - t.x, p.x);
- return length(q) - t.y;
- }
- float plane(vec3 p) {
- return p.y + 1;
- }
- vec3 modulusPosition(vec3 p) {
- return vec3(mod(p.x + 4, 8) - 4, p.y, mod(p.z + 4, 8) - 4);
- }
- float sceneWithoutPlane(vec3 p) {
- vec3 pos = p + vec3(0, 0, 4); // Tweak to fit output to required position
- float torusXZSdf = torusXZ(modulusPosition(pos), vec2(3, 0.5));
- float torusXYSdf = torusXY(modulusPosition(pos + vec3(4, 0, 0)), vec2(3, 0.5));
- float torusYZSdf = torusYZ(modulusPosition(pos + vec3(0, 0, 4)), vec2(3, 0.5));
- return min(min(torusXZSdf, torusXYSdf), torusYZSdf);
- }
- float wholeScene(vec3 p) {
- return min(sceneWithoutPlane(p), plane(p));
- }
- ///////////////////////////////////////////////////////////////////////////////
- vec3 getNormal(vec3 pt) {
- return normalize(GRADIENT(pt, wholeScene));
- }
- vec3 getProceduralTexture(vec3 pt) {
- float sdf = sceneWithoutPlane(vec3(pt.x, -1, pt.z));
- float modedSdf = mod(sdf, 5);
- if (modedSdf >= 4.75) return vec3(0);
- float mixWeight = mod(modedSdf, 1);
- return mix(vec3(0.4, 1, 0.4), vec3(0.4, 0.4, 1), mixWeight);
- }
- vec3 getColor(vec3 pt) {
- return pt.y <= CLOSE_ENOUGH - 1 ? getProceduralTexture(pt) : vec3(1);
- }
- ///////////////////////////////////////////////////////////////////////////////
- float shadow(vec3 pt, vec3 lightPos) {
- vec3 lightDir = normalize(lightPos - pt);
- float kd = 1;
- int step = 0;
- for (float t = 0.1;
- t < length(lightPos - pt) && step < RENDER_DEPTH && kd > 0.001; ) {
- float d = abs(wholeScene(pt + t * lightDir));
- if (d < 0.001) {
- kd = 0;
- } else {
- kd = min(kd, 16 * d / t);
- }
- t += d;
- step++;
- }
- return kd;
- }
- float shade(vec3 eye, vec3 pt, vec3 n) {
- float val = 0;
- val += 0.1; // Ambient
- for (int i = 0; i < LIGHT_POS.length(); i++) {
- float illuminationFromSource = 0;
- vec3 l = normalize(LIGHT_POS[i] - pt);
- float nDotL = dot(n, l);
- illuminationFromSource += max(nDotL, 0); // Diffuse
- if (!(nDotL < 0)) {
- vec3 r = reflect(-l, n);
- vec3 v = normalize(eye - pt);
- illuminationFromSource += max(pow(dot(r, v), 256), 0); // Specular
- }
- val += illuminationFromSource * shadow(pt, LIGHT_POS[i]);
- }
- return val;
- }
- vec3 illuminate(vec3 camPos, vec3 rayDir, vec3 pt) {
- vec3 c, n;
- n = getNormal(pt);
- c = getColor(pt);
- return shade(camPos, pt, n) * c;
- }
- ///////////////////////////////////////////////////////////////////////////////
- vec3 raymarch(vec3 camPos, vec3 rayDir) {
- int step = 0;
- float t = 0;
- for (float d = 1000; step < RENDER_DEPTH && abs(d) > CLOSE_ENOUGH; t += abs(d)) {
- d = wholeScene(camPos + t * rayDir);
- step++;
- }
- if (step == RENDER_DEPTH) {
- return getBackground(rayDir);
- } else if (showStepDepth) {
- return vec3(float(step) / RENDER_DEPTH);
- } else {
- return illuminate(camPos, rayDir, camPos + t * rayDir);
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- void main() {
- color = raymarch(camPos, getRayDir());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement