demotool/raymarcher.glsl

163 lines
4.4 KiB
GLSL

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 );
if ( r.y >= 1. ) {
bc += vec3( 5. , .1 , 4. ) * 4;
}
} 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;
}
}
}
*/
}