From 980b2d36642775c8565033447aa2ec4db20e9c05 Mon Sep 17 00:00:00 2001 From: David Williams Date: Sun, 13 Jan 2008 19:56:42 +0000 Subject: [PATCH] Created experimental texture atlas version for testing out ideas such as interpolation. Didn't simplify code yet as previously promised. Next task should probably be to simplify the code to remove unnecessary maps. --- ...TextureAtlasExperimentalFragmentProgram.cg | 82 +++++++++++++++++++ .../programs/TextureAtlasFragmentProgram.cg | 50 +++++------ media/materials/programs/Thermite.program | 7 ++ .../scripts/TextureAtlasExperimental.material | 28 +++++++ 4 files changed, 142 insertions(+), 25 deletions(-) create mode 100644 media/materials/programs/TextureAtlasExperimentalFragmentProgram.cg create mode 100644 media/materials/scripts/TextureAtlasExperimental.material diff --git a/media/materials/programs/TextureAtlasExperimentalFragmentProgram.cg b/media/materials/programs/TextureAtlasExperimentalFragmentProgram.cg new file mode 100644 index 00000000..75da1077 --- /dev/null +++ b/media/materials/programs/TextureAtlasExperimentalFragmentProgram.cg @@ -0,0 +1,82 @@ +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; +} \ No newline at end of file diff --git a/media/materials/programs/TextureAtlasFragmentProgram.cg b/media/materials/programs/TextureAtlasFragmentProgram.cg index 71a398d5..2daa61bc 100644 --- a/media/materials/programs/TextureAtlasFragmentProgram.cg +++ b/media/materials/programs/TextureAtlasFragmentProgram.cg @@ -9,36 +9,36 @@ struct v2f float4 main(v2f IN, uniform sampler2D colourMap : TEXUNIT0) : COLOR { - /*OUT.TexCoordsXY.xy = OUT.Position.xy; - OUT.TexCoordsYZ.xy = OUT.Position.yz; - OUT.TexCoordsXZ.xy = OUT.Position.xz;*/ - - /*OUT.TexCoordsXY.xy /= textureScale; - OUT.TexCoordsYZ.xy /= textureScale; - OUT.TexCoordsXZ.xy /= textureScale;*/ + float textureScalingFactor = 20.0f; + float textureSize = 512.0f; + float noOfTexturesPerDimension = 4.0; - IN.TexCoords /= 16; + //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); - IN.TexCoords /= 4.0; - float material = floor(IN.Alpha); - float y = floor(material / 4.0); - //float x = material - y; - float x = fmod(material,4.0); - //x = 1.0 - x; - float2 offset = float2(x,y); - offset /= 4.0; + //Now scale the texture coordinates to the right range for the texture atlas. + IN.TexCoords /= 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; - - //colourMapValue /= 3.0; + //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; + + //Retrieve the 3 samples + 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); - return float4(colourMapValue*IN.Color.rgb,1.0); - //return float4(1.0,0.0,0.0,1.0); + //Blend according to triplanar texturing + float3 colourMapValue = colourMapValueXY + colourMapValueYZ + colourMapValueXZ; + + //Return the result + return float4(colourMapValue*IN.Color.rgb,1.0); } \ No newline at end of file diff --git a/media/materials/programs/Thermite.program b/media/materials/programs/Thermite.program index 7e92a559..938f190d 100644 --- a/media/materials/programs/Thermite.program +++ b/media/materials/programs/Thermite.program @@ -87,4 +87,11 @@ fragment_program TextureAtlasFragmentProgram cg source TextureAtlasFragmentProgram.cg entry_point main profiles ps_1_1 arbfp1 +} + +fragment_program TextureAtlasExperimentalFragmentProgram cg +{ + source TextureAtlasExperimentalFragmentProgram.cg + entry_point main + profiles ps_1_1 arbfp1 } \ No newline at end of file diff --git a/media/materials/scripts/TextureAtlasExperimental.material b/media/materials/scripts/TextureAtlasExperimental.material new file mode 100644 index 00000000..9360286f --- /dev/null +++ b/media/materials/scripts/TextureAtlasExperimental.material @@ -0,0 +1,28 @@ +material TextureAtlasExperimentalMaterial +{ + technique + { + pass + { + vertex_program_ref TextureAtlasOneLightVertexProgram + { + param_named_auto world world_matrix + param_named_auto viewProj viewproj_matrix + param_named_auto ambient ambient_light_colour + param_named_auto light0.position light_position 0 + param_named_auto light0.diffuseColour light_diffuse_colour 0 + param_named_auto light0.attenuation light_attenuation 0 + } + + fragment_program_ref TextureAtlasExperimentalFragmentProgram + { + } + + texture_unit + { + texture texture_atlas.png 2d 0 + //filtering none + } + } + } +}