From 62639996448f2188f82cf1e4ef4a60618a81fa4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 3 Oct 2017 09:12:21 +0200 Subject: [PATCH] "Enhanced sphere tracing" by Mercury /et al./ --- shaders/raymarcher.glsl | 45 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/shaders/raymarcher.glsl b/shaders/raymarcher.glsl index 3b0d922..d28a147 100644 --- a/shaders/raymarcher.glsl +++ b/shaders/raymarcher.glsl @@ -9,7 +9,7 @@ vec3 getNormal( vec3 pos ) // ----------------------------------------------------------------------------- -vec3 march( vec3 o , vec3 d , int steps , float factor ) +vec3 RM_Basic( vec3 o , vec3 d , int steps , float factor ) { int i = 0; float dist = .01 , mat = -1; @@ -26,6 +26,47 @@ vec3 march( vec3 o , vec3 d , int steps , float factor ) return vec3( dist , dist >= u_Render.w ? -1 : mat , i ); } +vec3 RM_Advanced( vec3 o , vec3 d , int steps , float factor ) +{ + const float dMin = .1 , dMax = u_Render.w , pixel = u_Render.z; + + int i = 0; + float dist = dMin , mat = -1; + float omega = factor; + float cError = 1 / 0. , cDist = dMin; + float pRad = 0 , sLen = 0; + + for ( ; i < steps ; ++ i ) { + vec2 res = map( o + d * dist ); + float rad = abs( res.x ); + + bool sorFail = omega > 1 && ( rad + pRad ) < sLen; + if ( sorFail ) { + sLen -= omega * sLen; + omega = 1; + } else { + sLen = res.x * omega; + } + pRad = rad; + + float error = rad / dist; + if ( !sorFail && error < cError ) { + cError = error; + cDist = dist; + } + + if ( !sorFail && error < pixel || dist > dMax ) { + break; + } + + dist += sLen; + } + if ( dist <= dMax && cError <= pixel ) { + return vec3( cDist , map( o + d * cDist ).y , i ); + } + return vec3( cDist , -1 , steps ); +} + // ----------------------------------------------------------------------------- void main( ) @@ -40,7 +81,7 @@ void main( ) + 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 r = RM_Advanced( camPos , rayDir , int( u_Render.x ) , u_Render.y ); vec3 hitPos = camPos + rayDir * r.x; vec3 bc = vec3( 0 );