It is currently Sat Aug 22, 2020 3:36 am


All times are UTC




Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Sun Apr 24, 2011 7:31 am 

Joined: Fri Feb 18, 2011 8:41 pm
Posts: 173
My latest views on the subject:
viewtopic.php?p=1642#p1642


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Tue Oct 11, 2011 6:48 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
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
         }
      }
   }
}




ImageImageImageImage
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 :lol:


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Tue Oct 11, 2011 10:10 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
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


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Tue Oct 11, 2011 9:46 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
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.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Wed Oct 12, 2011 4:17 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
Actually I was referring to his post on the first page of this thread, but thanks for the pointer! I'll try that tex2dgrad and see if that looks better. Here's how it's looking now.

Image

The textures I currently have don't tile very well, but considering before any of this everything was untextured and green, I'm happy :D.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Thu Oct 13, 2011 6:21 pm 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
edit2: Of course, 30 seconds after I edited this, I uncommented the +vec4(0.5, 0.5,0.5,0.5) in the vertex program and it all lines up perfectly.

Image



edit: Updated code, it's working a lot better. However, with the current state it starts in the center of the face instead of on the corners. When I figure it out, I'll update this post again.
Image the corner is a single cube.

/*
I'm hoping you might be able to help me here.. Cg wasn't performing very well on my other test computers(at all actually), so I've been trying to convert it all to GLSL.. I got it to partly work, except well.. the screen shot says it all.
Image

Note: If I switch the if(normal.xyz >< .5) to if/else's it will switch the faces that are drawn correctly. I've been screwing with it for hours trying to get it "right(tm)". I'm guessing the line worldPosition = gl_Vertex + vec4( 0.5, 0.5, 0.5, 0.5); has something to do with it, but I don't know for sure.
*/ -- I didn't catch it should have been if(worldNormal.xyz < -0.5), not < 0.5. I don't know how the -'s where thrown out.

Here is the codes (First passed through cgc, then hand edited to look like the old shader)

Vertex Program: (EDIT: FIXED)
Code:

float ATLAS_WIDTH = 4096.0;
float TEXTURE_WIDTH = 256.0;
float RATIO =  TEXTURE_WIDTH / ATLAS_WIDTH;
float NUM_TEXTURES_IN_ATLAS = (ATLAS_WIDTH / TEXTURE_WIDTH);
//vec4 _clipPosition1;

uniform mat4x4 worldMatrix;
uniform mat4x4 viewProj;

varying out vec4 textureAtlasOffset;
varying out vec3 worldPosition;

void main()
{
   
    float idx;
    float blocky;
    float blockx;
    //vec4 tmp = worldMatrix * gl_Vertex;
    worldPosition = gl_Vertex + vec4( 0.5, 0.5, 0.5, 0.5);

    idx = gl_Color.x* NUM_TEXTURES_IN_ATLAS;
    blocky = floor(idx/NUM_TEXTURES_IN_ATLAS);
    blockx = idx - blocky*NUM_TEXTURES_IN_ATLAS;
    textureAtlasOffset = vec4(blockx + 0.25, blocky + 0.25, 0.0, 0.0)*RATIO;

    gl_Position = ftransform();
} // main end



Fragment:
Code:
float ATLAS_WIDTH = 4096.0;
float TEXTURE_WIDTH = 256.0;
float RATIO =  TEXTURE_WIDTH / ATLAS_WIDTH;

uniform sampler2D Atlas;
varying in vec4 textureAtlasOffset;
varying in vec3 worldPosition;

//varying in vec3 normal;
void main()
{
   
    vec2 uv;
    vec3 wp = worldPosition;
    // ddx then ddy gives back positive normals for all the positive faces
    vec3   worldNormal = cross(dFdy(wp.xyz), dFdx(wp.xyz));
    worldNormal = normalize(worldNormal);
    uv = vec2( 1.0, 1.0);
    if (worldNormal.x > 0.5)
        uv = fract(vec2(-wp.z, -wp.y));
    if (worldNormal.x < -0.5)
        uv = fract(vec2(-wp.z, wp.y));
    if (worldNormal.y > 0.5)
        uv = fract(wp.xz);
    if (worldNormal.y < -0.5)
        uv = fract(vec2(-wp.x, wp.z));
    if (worldNormal.z > 0.5)
        uv = fract(vec2(wp.x, -wp.y));
    if (worldNormal.z < -0.5)
        uv = fract(vec2(-wp.x, -wp.y));

    uv = uv*0.5;
    vec4 voff = textureAtlasOffset + vec4(uv.x, uv.y, 0.0,0.0)*RATIO;
    gl_FragColor = texture2D(Atlas, voff.xy);
   
    return;
}



Material
Code:
vertex_program VoxelTexture_VP glsl
{
   source VoxelTexture.glslv
   entry_point main
   profiles arbvp1
   default_params
    {
        param_named_auto worldMatrix world_matrix
        param_named_auto viewProj viewproj_matrix
    }
}

fragment_program VoxelTexture_FP glsl
{
   source VoxelTexture.glslf
   entry_point main
   profiles arbfp1
}

material VoxelTexture
{
   receive_shadows on
   technique
   {
      pass
      {
         vertex_program_ref VoxelTexture_VP
         {
      
         }
         
         fragment_program_ref VoxelTexture_FP
         {
      param_named Atlas int 0
      
         }
         
         texture_unit
         {
            texture TextureAtlas.dds 2d
            filtering linear linear linear
            max_anisotropy 4
            tex_address_mode wrap
         }
      }
   }
}




Last edited by 0xDeadC0de on Fri Oct 14, 2011 8:29 am, edited 2 times in total.

Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Thu Oct 13, 2011 9:05 pm 
Developer
User avatar

Joined: Sun May 04, 2008 6:35 pm
Posts: 1827
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.


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Fri Oct 14, 2011 3:23 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
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 :). Thanks for the tip!


Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Fri Oct 14, 2011 3:45 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
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));


Last edited by 0xDeadC0de on Fri Oct 14, 2011 8:23 am, edited 1 time in total.

Top
Offline Profile  
Reply with quote  
 Post subject: Re: Texture atlases, bleeding, mipmaps & filtering
PostPosted: Fri Oct 14, 2011 6:37 am 

Joined: Fri Oct 07, 2011 11:53 pm
Posts: 7
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.


Top
Offline Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 23 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Theme created StylerBB.net