Volumes Of Fun http://www.volumesoffun.com/phpBB3/ |
|
Texture atlases, bleeding, mipmaps & filtering http://www.volumesoffun.com/phpBB3/viewtopic.php?f=2&t=152 |
Page 2 of 3 |
Author: | Shanee [ Sun Apr 24, 2011 7:31 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
My latest views on the subject: viewtopic.php?p=1642#p1642 |
Author: | 0xDeadC0de [ Tue Oct 11, 2011 6:48 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
I'm building my own little "cube voxel" toy, in an attempt to figure it all out. When I went researching how I should go about texturing everything once it all worked I came here and found these threads. I had to fix a few things in the way I generated my cubes(from a heightmap image). Their size was one big problem, I was using an offset of 8 from the center point for each vertex, but that ended up creating a bunch of fragments -so each time the shader ran on each fragment it would tile the image all over the place. Changing the offset to .5 seems to have worked, and made all the cubes a lot smaller of course. I had bleeding issues with a .png atlas, so I went and got nvidias legacy atlas creator tool, which runs just fine via wine. It generated a nice .dds that was 4096x256 from the textures I resized. so the code to generate the color value only needs to offset the r, instead of both the r and g. However, though it looks much better now, the 6 texture according to the NvidiaComparisonViewer should be an ice texture, and grass is the texture 3 (assuming the first texture is 0). oh hand of course, if I change the matid it falls apart. Code: int matid = 6;// pick the 6th texture float texture_count = 16; colours = new Ogre::RGBA[nVertices]; { Ogre::RGBA *pColour = colours; for(size_t l = 0; l<nVertices;l++) { rs->convertColourValue(Ogre::ColourValue(matid%texture_count*(1.0/texture_count), 0,0.0,1.0f), pColour++); } } Then I used the last shader jmgr posted with only a few small changes: Code: #define ATLAS_WIDTH 4096.0 #define TEXTURE_WIDTH 256.0 #define RATIO TEXTURE_WIDTH / ATLAS_WIDTH void voxeltexture_vp( float4 position : POSITION, float4 tile : COLOR, out float4 clipPosition : POSITION, out float4 worldPosition : TEXCOORD0, out float4 textureAtlasOffset : TEXCOORD1, uniform float4x4 world, uniform float4x4 viewProj) { worldPosition = mul(world, position); clipPosition = mul(viewProj, worldPosition); float tileX = ((tile.r != 0.0) ? (1.0 / tile.r) : 0.0); textureAtlasOffset = float4(tileX + 0.5f, 0, 0, 0) * RATIO; } void voxeltexture_fp( float4 position : POSITION, float4 worldPosition : TEXCOORD0, float4 textureAtlasOffset : TEXCOORD1, uniform sampler2D texture : TEXUNIT0, out float4 result : COLOR) { float3 worldNormal = cross(ddy(worldPosition.xyz),ddx(worldPosition.xyz)); worldNormal = normalize(worldNormal); worldPosition -= 0.5; float2 uv = float2(1.0, 1.0); if(worldNormal.x > 0.5) uv = frac(float2(-worldPosition.z, -worldPosition.y)); if(worldNormal.x < -0.5) uv = frac(float2(-worldPosition.z, worldPosition.y)); if(worldNormal.y > 0.5) uv = frac(worldPosition.xz); if(worldNormal.y < -0.5) uv = frac(float2(-worldPosition.x, worldPosition.z)); if(worldNormal.z > 0.5) uv = frac(float2(worldPosition.x, -worldPosition.y)); if(worldNormal.z < -0.5) uv = frac(float2(-worldPosition.x,-worldPosition.y)); textureAtlasOffset += float4(uv * 0.5, 0.0, 0.0) * RATIO; result = tex2D(texture, textureAtlasOffset.xy); } and my material file Code: vertex_program VoxelTexture_VP cg { source VoxelTexture.cg entry_point voxeltexture_vp profiles vs_3_0 vs_2_x vs_2_0 vs_1_1 vp40 vp30 vp20 arbvp1 glsl default_params { param_named_auto world world_matrix param_named_auto viewProj viewproj_matrix } } fragment_program VoxelTexture_FP cg { source VoxelTexture.cg entry_point voxeltexture_fp profiles ps_3_x ps_3_0 ps_2_x ps_2_0 ps_1_4 ps_1_3 ps_1_2 ps_1_1 fp40 fp30 fp20 arbfp1 glsl } material VoxelTexture { receive_shadows on technique { pass { vertex_program_ref VoxelTexture_VP { } fragment_program_ref VoxelTexture_FP { } texture_unit { texture TextureAtlas.dds 2d filtering point point point tex_address_mode wrap } } } } ![]() ![]() ![]() ![]() Uploaded with ImageShack.us this is my first time playing with Cg, so I'm learning a lot from this whole experience, thank heavens for The Cg Tutorial or I'd be completely lost.. now I'm lost with a giant complex map ![]() |
Author: | 0xDeadC0de [ Tue Oct 11, 2011 10:10 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
changing the color value to (matid/num_rows), and changing the vert program to a derivative based on what beyzend posted seemed to have solved most if not all the issues I had Code: rs->convertColourValue(Ogre::ColourValue(((matid)/16.0), 0,0.0,1.0f), pColour++); and Code: #define ATLAS_WIDTH 4096.0 #define TEXTURE_WIDTH 256.0 #define RATIO TEXTURE_WIDTH / ATLAS_WIDTH #define NUM_TEXTURES_IN_ATLAS 16.0 void voxeltexture_vp( float4 position : POSITION, float4 tile : COLOR, out float4 clipPosition : POSITION, out float4 worldPosition : TEXCOORD0, out float4 textureAtlasOffset : TEXCOORD1, uniform float4x4 world, uniform float4x4 viewProj) { worldPosition = position + float4(0.5f, 0.5f, 0.5f, 0.5f);//mul(world, position); clipPosition = mul(viewProj, mul(world,position)); float idx = ((tile.r)) * NUM_TEXTURES_IN_ATLAS;//TEXTURE_WIDTH - 1; float blocky = floor(idx / NUM_TEXTURES_IN_ATLAS); float blockx = (idx - blocky * NUM_TEXTURES_IN_ATLAS); //float tileX = ((tile.r != 0.0) ? (1.0 / tile.r) : 0.0); textureAtlasOffset = float4(blockx +0.25f, blocky + 0.25f, 0, 0) * RATIO; } edit: I also commented out worldPosition -= 0.5; in the fragment shader |
Author: | David Williams [ Tue Oct 11, 2011 9:46 pm ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
Looks good... it's always the case that you have to adjust shader code to move it between projects but you seem to have got it working. You mentioned beyzend's post, were you referring to this one? It might be worth checking if you didn't see it yet, though it's only necessary if you want filtering on your textures. |
Author: | David Williams [ Thu Oct 13, 2011 9:05 pm ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
I think you should first vertify whether your normals are correct, as these are used when computing the UVs. You could try outputting the normal as a colour - something like this: Code: gl_FragColor = worldNormal.xyz; return; You should then get one red face, one green, one blue, and three black. Think about which are coloured and which are black... does the normal point in the right direction? When using Cg, I found that changing between OprnGL and Direct3D would cause the computed normal to flip as they use differnt coordinate systems. Assuming that is all fine, you should comment out five of your six if statements and get each face working one at a time. Try flipping the components, swapping x for y or z, etc. Cutting it down is always the best way to get shaders working. |
Author: | 0xDeadC0de [ Fri Oct 14, 2011 3:23 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
I'm getting the +y face as green, +x blue, +z black, -x black, -z red, -y black. I'll keep tinkering, if I get it working i will post the results, of course ![]() |
Author: | 0xDeadC0de [ Fri Oct 14, 2011 3:45 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
Well, I went through and added more checks in all the if's, now the only faces still rendering like the image above are -x and -y. Closer, yay. Code: this was just a bad idea. The fix is above. ( < -0.5 not < 0.5)
if (worldNormal.x > 0.5) uv = fract(vec2(-wp.z, -wp.y)); else if (worldNormal.x < 0.5 && !(worldNormal.y > 0.5) && !(worldNormal.z > 0.5)) uv = fract(vec2(-wp.z, wp.y)); else if (worldNormal.y > 0.5) uv = fract(wp.xz); else if (worldNormal.y < 0.5 && worldNormal.z < 0.5) uv = fract(vec2(-wp.x, wp.z)); else if (worldNormal.z > 0.5 ) uv = fract(vec2(+wp.x, -wp.y)); else uv = fract(vec2(-wp.x, -wp.y)); |
Author: | 0xDeadC0de [ Fri Oct 14, 2011 6:37 am ] |
Post subject: | Re: Texture atlases, bleeding, mipmaps & filtering |
Thanks again for the tips, and your patience ![]() EDIT: Removed old code. I can't believe I didn't notice I missed the -'s. :facepalm: < -0.5 not < 0.5.. I'll fix the old post. |
Page 2 of 3 | All times are UTC |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |