1//----------------------------------------------------------------------------- 2// Program Name: SGXLib_IntegratedPSSM 3// Program Desc: Texture Atlas functions. 4// Program Type: Vertex/Pixel shader 5// Language: GLSL 6//----------------------------------------------------------------------------- 7#extension GL_ARB_shader_texture_lod : require 8 9float mipmapLevel(vec2 coords, vec2 texSize) 10{ 11 coords = coords.xy * texSize; 12 vec2 dx = dFdx(coords.xy); 13 vec2 dy = dFdy(coords.xy); 14 float Px = length(dx); 15 float Py = length(dy); 16 float Pmax = max(Px, Py); 17 return log2(max(Pmax,1)); 18} 19 20 21//----------------------------------------------------------------------------- 22void SGX_Atlas_Sample_Auto_Adjust(in sampler2D sample, 23 in vec2 origTexcoord, 24 in vec2 atlasTexcoord, 25 in vec4 textureData, 26 in vec2 imageSize, 27 out vec4 texel) 28{ 29 // 30 // Most of the idea for this function has been taken from the code under the webpage: 31 // http://www.gamedev.net/topic/534149-solved-texture-seams-using-atlas-with-screenshots/ 32 33 34 // origTexcoord - original texture coordintates as received from the vertex buffer. 35 // atlasTexcoord - texture coordinates that have gone through on which different mathematical 36 // functions to simulate different texture addressing modes (wrap, mirror, clamp) 37 // textureData.xy - top left corner (in 0-1 units) where the needed texture in the texture atlas begins 38 // textureData.zw - width and height in power of 2 for the needed texture in the texture atlas 39 // imageSize - size of the image in pixels 40 // texel - [Output] The color of the pixel at the requested position 41 42 vec2 startPos = textureData.xy; 43 44 45 // calculate the tileSize by using the power of 2 value 46 vec2 pwrs = textureData.zw; 47 48 //Calculate the power of 2 size of the maximum avialable Mipmap 49 //Note: We limit the amount of available LODs to [actual number] - 2 50 //as some atlas packaging tools do not include the last 2 LODs 51 //when packeging DXT format atlas textures. 52 float availableLODCount = min(pwrs.x,pwrs.y) - 2; 53 vec2 tileSize = pow(vec2(2.0,2.0),pwrs); 54 55 // retrieve the mipmap level for this pixel clamped by the power of 2 value 56 float lod = clamp(mipmapLevel(origTexcoord, tileSize), 0, availableLODCount); 57 58 vec2 relativeTileSize = tileSize / imageSize; 59 // get the width/height of the mip surface we've decided on 60 vec2 mipSize = pow(vec2(2.0,2.0), pwrs.xy - ceil(lod)); 61 62 // compute the inverse fraction size for the tile 63 //vec2 lodSize = mipSize * imageSize / tileSize; 64 vec2 lodSizeInv = (relativeTileSize / mipSize); 65 //compute the new coordinates 66 //atlasTexcoord = atlasTexcoord * ((lodSize * (tileSize / imageSize) - 1.0) / lodSize) + (0.5 / lodSize) + startPos; 67 atlasTexcoord = atlasTexcoord * (relativeTileSize - lodSizeInv) + (0.5 * lodSizeInv) + startPos; 68 69 //return the pixel from the correct mip surface of the atlas 70 texel = texture2DLod(sample, atlasTexcoord, lod); 71} 72//----------------------------------------------------------------------------- 73void SGX_Atlas_Sample_Normal(in sampler2D sample, 74 in vec2 origTexcoord, 75 in vec2 atlasTexcoord, 76 in vec4 textureData, 77 in vec2 imageSize, 78 out vec4 texel) 79{ 80 //texcoord contain: 81 // x = texture atlas u 82 // y = texture atlas v 83 // z = derivative of original u 84 // w = derivative of original v 85 atlasTexcoord = textureData.xy + (atlasTexcoord * pow(vec2(2.0,2.0),textureData.zw) / imageSize); 86 //texel = texture2DLod(sample, vec4(atlasTexcoord, 0,0)); 87 texel = texture2D(sample, atlasTexcoord); 88} 89 90//----------------------------------------------------------------------------- 91void SGX_Atlas_Wrap(in float inpCoord, out float outCoord) 92{ 93 outCoord = fract(inpCoord); 94} 95 96//----------------------------------------------------------------------------- 97void SGX_Atlas_Clamp(in float inpCoord, out float outCoord) 98{ 99 outCoord = clamp(inpCoord, 0.0, 1.0); 100} 101//----------------------------------------------------------------------------- 102void SGX_Atlas_Mirror(in float inpCoord, out float outCoord) 103{ 104 outCoord = (inpCoord + 1) * 0.5; 105 outCoord = abs(fract(outCoord) * 2 - 1); 106} 107 108//----------------------------------------------------------------------------- 109void SGX_Atlas_Border(in float inpCoord, out float outCoord) 110{ 111 // 112 //The shader needs to check whether the original texcoord are beyond the 0,1 range. 113 //The shader attempts to do so without using if statments which are complicated for shaders 114 // 115 116 //if texcoord is in the 0,1 range then check will equal 0, 117 //Otherwise it will equal the number 1 or greater 118 float check = step(inpCoord, 0) + step(1, inpCoord); 119 120 //using the check value transport the value of the texcoord beyond the 0,1 range so it will 121 //recive the border color 122 outCoord = abs(inpCoord) + check * 2; 123} 124