// Credit to iq: https://www.shadertoy.com/view/XdjXWK // // 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 NUMPASES 1 //------------------------------------------------------------------------------------------- // sphere related functions //------------------------------------------------------------------------------------------- vec3 sphNormal( in vec3 pos, in vec4 sph ) { return normalize(pos-sph.xyz); } float sphIntersect( in vec3 ro, in vec3 rd, in vec4 sph ) { vec3 oc = ro - sph.xyz; float b = dot( oc, rd ); float c = dot( oc, oc ) - sph.w*sph.w; float h = b*b - c; if( h<0.0 ) return -1.0; return -b - sqrt( h ); } float sphShadow( in vec3 ro, in vec3 rd, in vec4 sph ) { vec3 oc = ro - sph.xyz; float b = dot( oc, rd ); float c = dot( oc, oc ) - sph.w*sph.w; return step( min( -b, min( c, b*b - c ) ), 0.0 ); } vec2 sphDistances( in vec3 ro, in vec3 rd, in vec4 sph ) { vec3 oc = ro - sph.xyz; float b = dot( oc, rd ); float c = dot( oc, oc ) - sph.w*sph.w; float h = b*b - c; float d = sqrt( max(0.0,sph.w*sph.w-h)) - sph.w; return vec2( d, -b-sqrt(max(h,0.0)) ); } float sphSoftShadow( in vec3 ro, in vec3 rd, in vec4 sph ) { float s = 1.0; vec2 r = sphDistances( ro, rd, sph ); if( r.y>0.0 ) s = max(r.x,0.0)/r.y; return s; } float sphOcclusion( in vec3 pos, in vec3 nor, in vec4 sph ) { vec3 r = sph.xyz - pos; float l = length(r); float d = dot(nor,r); float res = d; if( d0.0 && h-0.5 ) { vec3 pos = ro + t*rd; vec3 nor = sphNormal( pos, obj ); col = shade( rd, pos, nor, float(NUMSPHEREES-1)-id, pos-obj.xyz, t ); } else { discard; } return col; } vec3 animate( float time ) { // animate vec3 cen = vec3(0.0); for( int i=0; i0 #if NUMPASES>1 for( int k=0; k