vec2 tapCoord(int sampleNumber, in float spinAngle, const int samples, in float rot) {    //from chocapic13
    float alpha =  (float(sampleNumber + spinAngle/6.28) / samples);
    float angle = alpha * (rot * 6.28) + spinAngle;
    float ssR = alpha;
    float sin_v, cos_v;
	sin_v = sin(angle);
	cos_v = cos(angle);
	
    return vec2(cos_v, sin_v)*ssR;
}
/*
#ifdef setGI
vec3 getGI(in vec3 wPos, in vec3 wPosR, in float distortion, const int samples, const float radius, in float fade, in float shade, in float cdepth) {
    vec3 nrm     = mat3(shadowModelView) * mat3(gbufferModelViewInverse) * scene.normal;
    float dither = ditherDynamic*2.0*pi;
    vec3 result  = vec3(0.0);

    if (fade > 0.01) {
        for (int i = 0; i<samples; i++) {
        vec2 offset     = tapCoord(i, dither, samples, 2.0)*(1.0/distortion)*0.1;
        vec2 sampleCoord = wPos.xy + offset*0.07121;

        vec4 shadowSample   = texelFetch2D(shadowcolor1, ivec2(sampleCoord*shadowMapResolution), 0);
        vec3 albedo         = toLinear(shadowSample.rgb);
        float shadowDepth   = shadowSample.a*16.0;
        float cDepth        = -wPosR.z;

        vec3 p1     = vec3(sampleCoord, shadowDepth);
        vec4 shadowPos = shadowProjectionInverse * ((vec4(p1, 1.0)*2.0-1.0) * vec4(1.0, 1.0, 3.0, 1.0));
        vec3 p2     = (shadowPos.xyz*0.5+0.5)-(wPos.xyz*2.0-1.0);

        float nDotS     = saturate(dot(nrm, normalize(p2)))*0.8+0.2;
            nDotS       = mat.foliage>0.6 ? 1.0 : nDotS;
        //float isShaded  = shade;
            //isShaded    = 1.0-saturate(isShaded);
        float nDotSscale = linStep(scene.lightmap.y, 0.2, 0.85)*0.4+0.6;
            //nDotS       = mix(nDotS, 1.0*nDotSscale, isShaded*0);
        float dist      = max(length(p2), 3.0);
        //float falloff   = saturate(1.0 - pow4(dist/radius));
        const float shadowFalloff = 12.0*0.2;
        float shadowTest = 1.0-(clamp(cDepth-shadowDepth*256.0, 0.0, shadowFalloff)/shadowFalloff);
            shadowTest  = max(shadowTest, 0);
        float falloffExp = mix(12.0, 6.0, linStep(scene.lightmap.y, 0.02, 0.12));
            falloffExp  = mix(falloffExp, 1.0, linStep(scene.lightmap.y, 0.12, 0.8));
            shadowTest  = pow(shadowTest, falloffExp);
        float falloff   = linStep(cDepth-shadowDepth, 0.5, 10.0);

        float weight    = float(i)/samples + dither/samples;

        vec3 bounceColor = albedo*0.7+normalize(albedo)*0.3;

        result     += nDotS*colorSat(bounceColor, 0.8)*weight*fade*saturate(shadowTest);
        //result = vec3(shadowTest)*10.0;
        }
    }
    return max(result*0.66, 0.0);
}
*/
/*
vec3 getGI(in vec3 wPos, in vec3 wPosR, in float distortion, const int samples, const float radius, in float fade, in float shade, in float cdepth) {
    vec4 worldp     = gbufferModelViewInverse*pos.screen;
        worldp      = shadowModelView * worldp;
    vec3 worldp2    = worldp.xyz;
        worldp      = shadowProjection*worldp;
        warpShadowmap(worldp.xy);
        worldp     /= worldp.w;
        worldp      = worldp*0.5+0.5;
    
    vec3 nrm     = mat3(shadowModelView) * mat3(gbufferModelViewInverse) * scene.normal;
    vec3 result  = vec3(0.0);

    float dither = ditherDynamic*2.0*pi;

    if (fade > 0.01) {
        for (int i = 0; i<samples; i++) {

        vec2 offset     = tapCoord(i, dither, samples, 2.0)*(1.0/distortion);

        vec2 sampleCoord = worldp.xy + offset*0.7121;

        vec4 shadowSample   = texelFetch2D(shadowcolor1, ivec2(sampleCoord*shadowMapResolution), 0);
        float shadowDepth   = shadowSample.a*16.0;

        vec3 albedo         = toLinear(shadowSample.rgb);

        float cDepth        = -wPosR.z;

        vec3 p1     = vec3(sampleCoord, shadowDepth);
        vec4 shadowPos = shadowProjectionInverse * ((vec4(p1, 1.0)*2.0-1.0) * vec4(1.0, 1.0, 3.0, 1.0));
        vec3 p2     = shadowPos.xyz-worldp2;

        float nDotS     = saturate(dot(nrm, normalize(p2)))*0.8+0.2;
            //nDotS       = mat.foliage>0.6 ? 1.0 : nDotS;
        //float isShaded  = shade;
            //isShaded    = 1.0-saturate(isShaded);
        float nDotSscale = linStep(scene.lightmap.y, 0.2, 0.85)*0.4+0.6;
            //nDotS       = mix(nDotS, 1.0*nDotSscale, isShaded*0);
        float dist      = max(length(p2), 3.0);

        //float falloff   = saturate(1.0 - pow4(dist/radius));

        //float scoef     = falloff*falloff/pow2(dist);

        const float shadowFalloff = 12.0*0.2;

        float shadowTest = 1.0-(clamp(cDepth-shadowDepth*256.0, 0.0, shadowFalloff)/shadowFalloff);
            shadowTest  = max(shadowTest, 0);
        float falloffExp = mix(12.0, 6.0, linStep(scene.lightmap.y, 0.02, 0.12));
            falloffExp  = mix(falloffExp, 1.0, linStep(scene.lightmap.y, 0.12, 0.8));
            shadowTest  = pow(shadowTest, falloffExp);
        float falloff   = linStep(cDepth-shadowDepth, 0.5, 10.0);

        float weight    = float(i)/samples + dither/samples;

        vec3 bounceColor = albedo*0.7+normalize(albedo)*0.3;

        result     += nDotS*colorSat(bounceColor, 0.8)*weight*fade*saturate(shadowTest);
        }
    }
    return max(result, 0.0);
}*/
/*
const float PI 		= acos(-1.0);
const float TAU 	= PI * 2.0;
const float PHI		= sqrt(5.0) * 0.5 + 0.5;

const float goldenAngle = TAU / PHI / PHI;

vec2 sincos(float x){
    return vec2(sin(x), cos(x));
}
vec2 circlemap(float i, float n){
	return sincos(i * n * goldenAngle) * sqrt(i);
}

vec3 getGlobalIllumination(vec3 spos, in float cdepth) {
    vec3 snormal    = mat3(shadowModelView) * mat3(gbufferModelViewInverse) * scene.normal;
    float lightmap  = scene.lightmap.y;

    const int steps = 6;
    const float invStep = 1.0/steps;

    const float radius = 50.0;
    const float invRadius = 1.0/radius;

    const float pixelOffset = radius * (1.0/2048.0);

    vec3 result     = vec3(0.0);
    float totalWeight    = 0.0;

    float dither    = ditherDynamic;

    snormal *= vec3(1.0, 1.0, -1.0);

    for (int i = 0; i<steps; ++i) {
        vec2 coordOffset    = circlemap((float(i) + dither)*invStep, 4096.0*float(steps))*pixelOffset;
        float weight    = 1.0;

        vec2 offsetCoord    = spos.xy + coordOffset;
        vec2 warpedCoord    = offsetCoord;
        warpShadowmap(offsetCoord);
        //warpedCoord         = warpedCoord*0.5+0.5;

        float shadow        = texture2D(shadowtex1, warpedCoord).x - 0.00005;

        vec3 samplePosition = vec3(offsetCoord, shadow*8.0-4.0)-spos;
        float normFactor    = dot(samplePosition, samplePosition);
        vec3 sampleVector   = samplePosition * inversesqrt(normFactor);
        float SoN   = saturate(dot(sampleVector, snormal));
            SoN     = mat.foliage > 0.5 ? 1.0 : SoN;

        if (SoN <= 0.0) continue;

        vec3 normal = texture2D(shadowcolor1, warpedCoord).rgb*2.0-1.0;
            normal.xy = -normal.xy;

        float LoN = saturate(dot(sampleVector, normal));
        float falloff = 1.0 / (normFactor*invRadius*16384.0 + invRadius*16.0);

        SoN = sqrt(SoN);

        if (LoN <= 0.0) continue;

        vec4 albedo = texture2D(shadowcolor0, warpedCoord);

        float skyLightMapShadow = albedo.a*2.0-1.0;
        float bleedingMask  = skyLightMapShadow - lightmap;
            bleedingMask    = pow6(bleedingMask);
            bleedingMask    = saturate(0.005/max(bleedingMask, 0.005));

        const float shadowFalloff = 8.0;
        float shadowTest = 1.0-(clamp(cdepth-shadow*256.0, 0.0, shadowFalloff)/shadowFalloff);
            shadowTest  = max(shadowTest, 0);
        float falloffExp = mix(12.0, 6.0, linStep(scene.lightmap.y, 0.02, 0.12));
            falloffExp  = mix(falloffExp, 1.0, linStep(scene.lightmap.y, 0.12, 0.8));
            shadowTest  = pow(shadowTest*(linStep(1.0-scene.lightmap.y, 0.12, 0.6)*0.9+0.1), falloffExp);

        result += albedo.rgb * LoN * SoN;
    }

    result = result * invStep * (1.0/PI);

    return mix(result, vec3(getLuma(result)), 0.0);
}
#endif
*/