Advertisement
Guest User

Untitled

a guest
Oct 7th, 2014
442
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.09 KB | None | 0 0
  1. #version 130
  2. precision mediump float;
  3.  
  4. #define SAMPLER_ARRAY sampler2DArray
  5. #define TEXTURE_ARRAY texture
  6.  
  7. #define SAMPLER_2D sampler2D
  8. #define TEXTURE_2D texture
  9.  
  10. #define ATLAS_FILTER_MODE 11
  11. #define DISTANCE_ATLAS 1
  12. uniform vec4 m_Color;
  13. varying vec4 color;
  14.  
  15. #ifdef DISTANCE_MAP
  16. uniform sampler2DArray m_DistanceMap;
  17. varying vec3 texCoord;
  18. #endif
  19. #ifdef DISTANCE_ATLAS
  20. uniform sampler2D m_DistanceAtlas;
  21. varying vec2 texCoord;
  22. uniform int m_AtlasWidth;
  23. uniform int m_AtlasHeight;
  24. #if (__VERSION__ == 120)
  25. varying vec2 atlasTileOffsetF;
  26. varying vec2 atlasTileSizeF;
  27. ivec2 atlasTileOffset;
  28. ivec2 atlasTileSize;
  29. #define TEXEL_FETCH(sampler, coord, lod) texelFetch120(sampler, coord, lod)
  30. vec4 texelFetch120(sampler2D tex, ivec2 coord, int lod) {
  31.     ivec2 size = ivec2(m_AtlasWidth, m_AtlasHeight);
  32.     vec2 uv = vec2(((coord.x << lod) + 0.5) / size.x, ((coord.y << lod) + 0.5) / size.y);
  33.     return texture2D(tex, uv);
  34. }
  35. void getTextureAtlasLayer() {
  36.     atlasTileOffset = ivec2(round(atlasTileOffsetF));
  37.     atlasTileSize = ivec2(round(atlasTileSizeF));
  38. }
  39. #define GET_TEXTURE_ATLAS_LAYER getTextureAtlasLayer()
  40. #elif (__VERSION__ >= 130)
  41. flat in ivec2 atlasTileOffset;
  42. flat in ivec2 atlasTileSize;
  43. #define GET_TEXTURE_ATLAS_LAYER /* empty */
  44. #define TEXEL_FETCH(sampler, coord, lod) texelFetch(sampler, coord, lod)
  45. #endif
  46.  
  47. #if (__VERSION__ == 120)
  48. int iclamp(int x, int minVal, int maxVal) {
  49.     if(x < minVal)
  50.         return minVal;
  51.     if(x > maxVal)
  52.         return maxVal;
  53.     return x;
  54.     //return int(clamp(float(x), float(minVal), float(maxVal)));
  55. }
  56. #else
  57. #define iclamp(x, minVal, maxVal) clamp(x, minVal, maxVal)
  58. #endif
  59.  
  60. #define ATLAS_MAG_MIN_FILTER (ATLAS_FILTER_MODE & 0x7)
  61. #define ATLAS_WRAP_MODE ((ATLAS_FILTER_MODE & 0x8) >> 3)
  62.  
  63. #if (ATLAS_MAG_MIN_FILTER == 0) // MagFilter.Nearest + MinFilter.NearestNoMipMaps
  64.     #define TEXTURE_ATLAS getAtlasNearestNoMipmap
  65.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  66. #endif
  67. #if (ATLAS_MAG_MIN_FILTER == 1) // MagFilter.Nearest + MinFilter.NearestNearestMipMap
  68.     #define TEXTURE_ATLAS getAtlasNearestMipMapNearest
  69.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  70. #endif
  71. #if (ATLAS_MAG_MIN_FILTER == 2) // MagFilter.Nearest + MinFilter.NearestLinearMipMap
  72.     #define TEXTURE_ATLAS getAtlasNearestMipMapLinear
  73.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  74. #endif
  75. #if (ATLAS_MAG_MIN_FILTER == 3) // MagFilter.Bilinear + MinFilter.BilinearNoMipMaps
  76.     #define TEXTURE_ATLAS getAtlasBilinearNoMipMaps
  77.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  78. #endif
  79. #if (ATLAS_MAG_MIN_FILTER == 4) // MagFilter.Bilinear + MinFilter.NearestNearestMipMap
  80.     #define TEXTURE_ATLAS getAtlasBilinearNearestMipMapNearest
  81.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  82. #endif
  83. #if (ATLAS_MAG_MIN_FILTER == 5) // MagFilter.Bilinear + MinFilter.NearestLinearMipMap
  84.     #define TEXTURE_ATLAS getAtlasBilinearNearestMipMapLinear
  85.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  86. #endif
  87. #if (ATLAS_MAG_MIN_FILTER == 6) // MagFilter.Bilinear + MinFilter.BilinearNearestMipMap
  88.     #define TEXTURE_ATLAS getAtlasBilinearMipMapNearest
  89.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  90. #endif
  91. #if (ATLAS_MAG_MIN_FILTER == 7) // MagFilter.Bilinear + MinFilter.Trilinear
  92.     #define TEXTURE_ATLAS getAtlasTrilinearMipMap
  93.     #define TEXTURE_ATLAS_ALPHA getAtlasNearestNoMipmap
  94. #endif
  95.  
  96. // This finctions may give edge issues
  97. // Use TEXTURE_ATLAS to correct filtering
  98. #define TEXTURE_ATLAS_WRAPPED getAtlasWrapped
  99. #define TEXTURE_ATLAS_SIMPLE getAtlasSimple
  100.  
  101. /******************** Filtering routine *********************************************/
  102.  
  103. // Transform tile texcoords to the atlas
  104. vec2 getAtlasCoords(sampler2D atlas, vec2 uv) {
  105.     ivec2 size = ivec2(m_AtlasWidth, m_AtlasHeight); // textureSize(atlas, 0);
  106.     return vec2((uv.x * atlasTileSize.x + atlasTileOffset.x) / size.x, (uv.y * atlasTileSize.y + atlasTileOffset.y) / size.y);
  107. }
  108.  
  109. // Wrapping texcoords inside the atlas tile
  110. vec2 getAtlasCoordsWrapped(sampler2D atlas, vec2 uv) {
  111. #if (ATLAS_WRAP_MODE == 0)
  112.     vec2 wrappedUV = fract(uv);
  113. #endif
  114. #if (ATLAS_WRAP_MODE == 1)
  115.     vec2 wrappedUV = clamp(uv, vec2(0), vec2(1));
  116. #endif
  117.     return getAtlasCoords(atlas, wrappedUV);
  118. }
  119.  
  120. // Wrapping pixel inside the atlas tile
  121. ivec2 wrapTilePixel(ivec2 pixel, ivec2 tileOffset, ivec2 tileSize) {
  122. #if (ATLAS_WRAP_MODE == 0)
  123.     ivec2 wrappedPixel = ivec2(mod(pixel.x, tileSize.x), mod(pixel.y, tileSize.y));
  124. #endif
  125. #if (ATLAS_WRAP_MODE == 1)
  126.     ivec2 wrappedPixel = ivec2(iclamp(pixel.x, 1, tileSize.x - 2), iclamp(pixel.y, 1, tileSize.y - 2));
  127. #endif
  128.     return wrappedPixel + tileOffset;
  129. }
  130.  
  131. // Compute nearest pixel at the atlas
  132. ivec2 computeAtlasNearestPixel(vec2 uv, int level) {
  133.     ivec2 tileOffset = ivec2(atlasTileOffset.x >> level, atlasTileOffset.y >> level);
  134.     ivec2 tileSize = ivec2(atlasTileSize.x >> level, atlasTileSize.y >> level);
  135.     ivec2 pixel = ivec2(floor(uv.x * tileSize.x), floor(uv.y * tileSize.y));
  136.     pixel = wrapTilePixel(pixel, tileOffset, tileSize);
  137.     return pixel;
  138. }
  139.  
  140. // Compute nearest pixels at the atlas for bilinear filtering
  141. vec2 computeAtlasBilinearPixels(vec2 uv, int level, out ivec2 pixelPrev, out ivec2 pixelNext) {
  142.     ivec2 tileOffset = ivec2(atlasTileOffset.x >> level, atlasTileOffset.y >> level);
  143.     ivec2 tileSize = ivec2(atlasTileSize.x >> level, atlasTileSize.y >> level);
  144.     // Texels centering
  145.     vec2 pixel = vec2(uv.x * tileSize.x - 0.5, uv.y * tileSize.y - 0.5);
  146.     // Get atlas nearest pixels
  147.     pixelPrev = ivec2(floor(pixel.x), floor(pixel.y));
  148.     pixelNext = ivec2(ceil(pixel.x), ceil(pixel.y));
  149.     // Compute interpolation factor
  150.     vec2 pixelInt = pixel - pixelPrev;
  151.     // Wrap pixels inside the atlas tile
  152.     pixelPrev = wrapTilePixel(pixelPrev, tileOffset, tileSize);
  153.     pixelNext = wrapTilePixel(pixelNext, tileOffset, tileSize);
  154.     return pixelInt;
  155. }
  156.  
  157. // Get bilinear interpolated color from the atlas
  158. vec4 getAtlasBilinearTextel(sampler2D atlas, vec2 uv, int level) {
  159.     ivec2 pixelPrev, pixelNext;
  160.     vec2 pixelInt = computeAtlasBilinearPixels(uv, level, pixelPrev, pixelNext);
  161.     // Compute bilinear interpolation
  162.     vec4 c0 = TEXEL_FETCH(atlas, ivec2(pixelPrev.x, pixelPrev.y), level);
  163.     vec4 c1 = TEXEL_FETCH(atlas, ivec2(pixelNext.x, pixelPrev.y), level);
  164.     vec4 c2 = TEXEL_FETCH(atlas, ivec2(pixelPrev.x, pixelNext.y), level);
  165.     vec4 c3 = TEXEL_FETCH(atlas, ivec2(pixelNext.x, pixelNext.y), level);
  166.     return mix(mix(c0, c1, pixelInt.x), mix(c2, c3, pixelInt.x), pixelInt.y);
  167. }
  168.  
  169. // Get nearest color from the atlas
  170. vec4 getAtlasNearestTextel(sampler2D atlas, vec2 uv, int level) {
  171.     ivec2 pixel = computeAtlasNearestPixel(uv, level);
  172.     return TEXEL_FETCH(atlas, pixel, level); // Lookup texels directly
  173. }
  174.  
  175. // Mathemagically estimates mipmap level
  176. float getMipMapLevel(in vec2 uv) {
  177.     int tileSize = atlasTileSize.x; // TODO use both sizes for rectangular textures
  178.     // dFdx and dFdy use texcoors in texel units
  179.     vec2  dx_vtc        = dFdx(uv * tileSize);
  180.     vec2  dy_vtc        = dFdy(uv * tileSize);
  181.     float delta_max_sqr = max(dot(dx_vtc, dx_vtc), dot(dy_vtc, dy_vtc));
  182.     float mml = 0.5 * log2(delta_max_sqr);
  183.     return clamp(mml, 0, log2(tileSize));
  184. }
  185.  
  186. // Get nearest mipmap level for atlas texture
  187. int getAtlasNearestMipMapLevel(vec2 uv) {
  188.     float level = getMipMapLevel(uv);
  189.     return int(floor(level));
  190. }
  191.  
  192. // Computes nearest mipmap levels for atlas mipmap linear filtering
  193. float computeAtlasLinearMipMapLevels(vec2 uv, out int levelPrev, out int levelNext) {
  194.     float level = getMipMapLevel(uv);
  195.     levelPrev = int(floor(level));
  196.     levelNext = int(ceil(level));
  197.     float levelInt = level - levelPrev; // interpolation factor
  198.     return levelInt;
  199. }
  200.  
  201. /******************** Filtering methods functions *************************************/
  202. vec4 getAtlasNearestNoMipmap(sampler2D atlas, vec2 uv) {
  203.     return getAtlasNearestTextel(atlas, uv, 0);
  204. }
  205.  
  206. vec4 getAtlasNearestMipMapNearest(sampler2D atlas, vec2 uv) {
  207.     int level = getAtlasNearestMipMapLevel(uv);
  208.     return getAtlasNearestTextel(atlas, uv, level);
  209. }
  210.  
  211. vec4 getAtlasNearestMipMapLinear(sampler2D atlas, vec2 uv) {
  212.     int levelPrev, levelNext;
  213.     float levelInt = computeAtlasLinearMipMapLevels(uv, levelPrev, levelNext);
  214.     ivec2 pixelPrev = computeAtlasNearestPixel(uv, levelPrev);
  215.     if(levelNext == 0) { // Magnification
  216.         return TEXEL_FETCH(atlas, pixelPrev, levelPrev);
  217.     } else { // Minification
  218.         ivec2 pixelNext = pixelPrev / 2; // Don't calculate again
  219.         // Compute linear imterpolation from mipmaps
  220.         vec4 c0 = TEXEL_FETCH(atlas, pixelPrev, levelPrev);
  221.         vec4 c1 = TEXEL_FETCH(atlas, pixelNext, levelNext);
  222.         return mix(c0, c1, levelInt);
  223.     }
  224. }
  225.  
  226. vec4 getAtlasBilinearNearestMipMapNearest(sampler2D atlas, vec2 uv) {
  227.     int level = getAtlasNearestMipMapLevel(uv);
  228.     if(level == 0) { // Magnification
  229.         return getAtlasBilinearTextel(atlas, uv, 0);
  230.     } else { // Minification
  231.         return getAtlasNearestTextel(atlas, uv, level);
  232.     }
  233. }
  234.  
  235. vec4 getAtlasBilinearNearestMipMapLinear(sampler2D atlas, vec2 uv) {
  236.     int levelPrev, levelNext;
  237.     float levelInt = computeAtlasLinearMipMapLevels(uv, levelPrev, levelNext);
  238.     if(levelNext == 0) { // Magnification
  239.         return getAtlasBilinearTextel(atlas, uv, 0);
  240.     } else { // Minification
  241.         ivec2 pixelPrev = computeAtlasNearestPixel(uv, levelPrev);
  242.         ivec2 pixelNext = pixelPrev / 2; // Don't calculate again
  243.         // Compute linear imterpolation from mipmaps
  244.         vec4 c0 = TEXEL_FETCH(atlas, pixelPrev, levelPrev);
  245.         vec4 c1 = TEXEL_FETCH(atlas, pixelNext, levelNext);
  246.         return mix(c0, c1, levelInt);
  247.     }
  248. }
  249.  
  250. vec4 getAtlasBilinearNoMipMaps(sampler2D atlas, vec2 uv) {
  251.     return getAtlasBilinearTextel(atlas, uv, 0);
  252. }
  253.  
  254. vec4 getAtlasBilinearMipMapNearest(sampler2D atlas, vec2 uv) {
  255.     int level = getAtlasNearestMipMapLevel(uv);
  256.     return getAtlasBilinearTextel(atlas, uv, level);
  257. }
  258.  
  259. vec4 getAtlasTrilinearMipMap(sampler2D atlas, vec2 uv) {
  260.     int levelPrev, levelNext;
  261.     float levelInt = computeAtlasLinearMipMapLevels(uv, levelPrev, levelNext);
  262.     if(levelNext == 0) { // Magnification
  263.         return getAtlasBilinearTextel(atlas, uv, 0);
  264.     } else { // Minification       
  265.         // Compute linear imterpolation from mipmaps
  266.         vec4 c0 = getAtlasBilinearTextel(atlas, uv, levelPrev);
  267.         vec4 c1 = getAtlasBilinearTextel(atlas, uv, levelNext);
  268.         return mix(c0, c1, levelInt);
  269.     }
  270. }
  271.  
  272. vec4 getAtlasSimple(sampler2D atlas, vec2 uv) {
  273.     // Can be used for atlas texture with no filtering
  274.     // And texCoords limited to [0..1]
  275.     uv = getAtlasCoords(atlas, uv);
  276.     return TEXTURE_2D(atlas, uv);
  277. }
  278.  
  279. vec4 getAtlasWrapped(sampler2D atlas, vec2 uv) {
  280.     // Can be used for atlas texture with no filtering
  281.     uv = getAtlasCoordsWrapped(atlas, uv);
  282.     return TEXTURE_2D(atlas, uv);
  283. }
  284. #endif
  285.  
  286. float getDistance() {
  287. #ifdef DISTANCE_MAP
  288.     return TEXTURE_ARRAY(m_DistanceMap, texCoord).a;
  289. #endif
  290. #ifdef DISTANCE_ATLAS
  291.     GET_TEXTURE_ATLAS_LAYER;
  292.     return TEXTURE_ATLAS(m_DistanceAtlas, texCoord).a;
  293. #endif
  294. }
  295.  
  296. void main(){
  297.     vec4 fColor = color;
  298.     if(fColor.a == 0.0) { // if have 0 alpha value, use material color
  299.         fColor = m_Color;
  300.     }
  301. #ifdef APPLY_COLOR
  302.     else {
  303.         fColor *= m_Color;
  304.     }
  305. #endif
  306.     float dist = getDistance();
  307. #ifdef FLAT_ALPHA
  308.     if(dist < 0.5)
  309.         discard;
  310. #else
  311.     float alpha = smoothstep(0.25, 0.75, dist);
  312.     fColor.a *= alpha;
  313. #endif
  314.     gl_FragColor = fColor;
  315. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement