<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>

<glsl_hacker>
	
  <window name="win3d01" title="MadShaders - Shadertoy/sierpkinki 3d" 
          width="800" height="400"
          gl_version_major="2" gl_version_minor="1" />
          
          
<gpu_program name="shadertoy_prog" >
	<raw_data_vs><![CDATA[	 
void main()
{	
	gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
}
  ]]></raw_data_vs>
  
	<raw_data_ps><![CDATA[	 

// https://www.shadertoy.com/view/4dl3Wl
  
uniform vec3      iResolution;     // viewport resolution (in pixels)
uniform float     iGlobalTime;     // shader playback time (in seconds)
uniform vec4      iMouse;          // mouse pixel coords. xy: current (if MLB down), zw: click
//uniform sampler2D iChannel0;


// Created by inigo quilez - iq/2013
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

float length2( in vec3 p ) { return dot(p,p); }

const vec3 va = vec3(  0.0,  0.57735,  0.0 );
const vec3 vb = vec3(  0.0, -1.0,  1.15470 );
const vec3 vc = vec3(  1.0, -1.0, -0.57735 );
const vec3 vd = vec3( -1.0, -1.0, -0.57735 );

// return distance and address
vec2 map( vec3 p )
{
	float a = 0.0;
	vec3 c;
	float dist, d, t;
	for( int i=0; i<7; i++ )
	{
		d = length2(p-va);                c = va; dist=d; t=0.0;
        d = length2(p-vb); if( d<dist ) { c = vb; dist=d; t=1.0; }
        d = length2(p-vc); if( d<dist ) { c = vc; dist=d; t=2.0; }
        d = length2(p-vd); if( d<dist ) { c = vd; dist=d; t=3.0; }
		p = c + 2.0*(p - c);
		a = t + a*4.0;
	}
	
	return vec2( (length(p)-1.41)/pow(2.0, 7.0), a/pow(4.0,7.0) );
}



const float precis = 0.001;


vec3 intersect( in vec3 ro, in vec3 rd )
{
	vec3 res = vec3( 1e20, 0.0, 0.0 );
	
	// plane
	float tp = (-1.0-ro.y)/rd.y;
	if( tp>0.0 ) res = vec3(tp, 1.0, 0.0 );
	
	// sierpinski
	float maxd = min( res.x, 8.0 );
    float h = 1.0;
    float t = 0.0;
	float m = 0.0;
	for( int i=0; i<80; i++ )
    {
        if( h>precis && t<maxd )
		{			
	    vec2 h = map( ro+rd*t );
		m = h.y;
        t += h.x;
		}			
    }

    if( t<maxd && t<res.x )
		res = vec3( t, 2.0, m );


	return res;
}

vec3 calcNormal( in vec3 pos )
{
    vec3 eps = vec3(precis*10.0,0.0,0.0);
	return normalize( vec3(
           map(pos+eps.xyy).x - map(pos-eps.xyy).x,
           map(pos+eps.yxy).x - map(pos-eps.yxy).x,
           map(pos+eps.yyx).x - map(pos-eps.yyx).x ) );
}

float softshadow( in vec3 ro, in vec3 rd, float mint, float k )
{
    float res = 1.0;
    float t = mint;
    for( int i=0; i<40; i++ )
    {
        float h = map(ro + rd*t).x;
        res = min( res, k*h/t );
		t += clamp( h, 0.01, 1.0 );
    }
    return clamp(res,0.0,1.0);
}

float occlusion( in vec3 pos, in vec3 nor )
{
	float totao = 0.0;
    float sca = 1.0;
    for( int aoi=0; aoi<8; aoi++ )
    {
        float hr = 0.01 + 1.2*pow(float(aoi)/8.0,1.5);
        vec3 aopos =  nor * hr + pos;
        float dd = map( aopos ).x;
        totao += -(dd-hr)*sca;
        sca *= 0.85;
    }
    return clamp( 1.0 - 0.6*totao, 0.0, 1.0 );
}

vec3 lig = normalize(vec3(1.0,0.7,0.9));

void main( void )
{
	vec2 q = gl_FragCoord.xy / iResolution.xy;
    vec2 p = -1.0 + 2.0 * q;
    p.x *= iResolution.x/iResolution.y;
    vec2 m = vec2(0.5);
	if( iMouse.z>0.0 ) m = iMouse.xy/iResolution.xy;

    //-----------------------------------------------------
    // camera
    //-----------------------------------------------------
	
	float an = 3.2 + 0.5*iGlobalTime - 6.2831*(m.x-0.5);

	vec3 ro = vec3(2.51*sin(an),0.0,2.5*cos(an));
    vec3 ta = vec3(0.0,-0.5,0.0);
    vec3 ww = normalize( ta - ro );
    vec3 uu = normalize( cross(ww,vec3(0.0,1.0,0.0) ) );
    vec3 vv = normalize( cross(uu,ww));
	vec3 rd = normalize( p.x*uu + p.y*vv + 2.5*ww );

    //-----------------------------------------------------
	// render
    //-----------------------------------------------------

	vec3 col = vec3(0.0);

	// raymarch
    vec3 tm = intersect(ro,rd);
    if( tm.y>0.5 )
    {
        // geometry
        vec3 pos = ro + tm.x*rd;
		vec3 nor = vec3( 0.0 );
		vec3 maa = vec3( 0.0 );
		
		float occ = 1.0;
		
		if( tm.y<1.5 )
		{
		    nor = vec3( 0.0, 1.0, 0.0 );
		    maa = vec3( 0.5 );
		}
		else
		{
            nor = calcNormal( pos );
            maa = 0.5 + 0.5*cos( 6.2831*tm.z + vec3(0.0,1.0,2.0) );
			occ *= 0.5 + 0.5*clamp( (pos.y+1.0)/0.5, 0.0, 1.0 );
		}

		occ *= occlusion( pos, nor );

		// lighting
		float amb = (0.5 + 0.5*nor.y)*(1.0 - smoothstep( 10.0, 40.0, length(pos.xz) ));
		float dif = max(dot(nor,lig),0.0);
		float sha = 0.0; if( dif>0.01 ) sha=softshadow( pos+0.01*nor, lig, 0.0005, 32.0 );
        float att = 1.0 - smoothstep( 1.5, 2.5, length(pos.xz) );
		// lights
		vec3 lin = vec3(0.0);
        lin += 1.5*dif*vec3(1.00,0.90,0.70)*pow(vec3(sha*att),vec3(1.0,1.2,1.5));
		lin += 0.4*amb*vec3(0.30,0.35,0.40) * occ;

		// surface-light interacion
		col = maa * lin;
		
	}

    // gamma
	col = pow( clamp(col,0.0,1.0), vec3(0.45) );

    gl_FragColor = vec4( col, 1.0 );
}
]]></raw_data_ps>

</gpu_program>

 
	<script name="init_scene" run_mode="INIT" >
		<raw_data><![CDATA[	

app_dir = gh_utils.get_scripting_libs_dir() 		
dofile(app_dir .. "lua/Moon3D_v2.lua")

moon3d.init(2, 1)
moon3d.graphics.vsync(0)

bmfont = moon3d.font.create("trebuchet_20px.fnt", "data/")
bmfont_texture = moon3d.font.getTexture(bmfont)
moon3d.madshaders.setBmFontData(bmfont, bmfont_texture)

winW, winH = moon3d.window.getSize()

quad = moon3d.graphics.newQuad(winW, winH)
shadertoy_prog = moon3d.graphics.getGpuProgram("shadertoy_prog")

-- tex0 = moon3d.image.load2d("./data/tex16.png")

moon3d.madshaders.resetBenchmarkData()

		]]></raw_data>
	</script> 

  
	<script name="update_scene" run_mode="FRAME" >
		<raw_data><![CDATA[	

moon3d.startFrame(0, 0, 0, 1)

local global_time = moon3d.getTime()

moon3d.madshaders.updateBenchmarkData(global_time)

moon3d.camera.bindOrtho()

moon3d.graphics.bindGpuProgram(shadertoy_prog)
moon3d.madshaders.updateShadertoyCommonParams(shadertoy_prog, global_time)
--moon3d.madshaders.setShadertoyTexture(shadertoy_prog, tex0, 0)
moon3d.graphics.draw(quad)

moon3d.madshaders.displayBenchmarkInfoV2("Shadertoy/sierpkinki 3d", global_time, 1, 1, 1, 1)

moon3d.endFrame()

		]]></raw_data>
	</script> 
	

	<script name="resize_scene" run_mode="SIZE" >
		<raw_data><![CDATA[	

moon3d.window.resize()
winW, winH = moon3d.window.getSize()
moon3d.graphics.resizeQuad(quad, winW, winH)

		]]></raw_data>
	</script> 
  
</glsl_hacker>
