vec3 getNormal( vec3 pos ) { vec2 v = vec2( .01 , 0 ); return normalize( vec3( map( pos + v.xyy ).x - map( pos - v.xyy ).x , map( pos + v.yxy ).x - map( pos - v.xyx ).x , map( pos + v.yyx ).x - map( pos - v.yyx ).x ) ); } // ----------------------------------------------------------------------------- vec3 march( vec3 o , vec3 d , int steps , float factor ) { int i = 0; float dist = .01 , mat = -1; for ( ; i < steps ; ++ i ) { vec2 res = map( o + d * dist ); if ( abs( res.x ) < u_Render.z || dist > u_Render.w ) { break; } dist += res.x * factor; mat = res.y; } return vec3( dist , dist >= u_Render.w ? -1 : mat , i ); } // ----------------------------------------------------------------------------- /* float computeIsolines( in float value , in float dist ) { float f0 = u_DebugPlaneLines.w , f1 = f0 * f0 , f2 = f1 * f0; vec3 iso = vec3( fract( value * f0 ) * 2 - 1 , fract( value * f1 ) * 2 - 1 , fract( value * f2 ) * 2 - 1 ); iso = pow( abs( iso ) , 100 / vec3( f0 , f1 , f2 ) ) * pow( 1 - dist * .02 , 8 ); return mix( mix( iso.z , iso.y , step( 1 / f1 , value ) ) , iso.x , step( 1 / f0 , value ) ); } */ // ----------------------------------------------------------------------------- void main( ) { setCamFromUniforms( ); vec2 uv = ( gl_FragCoord.xy / u_Resolution ) * 2 - 1; vec3 camDir = normalize( lookAt - camPos ); vec3 side = normalize( cross( camUp , camDir ) ); vec3 up = normalize( cross( camDir , side ) ); vec3 rayDir = normalize( camDir * nearPlane + uv.x * side * u_Resolution.x / u_Resolution.y + uv.y * up ); vec3 r = march( camPos , rayDir , int( u_Render.x ) , u_Render.y ); vec3 hitPos = camPos + rayDir * r.x; vec3 bc; if ( r.y >= 0. ) { bc = vec3( 1. , 1. , 0. ); vec3 hvec = normalize( rayDir - u_LightDir ) , norm = getNormal( hitPos ); float ndotl = dot( norm , -normalize( u_LightDir ) ) , ndoth = dot( norm , hvec ); float si = pow( clamp( ndoth , 0 , 1 ) , 4 ) , di = .6 + .3 * clamp( ndotl , 0 , 1 ); bc = mix( bc * di , vec3( 1. ) , si ); } else { bc = vec3( 0. ); } color = vec4( bc , 1 ); /* if ( r.y == -2 ) { // Debug plane float v = map( hitPos ).x; vec3 pc = mix( mix( mix( vec3( .4 , .05 , .4 ) , vec3( .6 , .2 , .2 ) , smoothstep( 0 , 1 , v ) ) , vec3( 1 , .8 , .4 ) , smoothstep( 1 , 2 , v ) ) , vec3( 1 ) , smoothstep( 2 , 3 , v ) ); color = vec4( mix( pc , u_DebugPlaneLines.rgb , computeIsolines( v , r.x ) ) , 1 ); } else if ( r.y == -1 ) { color = vec4( 0 , 0 , 0 , 1 ); } else { // Base color vec3 bc; if ( dispMode == 1 ) { // Single color mode bc = u_ObjColor; } else if ( dispMode == 2 ) { // Iterations bc = mix( u_ObjColor , u_ObjColor2 , r.z / u_Render.x ); } else { // Distance bc = mix( u_ObjColor , u_ObjColor2 , r.x / u_Render.w ); } // Grid if ( ( u_DebugFeatures.x & 0x04 ) != 0 ) { vec3 hpf = fract( hitPos / u_DebugGrid.x ) * 2 - 1; hpf = 1 - smoothstep( vec3( 1 - .01 / u_DebugGrid.x ) , vec3( 1 ) , abs( hpf ) ); bc = mix( u_DebugGrid.yzw , bc , hpf.x * hpf.y * hpf.z ); } if ( ( u_DebugFeatures & 0x20 ) != 0 ) { vec3 hvec = normalize( rayDir - u_LightDir ) , norm = getNormal( hitPos ); float ndotl = dot( norm , -normalize( u_LightDir ) ) , ndoth = dot( norm , hvec ); float si = pow( clamp( ndoth , 0 , 1 ) , 4 ) , di = .6 + .3 * clamp( ndotl , 0 , 1 ); bc = mix( bc * di , vec3( u_ObjColor ) , si ); } color = vec4( bc , 1 ); } */ // Translucent isolines /* if ( ( u_DebugFeatures.x & 3 ) == 2 ) { float pint = dot( rayDir , u_DebugPlane.xyz ); if ( abs( pint ) > .0001 ) { float pdist = u_DebugPlane.w - .5 * u_DebugPlaneTrans.x * u_DebugPlaneTrans.y; float cpdotpn = dot( camPos , u_DebugPlane.xyz ); int nbp = int( u_DebugPlaneTrans.x ); for ( int i = 0 ; i < nbp ; i ++ ) { float t = ( pdist - cpdotpn ) / pint; if ( t > .0001 && ( t < r.x || r.y == -1. ) ) { float v = map( camPos + t * rayDir ).x; bool inside = v <= 0; vec3 col = inside ? ( vec3(1) - u_DebugPlaneLines.rgb ) : u_DebugPlaneLines.rgb; color.rgb += mix( vec3( .05 ) , col * u_DebugPlaneTrans.w , computeIsolines( v , t ) ) * ( 1 - min( 1 , abs( v ) / u_DebugPlaneTrans.z ) ); } pdist += u_DebugPlaneTrans.y; } } } */ }