All Downloads are FREE. Search and download functionalities are using the official Maven repository.

Common.ShaderLib.Shadows.glsllib Maven / Gradle / Ivy

The newest version!
#if __VERSION__ >= 130
    // Because gpu_shader5 is actually where those
    // gather functions are declared to work on shadow maps
    // This "if" statement is useless as jme3 changes line ordering, so all extensions are tried to be loaded
    #ifdef GL_ES
        #extension GL_OES_gpu_shader5 : enable
    #else
        #extension GL_ARB_gpu_shader5 : enable
    #endif

    #define IVEC2 ivec2
    #ifdef HARDWARE_SHADOWS
        #define SHADOWMAP sampler2DShadow
        #define SHADOWCOMPAREOFFSET(tex,coord,offset) textureProjOffset(tex, coord, offset)
        #define SHADOWCOMPARE(tex,coord) textureProj(tex, coord)
        #if defined GL_ES && __VERSION__ <= 300
            #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy))
        #else
            #define SHADOWGATHER(tex,coord) textureGather(tex, coord.xy, coord.z)
        #endif
    #else
        #define SHADOWMAP sampler2D
        #define SHADOWCOMPAREOFFSET(tex,coord,offset) step(coord.z, textureProjOffset(tex, coord, offset).r)
        #define SHADOWCOMPARE(tex,coord) step(coord.z, textureProj(tex, coord).r)
        #define SHADOWGATHER(tex,coord) step(coord.z, textureGather(tex, coord.xy))
    #endif

    #if FILTER_MODE == 10
        #define GETSHADOW Shadow_Nearest
        #define KERNEL 1.0
    #elif FILTER_MODE == 1
        #ifdef HARDWARE_SHADOWS
            #define GETSHADOW Shadow_Nearest
        #else
            #define GETSHADOW Shadow_DoBilinear_2x2
        #endif
        #define KERNEL 1.0
    #endif
#else
    #define IVEC2 vec2
    #if defined GL_ES
        #define SHADOWMAP sampler2D
        #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r)
    #elif defined HARDWARE_SHADOWS
        #define SHADOWMAP sampler2DShadow
        #define SHADOWCOMPARE(tex,coord) shadow2DProj(tex, coord).r
    #else
        #define SHADOWMAP sampler2D
        #define SHADOWCOMPARE(tex,coord) step(coord.z, texture2DProj(tex, coord).r)
    #endif

    #if FILTER_MODE == 10
        #define GETSHADOW Shadow_DoShadowCompare
        #define KERNEL 1.0
    #elif FILTER_MODE == 1
        #ifdef HARDWARE_SHADOWS
            #define GETSHADOW Shadow_DoShadowCompare
        #else
            #define GETSHADOW Shadow_DoBilinear_2x2
        #endif
        #define KERNEL 1.0
    #endif


#endif

#if (FILTER_MODE == 2)
    #define GETSHADOW Shadow_DoDither_2x2
    #define KERNEL 1.0
#elif FILTER_MODE == 3
    #define GETSHADOW Shadow_DoPCF
    #define KERNEL 4.0
#elif FILTER_MODE == 4
    #define GETSHADOW Shadow_DoPCFPoisson
    #define KERNEL 4.0
#elif FILTER_MODE == 5
    #define GETSHADOW Shadow_DoPCF
    #define KERNEL 8.0
#endif

uniform SHADOWMAP m_ShadowMap0;
uniform SHADOWMAP m_ShadowMap1;
uniform SHADOWMAP m_ShadowMap2;
uniform SHADOWMAP m_ShadowMap3;
#ifdef POINTLIGHT
    uniform SHADOWMAP m_ShadowMap4;
    uniform SHADOWMAP m_ShadowMap5;
#endif

#ifdef PSSM
uniform vec4 m_Splits;
#endif

uniform float m_ShadowIntensity;

const vec2 pixSize2 = vec2(1.0 / SHADOWMAP_SIZE);
float shadowBorderScale = 1.0;

float Shadow_DoShadowCompare(in SHADOWMAP tex,in vec4 projCoord){
    return SHADOWCOMPARE(tex, projCoord);
}

float Shadow_BorderCheck(in vec2 coord){
    #ifdef GL_ES
        return 0.0;
    #else
        // Fastest, "hack" method (uses 4-5 instructions)
        vec4 t = vec4(coord.xy, 0.0, 1.0);
        t = step(t.wwxy, t.xyzz);
        return dot(t,t);
    #endif
}

float Shadow_Nearest(in SHADOWMAP tex,in vec4 projCoord){
    float border = Shadow_BorderCheck(projCoord.xy);
    if (border > 0.0){
        return 1.0;
    }
    return SHADOWCOMPARE(tex, projCoord);
}

float Shadow_DoShadowCompareOffset(in SHADOWMAP tex,in vec4 projCoord,in vec2 offset){
    vec4 coord = vec4(projCoord.xy + offset.xy * pixSize2 * shadowBorderScale, projCoord.zw);
    return SHADOWCOMPARE(tex, coord);
}


float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
    float border = Shadow_BorderCheck(projCoord.xy);
    if (border > 0.0)
        return 1.0;

    float shadow = 0.0;
    //IVEC2 o = IVEC2(mod(floor(gl_FragCoord.xy), 2.0));
    vec2 o = vec2(IVEC2(mod(floor(gl_FragCoord.xy), 2.0))); //Strict type checking in GLSL ES
    shadow += Shadow_DoShadowCompareOffset(tex, projCoord, (vec2(-1.5, 1.5)+o));
    shadow += Shadow_DoShadowCompareOffset(tex, projCoord, (vec2( 0.5, 1.5)+o));
    shadow += Shadow_DoShadowCompareOffset(tex, projCoord, (vec2(-1.5, -0.5)+o));
    shadow += Shadow_DoShadowCompareOffset(tex, projCoord, (vec2( 0.5, -0.5)+o));
    shadow *= 0.25;
    return shadow;
}

float Shadow_DoBilinear_2x2(in SHADOWMAP tex, in vec4 projCoord){
    float border = Shadow_BorderCheck(projCoord.xy);
    if (border > 0.0){
        return 1.0;
    }

    vec4 gather = vec4(0.0);
    #if __VERSION__ >= 130
        #if defined GL_ARB_gpu_shader5 || defined GL_OES_gpu_shader5
            vec4 coord = vec4(projCoord.xyz / projCoord.www,0.0);
            gather = SHADOWGATHER(tex, coord);
        #else
            gather.x = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 1));
            gather.y = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 1));
            gather.z = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(1, 0));
            gather.w = SHADOWCOMPAREOFFSET(tex, projCoord, ivec2(0, 0));
        #endif
    #else
        gather.x = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 0.0));
        gather.y = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 0.0));
        gather.z = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(0.0, 1.0));
        gather.w = Shadow_DoShadowCompareOffset(tex, projCoord, vec2(1.0, 1.0));
    #endif

   vec2 f = fract( projCoord.xy * SHADOWMAP_SIZE );
   vec2 mx = mix( gather.wx, gather.zy, f.x );
   return mix( mx.x, mx.y, f.y );
}

float Shadow_DoPCF(in SHADOWMAP tex,in vec4 projCoord){

    float shadow = 0.0;
    float border = Shadow_BorderCheck(projCoord.xy);
    if (border > 0.0)
        return 1.0;

    const float bound = (KERNEL * 0.5 - 0.5 ) * PCFEDGE;
    for (float y = -bound; y <= bound; y += PCFEDGE){
        for (float x = -bound; x <= bound; x += PCFEDGE){
            #if __VERSION__ < 130
                shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) + border, 0.0, 1.0);
            #else
                shadow += Shadow_DoShadowCompareOffset(tex, projCoord, vec2(x,y));
            #endif
        }
    }

    shadow = shadow / (KERNEL * KERNEL);
    return shadow;
}

//12 tap poisson disk
const vec2 poissonDisk0 =  vec2(-0.1711046, -0.425016);
const vec2 poissonDisk1 =  vec2(-0.7829809, 0.2162201);
const vec2 poissonDisk2 =  vec2(-0.2380269, -0.8835521);
const vec2 poissonDisk3 =  vec2(0.4198045, 0.1687819);
const vec2 poissonDisk4 =  vec2(-0.684418, -0.3186957);
const vec2 poissonDisk5 =  vec2(0.6026866, -0.2587841);
const vec2 poissonDisk6 =  vec2(-0.2412762, 0.3913516);
const vec2 poissonDisk7 =  vec2(0.4720655, -0.7664126);
const vec2 poissonDisk8 =  vec2(0.9571564, 0.2680693);
const vec2 poissonDisk9 =  vec2(-0.5238616, 0.802707);
const vec2 poissonDisk10 = vec2(0.5653144, 0.60262);
const vec2 poissonDisk11 = vec2(0.0123658, 0.8627419);


float Shadow_DoPCFPoisson(in SHADOWMAP tex, in vec4 projCoord){
    float shadow = 0.0;
    float border = Shadow_BorderCheck(projCoord.xy);
    if (border > 0.0){
        return 1.0;
    }

    vec2 texelSize = pixSize2 * 4.0 * PCFEDGE * shadowBorderScale;

    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk0 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk1 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk2 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk3 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk4 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk5 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk6 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk7 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk8 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk9 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk10 * texelSize, projCoord.zw));
    shadow += SHADOWCOMPARE(tex, vec4(projCoord.xy + poissonDisk11 * texelSize, projCoord.zw));

    //this is divided by 12
    return shadow * 0.08333333333;
}

#ifdef POINTLIGHT
    float getPointLightShadows(in vec4 worldPos,in vec3 lightPos,
                           in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3,in SHADOWMAP shadowMap4,in SHADOWMAP shadowMap5,
                           in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3,in vec4 projCoord4,in vec4 projCoord5){
        float shadow = 1.0;
        vec3 vect = worldPos.xyz - lightPos;
        vec3 absv= abs(vect);
        float maxComp = max(absv.x,max(absv.y,absv.z));
        if(maxComp == absv.y){
           if(vect.y < 0.0){
               shadow = GETSHADOW(shadowMap0, projCoord0 / projCoord0.w);
           }else{
               shadow = GETSHADOW(shadowMap1, projCoord1 / projCoord1.w);
           }
        }else if(maxComp == absv.z){
           if(vect.z < 0.0){
               shadow = GETSHADOW(shadowMap2, projCoord2 / projCoord2.w);
           }else{
               shadow = GETSHADOW(shadowMap3, projCoord3 / projCoord3.w);
           }
        }else if(maxComp == absv.x){
           if(vect.x < 0.0){
               shadow = GETSHADOW(shadowMap4, projCoord4 / projCoord4.w);
           }else{
               shadow = GETSHADOW(shadowMap5, projCoord5 / projCoord5.w);
           }
        }
        return shadow;
    }
#else
 #ifdef PSSM
    float getDirectionalLightShadows(in vec4 splits,in float shadowPosition,
                                    in SHADOWMAP shadowMap0,in SHADOWMAP shadowMap1,in SHADOWMAP shadowMap2,in SHADOWMAP shadowMap3,
                                    in vec4 projCoord0,in vec4 projCoord1,in vec4 projCoord2,in vec4 projCoord3){
        float shadow = 1.0;
        if(shadowPosition < splits.x){
            shadow = GETSHADOW(shadowMap0, projCoord0 );
        }else if( shadowPosition <  splits.y){
            shadowBorderScale = 0.5;
            shadow = GETSHADOW(shadowMap1, projCoord1);
        }else if( shadowPosition <  splits.z){
            shadowBorderScale = 0.25;
            shadow = GETSHADOW(shadowMap2, projCoord2);
        }else if( shadowPosition <  splits.w){
            shadowBorderScale = 0.125;
            shadow = GETSHADOW(shadowMap3, projCoord3);
        }
        return shadow;
    }
 #else
    float getSpotLightShadows(in SHADOWMAP shadowMap,in  vec4 projCoord){
        float shadow = 1.0;
        projCoord /= projCoord.w;
        shadow = GETSHADOW(shadowMap,projCoord);

        //a small falloff to make the shadow blend nicely into the not lighten
        //we translate the texture coordinate value to a -1,1 range so the length
        //of the texture coordinate vector is actually the radius of the lighten area on the ground
        projCoord = projCoord * 2.0 - 1.0;
        float fallOff = ( length(projCoord.xy) - 0.9 ) / 0.1;
        return mix(shadow,1.0,clamp(fallOff,0.0,1.0));
    }
 #endif
#endif




© 2015 - 2024 Weber Informatics LLC | Privacy Policy