Home | History | Annotate | Download | only in ShaderLib
      1 #ifdef NO_SHADOW2DPROJ
      2 #define SHADOWMAP sampler2D
      3 #define SHADOWTEX texture2D
      4 #define SHADCOORD(coord) coord.xy
      5 #else
      6 #define SHADOWMAP sampler2DShadow
      7 #define SHADOWTEX shadow2D
      8 #define SHADCOORD(coord) vec3(coord.xy,0.0)
      9 #endif
     10 
     11 //float shadowDepth = texture2DProj(tex, projCoord);
     12 
     13 const float texSize = 1024.0;
     14 const float pixSize = 1.0 / texSize;
     15 const vec2 pixSize2 = vec2(pixSize);
     16 
     17 float Shadow_DoShadowCompareOffset(in SHADOWMAP tex, vec4 projCoord, vec2 offset){
     18      return step(projCoord.z, SHADOWTEX(tex, SHADCOORD(projCoord.xy + offset * pixSize2)).r);
     19 }
     20 
     21 float Shadow_DoShadowCompare(in SHADOWMAP tex, vec4 projCoord){
     22     return step(projCoord.z, SHADOWTEX(tex, SHADCOORD(projCoord.xy)).r);
     23 }
     24 
     25 float Shadow_BorderCheck(in vec2 coord){
     26     // Very slow method (uses 24 instructions)
     27     //if (coord.x >= 1.0)
     28     //    return 1.0;
     29     //else if (coord.x <= 0.0)
     30     //    return 1.0;
     31     //else if (coord.y >= 1.0)
     32     //    return 1.0;
     33     //else if (coord.y <= 0.0)
     34     //    return 1.0;
     35     //else
     36     //    return 0.0;
     37 
     38     // Fastest, "hack" method (uses 4-5 instructions)
     39     vec4 t = vec4(coord.xy, 0.0, 1.0);
     40     t = step(t.wwxy, t.xyzz);
     41     return dot(t,t);
     42 }
     43 
     44 float Shadow_DoDither_2x2(in SHADOWMAP tex, in vec4 projCoord){
     45     float shadow = 0.0;
     46     vec2 o = mod(floor(gl_FragCoord.xy), 2.0);
     47     shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, 1.5) + o);
     48     shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, 1.5) + o);
     49     shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2(-1.5, -0.5) + o);
     50     shadow += Shadow_DoShadowCompareOffset(tex,projCoord,vec2( 0.5, -0.5) + o);
     51     shadow *= 0.25 ;
     52     return shadow;
     53 }
     54 
     55 float Shadow_DoBilinear(in SHADOWMAP tex, in vec4 projCoord){
     56     const vec2 size  = vec2(256.0);
     57     const vec2 pixel = vec2(1.0) / vec2(256.0);
     58 
     59     vec2 tc = projCoord.xy * size;
     60     vec2 bl = fract(tc);
     61     vec2 dn = floor(tc) * pixel;
     62     vec2 up = dn + pixel;
     63    
     64     vec4 coord = vec4(dn.xy, projCoord.zw);
     65     float s_00 = Shadow_DoShadowCompare(tex, coord);
     66     s_00 = clamp(s_00, 0.0, 1.0);
     67 
     68     coord = vec4(up.x, dn.y, projCoord.zw);
     69     float s_10 = Shadow_DoShadowCompare(tex, coord);
     70     s_10 = clamp(s_10, 0.0, 1.0);
     71 
     72     coord = vec4(dn.x, up.y, projCoord.zw);
     73     float s_01 = Shadow_DoShadowCompare(tex, coord);
     74     s_01 = clamp(s_01, 0.0, 1.0);
     75 
     76     coord = vec4(up.xy, projCoord.zw);
     77     float s_11 = Shadow_DoShadowCompare(tex, coord);
     78     s_11 = clamp(s_11, 0.0, 1.0);
     79 
     80     float xb0   = mix(s_00, s_10, clamp(bl.x, 0.0, 1.0));
     81     float xb1   = mix(s_01, s_11, clamp(bl.x, 0.0, 1.0));
     82     float yb    = mix(xb0, xb1,   clamp(bl.y, 0.0, 1.0));
     83     return yb;
     84 }
     85 
     86 float Shadow_DoPCF_2x2(in SHADOWMAP tex, in vec4 projCoord){
     87 
     88     float shadow = 0.0;
     89     float x,y;
     90     for (y = -1.5 ; y <=1.5 ; y+=1.0)
     91             for (x = -1.5 ; x <=1.5 ; x+=1.0)
     92                     shadow += clamp(Shadow_DoShadowCompareOffset(tex,projCoord,vec2(x,y)) +
     93                                     Shadow_BorderCheck(projCoord.xy),
     94                                     0.0, 1.0);
     95 
     96     shadow /= 16.0 ;
     97     return shadow;
     98 }
     99 
    100 
    101 float Shadow_GetShadow(in SHADOWMAP tex, in vec4 projCoord){
    102     return clamp(Shadow_DoDither_2x2(tex, projCoord) + Shadow_BorderCheck(projCoord.xy), 0.0, 1.0);
    103 }
    104 
    105 
    106