// Original created by inigo quilez - 2015 https://www.shadertoy.com/view/ld3Gz2 // // Created by Sam Gondelman on 7/6/2016 // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #define AA 1 float sdSphere( in vec3 p, in vec4 s ) { return length(p-s.xyz) - s.w; } float sdEllipsoid( in vec3 p, in vec3 c, in vec3 r ) { return (length( (p-c)/r ) - 1.0) * min(min(r.x,r.y),r.z); } float sdEllipsoid( in vec2 p, in vec2 c, in vec2 r ) { return (length( (p-c)/r ) - 1.0) * min(r.x,r.y); } float sdTorus( vec3 p, vec2 t ) { return length( vec2(length(p.xz)-t.x,p.y) )-t.y; } vec2 udSegment( vec3 p, vec3 a, vec3 b ) { vec3 pa = p-a, ba = b-a; float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 ); return vec2( length( pa - ba*h ), h ); } // http://research.microsoft.com/en-us/um/people/hoppe/ravg.pdf float det( vec2 a, vec2 b ) { return a.x*b.y-b.x*a.y; } vec3 getClosest( vec2 b0, vec2 b1, vec2 b2 ) { float a = det(b0,b2); float b = 2.0*det(b1,b0); float d = 2.0*det(b2,b1); float f = b*d - a*a; vec2 d21 = b2-b1; vec2 d10 = b1-b0; vec2 d20 = b2-b0; vec2 gf = 2.0*(b*d21+d*d10+a*d20); gf = vec2(gf.y,-gf.x); vec2 pp = -f*gf/dot(gf,gf); vec2 d0p = b0-pp; float ap = det(d0p,d20); float bp = 2.0*det(d10,d0p); float t = clamp( (ap+bp)/(2.0*a+b+d), 0.0 ,1.0 ); return vec3( mix(mix(b0,b1,t), mix(b1,b2,t),t), t ); } vec4 sdBezier( vec3 a, vec3 b, vec3 c, vec3 p ) { vec3 w = normalize( cross( c-b, a-b ) ); vec3 u = normalize( c-b ); vec3 v = normalize( cross( w, u ) ); vec2 a2 = vec2( dot(a-b,u), dot(a-b,v) ); vec2 b2 = vec2( 0.0 ); vec2 c2 = vec2( dot(c-b,u), dot(c-b,v) ); vec3 p3 = vec3( dot(p-b,u), dot(p-b,v), dot(p-b,w) ); vec3 cp = getClosest( a2-p3.xy, b2-p3.xy, c2-p3.xy ); return vec4( sqrt(dot(cp.xy,cp.xy)+p3.z*p3.z), cp.z, length(cp.xy), p3.z ); } float smin( float a, float b, float k ) { float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); return mix( b, a, h ) - k*h*(1.0-h); } vec2 smin( vec2 a, vec2 b, float k ) { float h = clamp( 0.5 + 0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec2( mix( b.x, a.x, h ) - k*h*(1.0-h), mix( b.y, a.y, h ) ); } vec4 smin( vec4 a, vec4 b, float k ) { float h = clamp( 0.5 + 0.5*(b.x-a.x)/k, 0.0, 1.0 ); return vec4( mix( b.x, a.x, h ) - k*h*(1.0-h), mix( b.yzw, a.yzw, h ) ); } float smax( float a, float b, float k ) { float h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); return mix( a, b, h ) + k*h*(1.0-h); } vec3 smax( vec3 a, vec3 b, float k ) { vec3 h = clamp( 0.5 + 0.5*(b-a)/k, 0.0, 1.0 ); return mix( a, b, h ) + k*h*(1.0-h); } //--------------------------------------------------------------------------- float hash1( float n ) { return fract(sin(n)*43758.5453123); } vec3 hash3( float n ) { return fract(sin(n+vec3(0.0,13.1,31.3))*158.5453123); } vec3 forwardSF( float i, float n) { const float PI = 3.141592653589793238; const float PHI = 1.618033988749894848; float phi = 2.0*PI*fract(i/PHI); float zi = 1.0 - (2.0*i+1.0)/n; float sinTheta = sqrt( 1.0 - zi*zi); return vec3( cos(phi)*sinTheta, sin(phi)*sinTheta, zi); } //--------------------------------------------------------------------------- const float pi = 3.1415927; float mapShell( in vec3 p, out vec4 matInfo ) { const float sc = 1.0/1.0; p -= vec3(0.05,0.12,-0.09); p *= sc; vec3 q = mat3(-0.6333234236, -0.7332753384, 0.2474039592, 0.7738444477, -0.6034162289, 0.1924931824, 0.0081370606, 0.3133626215, 0.9495986813) * p; const float b = 0.1759; float r = length( q.xy ); float t = atan( q.y, q.x ); // https://swiftcoder.wordpress.com/2010/06/21/logarithmic-spiral-distance-field/ float n = (log(r)/b - t)/(2.0*pi); const float th = 0.11; float nm = (log(th)/b-t)/(2.0*pi); n = min(n,nm); float ni = floor( n ); float r1 = exp( b * (t + 2.0*pi*ni)); float r2 = r1 * 3.019863; //------- float h1 = q.z + 1.5*r1 - 0.5; float d1 = sqrt( (r1-r)*(r1-r) + h1*h1) - r1; float h2 = q.z + 1.5*r2 - 0.5; float d2 = sqrt( (r2-r)*(r2-r) + h2*h2) - r2; float d, dx, dy; if( d1maxdist ) break; t += h.x*0.9; } return res; } vec3 render( in vec3 ro, in vec3 rd ) { //----------------------------- vec3 col = vec3(0); //----------------------------- float mindist = 0.0001; float maxdist = 20.0; vec4 matInfo; vec2 tm = intersectOpaque( ro, rd, mindist, maxdist, matInfo ); if( tm.y>-0.5 && tm.x < maxdist ) { col = shadeOpaque( ro, rd, tm.x, tm.y, matInfo ); maxdist = tm.x; } else { discard; } //----------------------------- return pow( col, vec3(0.45) ); } vec3 getProceduralColor() { vec3 worldEye = getEyeWorldPos(); // this will make it movable, scalable, and rotatable vec3 ro = _position.xyz; vec3 eye = (inverse(iWorldOrientation) * (worldEye - iWorldPosition)) / iWorldScale; // vec3 ro = iWorldOrientation * (_position.xyz * iWorldScale) + iWorldPosition; // world position of the current fragment // vec3 eye = worldEye; ro.x *= 1.8462; ro.y *= 3.0963; ro.z *= 0.8196; ro.x += -0.3344; ro.y += -0.0044; ro.z += -0.0337; eye.x *= 1.8462; eye.y *= 3.0963; eye.z *= 0.8196; eye.x += -0.3344; eye.y += -0.0044; eye.z += -0.0337; vec3 rd = normalize(ro - eye); // ray from camera eye to ro return render(eye, rd); } float getProceduralColors(inout vec3 diffuse, inout vec3 specular, inout float shininess) { vec3 color = getProceduralColor(); diffuse = color.rgb; specular = color.rgb; shininess = 0.5; return 1.0; }