struct v2f { float4 Position : POSITION; //in projection space float4 Color : COLOR; float4 TexCoords : TEXCOORD0; float4 Normal : TEXCOORD1; float Alpha : TEXCOORD2; }; float4 main(v2f IN, uniform sampler2D colourMap : TEXUNIT0) : COLOR { float textureScalingFactor = 20.0f; float textureSize = 512.0f; float noOfTexturesPerDimension = 4.0; //Scale the texture. IN.TexCoords /= textureScalingFactor; //Make sure texture coordinates are in the range 0.0 - 1.0 (or 0.9999? Is this necessary?) IN.TexCoords.x = frac(IN.TexCoords.x); IN.TexCoords.y = frac(IN.TexCoords.y); IN.TexCoords.z = frac(IN.TexCoords.z); //Avoid sampling the texels at the edge of each texture. To do this, compress the range of texture coordinates. //To work with mipmaping we can't use a constant addition of 0.5 - it needs to be dependant of mipmap level? IN.TexCoords *= (textureSize - 1.0); IN.TexCoords += 0.5f; IN.TexCoords /= textureSize; //Now scale the texture coordinates to the right range for the texture atlas. IN.TexCoords /= noOfTexturesPerDimension; //Next we compute the offset of the texture in the texture atlas float material = floor(IN.Alpha); float y = floor(material / noOfTexturesPerDimension); float x = fmod(material,noOfTexturesPerDimension); float2 offset = float2(x,y); offset /= noOfTexturesPerDimension; float3 colourMapValueXY = tex2D(colourMap, IN.TexCoords.xy + offset).rgb * abs(IN.Normal.z); float3 colourMapValueYZ = tex2D(colourMap, IN.TexCoords.yz + offset).rgb * abs(IN.Normal.x); float3 colourMapValueXZ = tex2D(colourMap, IN.TexCoords.xz + offset).rgb * abs(IN.Normal.y); float3 colourMapValue = colourMapValueXY + colourMapValueYZ + colourMapValueXZ; return float4(colourMapValue*IN.Color.rgb,1.0); } //Curently unused. This function mimics linear texture interpolation by taking several samples when in nearest neighbour sampling mode. float4 performInterpolatedTextureLookup(sampler2D texture, float2 pos) { float xPos = pos.x * 2048.0; float xFrac = frac(xPos); float xMin = xPos - xFrac; float xMax = xPos + 1.0; xMin /= 2048.0; xMax /= 2048.0; float yPos = pos.y* 2048.0; float yFrac = frac(yPos); float yMin = yPos - yFrac; float yMax = yPos + 1.0; yMin /= 2048.0; yMax /= 2048.0; float4 resultMinXMinY = tex2D(texture, float2(xMin, yMin)); float4 resultMaxXMinY = tex2D(texture, float2(xMax, yMin)); float4 resultMinXMaxY = tex2D(texture, float2(xMin, yMax)); float4 resultMaxXMaxY = tex2D(texture, float2(xMax, yMax)); float4 resultMinY = (resultMinXMinY * (1-xFrac) + resultMaxXMinY * xFrac); float4 resultMaxY = (resultMinXMaxY * (1-xFrac) + resultMaxXMaxY * xFrac); float4 result = (resultMinY * (1-yFrac) + resultMaxY * yFrac); return result; }