Advertisement
Guest User

Untitled

a guest
Sep 16th, 2014
350
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #version 120
  2.  
  3. ///////////////////////////////////////////////////////////////////////////////
  4. //                              Unchangable Variables                        //
  5. ///////////////////////////////////////////////////////////////////////////////
  6. const int   shadowMapResolution     = 2048;
  7. const float shadowDistance          = 120.0;
  8. const float shadowIntervalSize      = 4.0;
  9. const bool  shadowHardwareFiltering = false;
  10. const int   noiseTextureResolution  = 64;
  11.  
  12. const float sunPathRotation         = 25.0;
  13.  
  14. ///////////////////////////////////////////////////////////////////////////////
  15. //                              Changable Variables                          //
  16. ///////////////////////////////////////////////////////////////////////////////
  17.  
  18. #define HARD            0
  19. #define SOFT            1
  20. #define REALISTIC       2
  21.  
  22. #define POISSON         0
  23. #define PCF             1
  24.  
  25. #define PI              3.14159265
  26. #define E               2.71828183
  27.  
  28. #define SHADOW_QUALITY  REALISTIC
  29. #define SHADOW_BIAS     0.0065
  30. #define SHADOW_FILTER   PCF
  31. #define PCSS_SAMPLES    20              //don't make this number greater than 32. You'll just waste GPU time
  32.  
  33. #define SSAO            true
  34. #define SSAO_SAMPLES    32               //more samples = prettier
  35. #define SSAO_STRENGTH   1.0             //bigger number = more SSAO
  36. #define SSAO_RADIUS     150.0             //search a 2-unit radius hemisphere
  37. #define SSAO_MAX_DEPTH  1.0             //if a sample's depth is within 2 units of the world depth, the sample is
  38.                                         //obscured
  39.  
  40. ///////////////////////////////////////////////////////////////////////////////
  41. //                              I need these                                 //
  42. ///////////////////////////////////////////////////////////////////////////////
  43.  
  44. uniform sampler2D gcolor;
  45. uniform sampler2D gdepthtex;
  46. uniform sampler2D gnormal;
  47. uniform sampler2D gaux2;
  48.  
  49. uniform sampler2D shadow;
  50.  
  51. uniform sampler2D noisetex;
  52.  
  53. uniform vec3 cameraPosition;
  54.  
  55. uniform float viewWidth;
  56. uniform float viewHeight;
  57. uniform float far;
  58. uniform float near;
  59.  
  60. uniform mat4 gbufferModelView;
  61. uniform mat4 gbufferProjection;
  62. uniform mat4 gbufferModelViewInverse;
  63. uniform mat4 gbufferProjectionInverse;
  64.  
  65. uniform mat4 shadowModelView;
  66. uniform mat4 shadowProjection;
  67. uniform mat4 shadowModelViewInverse;
  68. uniform mat4 shadowProjectionInverse;
  69.  
  70. varying vec2 coord;
  71.  
  72. varying vec3 lightVector;
  73. varying vec3 lightColor;
  74.  
  75. struct Pixel {
  76.     vec4 position;
  77.     vec4 screenPosition;
  78.     vec3 color;
  79.     vec3 normal;
  80.     float metalness;
  81.     float smoothness;
  82.     bool isWater;
  83.    
  84.     bool skipLighting;
  85.    
  86.     vec3 directLighting;
  87.     vec3 torchLighting;
  88.     vec3 ambientLighting;
  89. };
  90.  
  91. struct World {
  92.     vec3 lightDirection;
  93.     vec3 lightColor;
  94. };
  95.  
  96. ///////////////////////////////////////////////////////////////////////////////
  97. //                              Helper Functions                             //
  98. ///////////////////////////////////////////////////////////////////////////////
  99. //Credit to Sonic Ether for depth, normal, and positions
  100.  
  101. float getDepth(  vec2 coord ) {
  102.     return texture2D( gdepthtex, coord ).r;
  103. }
  104.  
  105. float getDepthLinear( vec2 coord ) {
  106.     return 2.0 * near * far / (far + near - (2.0 * texture2D( gdepthtex, coord ).r - 1.0) * (far - near));
  107. }
  108.  
  109. vec4 getScreenSpacePosition() {
  110.     float depth = getDepth( coord );
  111.     vec4 fragposition = gbufferProjectionInverse * vec4( coord.s * 2.0 - 1.0, coord.t * 2.0 - 1.0, 2.0 * depth - 1.0, 1.0 );
  112.          fragposition /= fragposition.w;
  113.     return fragposition;
  114. }
  115.  
  116. vec4 getWorldSpacePosition() {
  117.     vec4 pos = getScreenSpacePosition();
  118.     pos = gbufferModelViewInverse * pos;
  119.     pos.xyz += cameraPosition.xyz;
  120.     return pos;
  121. }
  122.  
  123. vec3 getColor() {
  124.     return pow( texture2D( gcolor, coord ).rgb, vec3( 2.2 ) );
  125. }
  126.  
  127. bool shouldSkipLighting() {
  128.     return texture2D( gaux2, coord ).r > 0.5;
  129. }
  130.  
  131. bool getWater() {
  132.     return texture2D( gaux2, coord ).b > 0.5;
  133. }
  134.  
  135. float getSmoothness() {
  136.     return texture2D( gaux2, coord ).a;
  137. }
  138.  
  139. vec3 getNormal() {
  140.     return normalize( texture2D( gnormal, coord ).xyz * 2.0 - 1.0 );
  141. }
  142.  
  143. float getMetalness() {
  144.     return texture2D( gnormal, coord ).a;
  145. }
  146.  
  147. ///////////////////////////////////////////////////////////////////////////////
  148. //                              Lighting Functions                           //
  149. ///////////////////////////////////////////////////////////////////////////////
  150.  
  151. //from SEUS v8
  152. vec3 calcShadowCoordinate( in Pixel pixel ) {
  153.     vec4 shadowCoord = pixel.position;
  154.     shadowCoord.xyz -= cameraPosition;
  155.     shadowCoord = shadowModelView * shadowCoord;
  156.     shadowCoord = shadowProjection * shadowCoord;
  157.     shadowCoord /= shadowCoord.w;
  158.    
  159.     shadowCoord.st = shadowCoord.st * 0.5 + 0.5;    //take it from [-1, 1] to [0, 1]
  160.     float dFrag = (1 + shadowCoord.z) * 0.5 + 0.005;
  161.    
  162.     return vec3( shadowCoord.st, dFrag );
  163. }
  164.  
  165. //I'm sorry this is so long, OSX doesn't support GLSL 120 arrays
  166. vec2 poisson( int i ) {
  167.     if ( i == 0 ) {
  168.         return vec2( -0.4994766, -0.4100508 );
  169.     } else if( i == 1 ) {
  170.         return vec2(  0.1725386, -0.50636 );
  171.     } else if( i == 2 ) {
  172.         return vec2( -0.3050305,  0.7459931 );
  173.     } else if( i == 3 ) {
  174.         return vec2(  0.3256707,  0.2347208 );
  175.  
  176.     } else if( 1 == 4 ) {
  177.         return vec2( -0.1094937, -0.752005 );
  178.     } else if( i == 5 ) {
  179.         return vec2(  0.5059697, -0.7294227 );
  180.     } else if( i == 6 ) {
  181.         return vec2( -0.3904303,  0.5678311 );
  182.     } else if( i == 7 ) {
  183.         return vec2(  0.3405131,  0.4458854 );
  184.  
  185.     } else if( i == 8 ) {
  186.         return vec2( -0.163072,  -0.9741971 );
  187.     } else if( i == 9 ) {
  188.         return vec2(  0.4260757, -0.02231212 );
  189.     } else if( i == 10 ) {
  190.         return vec2( -0.8977778,  0.1717084 );
  191.     } else if( i == 11 ) {
  192.         return vec2(  0.02903906, 0.3999698 );
  193.        
  194.     } else if( i == 12 ) {
  195.         return vec2( -0.4680224, -0.4418066 );
  196.     } else if( i == 13 ) {
  197.         return vec2(  0.09780561, -0.1236207 );
  198.     } else if( i == 14 ) {
  199.         return vec2( -0.3564819,  0.2770886 );
  200.     } else if( i == 15 ) {
  201.         return vec2(  0.0663829,  0.9336991 );
  202.        
  203.     } else if( i == 16 ) {
  204.         return vec2( -0.8206947, -0.3301564 );
  205.     } else if( i == 17 ) {
  206.         return vec2(  0.1038207, -0.2167438 );
  207.     } else if( i == 18 ) {
  208.         return vec2( -0.3123821,  0.2344262 );
  209.     } else if( i == 19 ) {
  210.         return vec2(  0.1979104,  0.7830779 );
  211.        
  212.     } else if( i == 20 ) {
  213.         return vec2( -0.6740047, -0.4649915 );
  214.     } else if( i == 21 ) {
  215.         return vec2(  0.08938109, -0.005763604 );
  216.     } else if( i == 22 ) {
  217.         return vec2( -0.6670403,  0.658087 );
  218.     } else if( i == 23 ) {
  219.         return vec2(  0.8211543,  0.365194 );
  220.        
  221.     } else if( i == 24 ) {
  222.         return vec2( -0.8381009, -0.1279669 );
  223.     } else if( i == 25 ) {
  224.         return vec2(  0.6365152, -0.229197 );
  225.     } else if( i == 26 ) {
  226.         return vec2( -0.1748933,  0.1948632 );
  227.     } else if( i == 27 ) {
  228.         return vec2(  0.1710306,  0.5527771 );
  229.        
  230.     } else if( i == 28 ) {
  231.         return vec2( -0.5874177, -0.1295959 );
  232.     } else if( i == 29 ) {
  233.         return vec2(  0.6305282, -0.5586912 );
  234.     } else if( i == 30 ) {
  235.         return vec2( -0.030519,  0.3487186 );
  236.     } else {
  237.         return vec2(  0.4240496, -0.1010172 );
  238.     }
  239. }
  240.  
  241. int rand( vec2 seed ) {
  242.     return int( 32 * fract( sin( dot( vec2( 12.9898, 72.233 ), seed ) * 43758.5453 ) ) );
  243. }
  244.  
  245. //Implements the Percentage-Closer Soft Shadow algorithm, as defined by nVidia
  246. //Implemented by DethRaid - github.com/DethRaid
  247. float calcPenumbraSize( vec3 shadowCoord ) {
  248.     float dFragment = shadowCoord.z;
  249.     float dBlocker = 0;
  250.     float penumbra = 0;
  251.     float wLight = 0.5;
  252.  
  253.     // Sample the shadow map 8 times
  254.     float temp;
  255.     float count = 0;
  256.  
  257.  
  258.  
  259.     for( int i = 0; i < 32; i++ ) {    
  260.         temp = texture2D( shadow, shadowCoord.st + (poisson( i ) *  0.005 ) ).r;
  261.         if( temp < dFragment ) {
  262.             dBlocker += temp;
  263.             count += 1.0;
  264.         }
  265.     }
  266.  
  267.     if( count > 0.1 ) {
  268.         dBlocker /= count;
  269.         penumbra = wLight * (dFragment - dBlocker) / dFragment;
  270.     }
  271.    
  272.     return penumbra * 0.025;
  273. }
  274.  
  275. void calcShadowing( inout Pixel pixel ) {
  276.     vec3 shadowCoord = calcShadowCoordinate( pixel );
  277.    
  278.     if( shadowCoord.x > 1 || shadowCoord.x < 0 ||
  279.         shadowCoord.y > 1 || shadowCoord.y < 0 ) {
  280.         return;
  281.     }
  282.    
  283. #if SHADOW_QUALITY == HARD
  284.     float shadowDepth = texture2D( shadow, shadowCoord.st ).r;    
  285.     if( shadowCoord.z - shadowDepth > SHADOW_BIAS ) {
  286.         pixel.directLighting = vec3( 0 );
  287.         return;
  288.     }
  289.    
  290. #elif SHADOW_QUALITY >= SOFT
  291.     float penumbraSize = 3;
  292.  
  293. #if SHADOW_FILTER == PCF
  294.     penumbraSize = 0.00049;
  295. #endif
  296.    
  297. #if SHADOW_QUALITY == REALISTIC
  298.     penumbraSize = calcPenumbraSize( shadowCoord );
  299. #endif
  300.    
  301.     float visibility = 1.0;
  302.  
  303. #if SHADOW_FILTER == POISSON
  304.     float sub = 1.0 / PCSS_SAMPLES;
  305.     int shadowCount = 0;
  306.     for( int i = 0; i < PCSS_SAMPLES; i++ ) {
  307.         int ind = rand( coord * i );
  308.         float shadowDepth = texture2D( shadow, shadowCoord.st + (penumbraSize * poisson( ind )) ).r;
  309.         if( shadowCoord.z - shadowDepth > SHADOW_BIAS ) {
  310.             visibility -= sub;
  311.         }
  312.     }
  313. #else
  314.     //go from UV to texels
  315.     int kernelSize = int( penumbraSize * shadowMapResolution * 5 );
  316.     int kernelSizeHalf = kernelSize / 2;
  317.     float sub = 1.0 / (4 * kernelSizeHalf * kernelSizeHalf);
  318.     float shadowDepth;
  319.  
  320.     for( int i = -kernelSizeHalf; i < kernelSizeHalf; i++ ) {
  321.         for( int j = -kernelSizeHalf; j < kernelSizeHalf; j++ ) {
  322.             vec2 sampleCoord = vec2( j, i ) / shadowMapResolution;
  323.             shadowDepth = texture2D( shadow, shadowCoord.st + sampleCoord ).r;
  324.             if( shadowCoord.z - shadowDepth > SHADOW_BIAS ) {
  325.                 visibility -= sub;
  326.             }
  327.         }
  328.     }
  329. #endif
  330.  
  331.     visibility = max( visibility, 0 );
  332.     pixel.directLighting *= visibility;
  333. #endif
  334. }
  335.  
  336. vec3 fresnel( vec3 specularColor, float hdotl ) {
  337.     return specularColor + (vec3( 1.0 ) - specularColor) * pow( 1.0f - hdotl, 5 );
  338. }
  339.  
  340. //Cook-Toorance shading
  341. void calcDirectLighting( inout Pixel pixel ) {
  342.     //data that's super important to the shading algorithm
  343.     vec3 albedo = pixel.color;
  344.     vec3 normal = pixel.normal;
  345.     float specularPower = pow( 10 * pixel.smoothness + 1, 2 );  //yeah
  346.     float metalness = pixel.metalness;
  347.     vec3 specularColor = pixel.color * metalness + (1 - metalness) * vec3( 1.0 );
  348.     specularColor *= pixel.smoothness;
  349.  
  350.     //Other useful value
  351.     vec3 viewVector = normalize( cameraPosition - pixel.position.xyz );
  352.     viewVector = (gbufferModelView * vec4( viewVector, 0 )).xyz;
  353.     vec3 half = normalize( lightVector + viewVector );
  354.     float specularNormalization = (specularPower + 2.0) / 8.0;
  355.  
  356.  
  357.     float ndotl = dot( normal, lightVector );
  358.     float ndoth = dot( normal, half );
  359.     float ndotv = dot( normal, viewVector );
  360.  
  361.     ndotl = max( 0, ndotl );
  362.     ndoth = max( 0, ndoth );
  363.     ndotv = max( 0, ndotv );
  364.  
  365.     //calculate diffuse lighting
  366.     vec3 lambert = albedo * ndotl;
  367.  
  368.     vec3 fresnel = fresnel( specularColor, ndotv );
  369.  
  370.     //microfacet slope distribution
  371.     //Or, how likely is it that microfactes are oriented toward the half vector  
  372.     float d = pow( ndoth, specularPower );
  373.  
  374.     vec3 specular = fresnel * specularNormalization * d * ndotl * 0.5;
  375.  
  376.     lambert = (vec3( 1.0 ) - specular) * lambert * (1.0 - metalness);
  377.  
  378.     pixel.directLighting = (lambert + specular) * lightColor * 0.4;
  379.     //pixel.directLighting = pixel.color * ndotl * lightColor;
  380.     calcShadowing( pixel );
  381.     //pixel.directLighting = fresnel * ndoth;
  382. }
  383.  
  384. //calcualtes the lighting from the torches
  385. void calcTorchLighting( inout Pixel pixel ) {
  386.     vec3 torchColor = vec3( 1, 0.6, 0.4 ) * 0.75;
  387.     float torchIntensity = length( torchColor );
  388.     torchIntensity = pow( torchIntensity, 3 );
  389.     torchColor *= torchIntensity;
  390.     float torchFac = texture2D( gaux2, coord ).g;
  391.     pixel.torchLighting = torchColor * torchFac;
  392. }
  393.  
  394. void calcAmbientLighting( inout Pixel pixel ) {
  395.     pixel.ambientLighting = vec3( 0.15, 0.17, 0.2 );
  396. }
  397.  
  398. ///////////////////////////////////////////////////////////////////////////////
  399. //                              Main Functions                               //
  400. ///////////////////////////////////////////////////////////////////////////////
  401.  
  402. void fillPixelStruct( inout Pixel pixel ) {
  403.     pixel.position =        getWorldSpacePosition();
  404.     pixel.normal =          getNormal();
  405.     pixel.color =           getColor();
  406.     pixel.metalness =       getMetalness();
  407.     pixel.smoothness =      getSmoothness();
  408.     pixel.skipLighting =    shouldSkipLighting();
  409.     pixel.isWater =         getWater();
  410. }
  411.  
  412. vec2 texelToScreen( vec2 texel ) {
  413.     float newx = texel.x / viewWidth;
  414.     float newy = texel.y / viewHeight;
  415.     return vec2( newx, newy );
  416. }
  417.  
  418.  
  419. void calcSSAO( inout Pixel pixel ) {
  420.     float ssaoFac = SSAO_STRENGTH;
  421.     float compareDepth = getDepthLinear( coord );
  422.  
  423.     float radiusx = SSAO_RADIUS / (viewWidth * compareDepth);
  424.     float radiusy = SSAO_RADIUS / (viewHeight * compareDepth);
  425.     vec2 sampleScale = vec2( radiusx, radiusy );
  426.  
  427.     float occlusionPerSample = ssaoFac / float( SSAO_SAMPLES );
  428.  
  429.     vec2 sampleCoord;
  430.     for( int i = 0; i < SSAO_SAMPLES; i++ ) {
  431.         sampleCoord = poisson( rand( coord * i ) );
  432.         sampleCoord *= sign( dot( sampleCoord, pixel.normal.xy ) );
  433.         sampleCoord = sampleCoord * sampleScale + coord;
  434.         float depthDiff = compareDepth - getDepthLinear( sampleCoord );
  435.         if( depthDiff > 0.05 && depthDiff < SSAO_MAX_DEPTH ) {
  436.             ssaoFac -= occlusionPerSample * (1 - (depthDiff / SSAO_MAX_DEPTH));
  437.         }
  438.     }
  439.  
  440.     ssaoFac = max( ssaoFac, 0 );
  441.    
  442.     pixel.directLighting *= ssaoFac;
  443.     pixel.torchLighting *= ssaoFac;
  444.     pixel.ambientLighting *= ssaoFac;
  445. }
  446.  
  447. void calcSkyScattering( inout Pixel pixel ) {
  448.     float fogFac = pixel.position.z * 0.001;
  449.     pixel.color = vec3( 0.529, 0.808, 0.980 ) * fogFac + pixel.color * (1 - fogFac);
  450. }
  451.  
  452. vec3 calcLitColor( in Pixel pixel ) {
  453.     vec3 color = pixel.directLighting +
  454.                  pixel.color * pixel.torchLighting +
  455.                  pixel.color * pixel.ambientLighting;
  456.     return pow( color / 1.25, vec3( 1 / 2.2 ) );
  457. }
  458.  
  459. void main() {
  460.     Pixel pixel;
  461.     vec3 finalColor;
  462.    
  463.     fillPixelStruct( pixel );
  464.    
  465.     if( !pixel.skipLighting ) {
  466.         calcDirectLighting( pixel );
  467.         calcTorchLighting( pixel );
  468.         calcAmbientLighting( pixel );
  469.    
  470. //        calcSSAO( pixel );
  471.  
  472.         //calcSkyScattering( pixel );
  473.    
  474.         finalColor = calcLitColor( pixel );
  475.     } else {
  476.         finalColor = pixel.color;
  477.     }
  478.  
  479.     gl_FragData[3] = vec4( finalColor, 1 );
  480. //    gl_FragData[3] = vec4( pixel.normal, 1 );
  481. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement