Jump to content

Shader Texture Atlas Support


MackeyK24
 Share

Recommended Posts

I am trying to get Terrain Splatmap support into the toolkit. So a terrain built with up to 12 separate textures with the 12 matching normal maps (if using bumping).

Now including the up to 4 actual splatmaps or alphamaps used to 'SPLAT' the textures onto the terrain thats a total of 28 additional textures (besides any lightmap of reflection textures) needed to create a max detailed terrain. Thats way too many textures for WebGL. My browser only supports a max use of 16 textures at once even if in a textureArray. IPHONES only support 8 textures at once... GLSL MAX_TEXTURE_IMAGE_UNITS.

So I created a Texture Atlas system in Babylon Toolkit (I also use this for my Texture Atlas Baking Tools) to pack textures into a texture atlas and return an array of UV coordinates rectangle structs for each tile or cell in the texture atlas. Example atlasRect Array, atlasInfo Array And The textureAtlas image:

        "atlasRect1": [
          0.0,
          0.0,
          0.5,
          0.25
        ],
        "atlasRect2": [
          0.0,
          0.5,
          0.5,
          0.25
        ],
        "atlasRect3": [
          0.25,
          0.0,
          0.5,
          0.25
        ],
        "atlasRect4": [
          0.25,
          0.5,
          0.5,
          0.25
        ],
        "atlasRect5": [
          0.5,
          0.0,
          0.5,
          0.25
        ],
        "atlasRect6": [
          0.75,
          0.0,
          0.5,
          0.25
        ],
        "atlasRect7": [
          0.5,
          0.5,
          0.5,
          0.25
        ],

The matching atlasInfo array contains the texture tile or cell information (uScale, vScale, uOffset, vOffset):

       "atlasInfo1": [
          80.0,
          80.0,
          0.0,
          0.0
        ],
        "atlasInfo2": [
          100.0,
          100.0,
          0.0,
          0.0
        ],
        "atlasInfo3": [
          80.0,
          80.0,
          0.0,
          0.0
        ],
        "atlasInfo4": [
          80.0,
          80.0,
          0.0,
          0.0
        ],
        "atlasInfo5": [
          100.0,
          100.0,
          0.0,
          0.0
        ],
        "atlasInfo6": [
          80.0,
          80.0,
          0.0,
          0.0
        ],
        "atlasInfo7": [
          80.0,
          80.0,
          0.0,
          0.0
        ],

The texture atlas image I create, Note the first tile or cell is the bottom left:

Terrain_Candyland_Terrain_Atlas.thumb.jpg.c6783ceba4795fc2dc4fb4303aaabe99.jpg

I dont know all the ins and outs of what to multiply by what to get the desired effect.

Now I need to get the tile or cell from texture atlas and use atlasInfo.xy (uScale and vScale):

Here are my main two functions I added to shader:

vec4 textureAtlas2D(sampler2D atlas, vec4 rect, vec2 uv, vec2 offset) {
	vec2 atlasUV = vec2((uv.x * rect.w) + rect.x, (uv.y * rect.z) + rect.y);
	return texture2D(atlas, atlasUV + offset);
}

vec4 textureFract2D(sampler2D atlas, vec4 rect, vec2 scale, vec2 uv, vec2 offset) {
	vec2 fractUV = fract(uv * scale);
	return textureAtlas2D(atlas, rect, fractUV, offset);
}

textureAtlas2D uses the rectangle that holds the UV Coords from above to just get the 'Desired Cell'. This works great... EXCEPT IS DOES NOT SCALE ... The ONLY code I could find after months of goggle search of GLSL Texture Atlas Tiling (or Scaling) was to use the GLSL fract() function to REPEAT into the texture atlas giving you scale. So I created textureFract2D as a wrapper to incorporate 'uvScale'. Example snippet from my splatmap  shader call texture atlas functions:

#ifdef DIFFUSE
// Splatmaps
#ifdef splatmapDef
vec4 splatColor = vec4(0.0, 0.0, 0.0, 0.0);
vec4 baseColor1 = vec4(0.0, 0.0, 0.0, 0.0);
vec4 baseColor2 = vec4(0.0, 0.0, 0.0, 0.0);
vec4 baseColor3 = vec4(0.0, 0.0, 0.0, 0.0);
vec4 baseColor4 = vec4(0.0, 0.0, 0.0, 0.0);

// Base splat colors (No Texture Tiling)
if (splatmapRects > 0.0) {
    baseColor1 = textureAtlas2D(splatmap, splatmapRect1, vTerrainUV, uvOffset);
}
if (splatmapRects > 1.0) {
    baseColor2 = textureAtlas2D(splatmap, splatmapRect2, vTerrainUV, uvOffset);
}
if (splatmapRects > 2.0) {
    baseColor3 = textureAtlas2D(splatmap, splatmapRect3, vTerrainUV, uvOffset);
}
if (splatmapRects > 3.0) {
    baseColor4 = textureAtlas2D(splatmap, splatmapRect4, vTerrainUV, uvOffset);
}
// Texture atlas colors (Use Texture Tiling)
if (atlasInfos > 0.0 && atlasRects > 0.0) {
splatColor = textureFract2D(diffuseSampler, atlasRect1, atlasInfo1.xy, vTerrainUV, uvOffset) * baseColor1.r;
if (atlasInfos > 1.0 && atlasRects > 1.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect2, atlasInfo2.xy, vTerrainUV, uvOffset) * baseColor1.g;
}
if (atlasInfos > 2.0 && atlasRects > 2.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect3, atlasInfo3.xy, vTerrainUV, uvOffset) * baseColor1.b;
}
// Second splat colors
if (atlasInfos > 3.0 && atlasRects > 3.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect4, atlasInfo4.xy, vTerrainUV, uvOffset) * baseColor2.r;
}
if (atlasInfos > 4.0 && atlasRects > 4.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect5, atlasInfo5.xy, vTerrainUV, uvOffset) * baseColor2.g;
}
if (atlasInfos > 5.0 && atlasRects > 5.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect6, atlasInfo6.xy, vTerrainUV, uvOffset) * baseColor2.b;
}
// Third splat colors
if (atlasInfos > 6.0 && atlasRects > 6.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect7, atlasInfo7.xy, vTerrainUV, uvOffset) * baseColor3.r;
}
if (atlasInfos > 7.0 && atlasRects > 7.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect8, atlasInfo8.xy, vTerrainUV, uvOffset) * baseColor3.g;
}
if (atlasInfos > 8.0 && atlasRects > 8.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect9, atlasInfo9.xy, vTerrainUV, uvOffset) * baseColor3.b;
}
// Final splat colors
if (atlasInfos > 9.0 && atlasRects > 9.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect10, atlasInfo10.xy, vTerrainUV, uvOffset) * baseColor4.r;
}
if (atlasInfos > 10.0 && atlasRects > 10.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect11, atlasInfo11.xy, vTerrainUV, uvOffset) * baseColor4.g;
}
if (atlasInfos > 11.0 && atlasRects > 11.0) {
    splatColor += textureFract2D(diffuseSampler, atlasRect12, atlasInfo12.xy, vTerrainUV, uvOffset) * baseColor4.b;
}
}
baseColor = splatColor;
#else
baseColor = texture2D(diffuseSampler, vDiffuseUV + uvOffset);
#endif

#ifdef ALPHATEST
if (baseColor.a < 0.4)å
    discard;
#endif

#ifdef ALPHAFROMDIFFUSE
alpha *= baseColor.a;
#endif

baseColor.rgb *= vDiffuseInfos.y;

#ifdef splatmapDef
#ifdef BUMP
//normalW = perturbNormals(viewDirectionW, baseColor1, baseColor2, baseColor3, baseColor4, uvOffset, atlas1UV, atlas2UV, atlas3UV, atlas4UV, atlas5UV, atlas6UV, atlas7UV, atlas8UV, atlas9UV, atlas10UV, atlas11UV, atlas12UV);
#endif

#ifdef TWOSIDEDLIGHTING
normalW = gl_FrontFacing ? normalW : -normalW;
#endif
#endif

#endif

My problem is I dont know how to grab the cell info using the UV coords and apply the scaling needed. If I use the textureFract2D GLSL fract to do the scaling I get edge seams (I will post screen shots in the next post).

@Deltakosh pointed me the particleSystem direction because I guess it does something like using SPRITESHEET and what they ar calling a 'cellIndex' to get to the tile or cell. Now there is a bunch of code that deals with sprite sheet width and some calculations to get a rowOffset and columnOffset. Well I dont have that kind of info, but like I explained above, I have the ACTUAL UV COORDS for each tile or cell in the texture atlas. But I am STILLL GAME DEV NEWBIE, I dont know what I need to do to use those UV coords and info.xy (uScale, vScale) to get the desired effect. This is the gist of what the particle system does for texture atlas or sprite sheet support:

        //vec2 offset = options.zw;     // Dunno what this is - ???
        //attribute float cellIndex;    // Dunno what this is - ???
        //uniform vec3 particlesInfos;  // x (number of rows) y(number of columns) z(rowSize)

        //#ifdef ANIMATESHEET
        //float rowOffset = floor(cellIndex / particlesInfos.z);
        //float columnOffset = cellIndex - rowOffset * particlesInfos.z;

        //vec2 uvScale = particlesInfos.xy;
        //vec2 uvOffset = vec2(offset.x , 1.0 - offset.y);
        //vUV = (uvOffset + vec2(columnOffset, rowOffset)) * uvScale;
        //#else
        //vUV = offset;
        //#endif

I have no idea how to take this and adapt this to using the actual UV coords WITH SCALE.

PLEASE, ANYBODY, I AM BEGGING (AGAIN)... HELP ME RE-WRITE textureFract2D to get the desired effect :(

Here is my shader programs so far:

splatmap.vertex.fx

splatmap.fragment.fx

UPDATE

You can download the Test Terrain export project and edit the shader in the src/shader folder directly and just hit refresh on your browser to see effect

Look at next post for example screen shots ...

THANKS FOR READING THIS FAR :)

Pinging @Deltakosh and @Sebavan and @Pryme8 and @adam and last but not least my man 'Wingy' at @Wingnut ... Any thought Guys ???

Yo @NasimiAsl ... The Shader Guru ... Maybe you can have another crack at it, but this time use the Test Terrain project from above and change the splatmap shader and hit refresh... Even better than play ground, you get the whole export project... easy access :)

 

Link to comment
Share on other sites

16 minutes ago, Pryme8 said:

what is your sampling mode?

Set it to nearest, and see if that fixes the seams. Also turn of Mips for now.

Yo @Pryme8 ... I dont know how to turn off mips... When using the Babylon.Entities to serialize the texture, this is how I create the BabylonTexture in C# then its serialized into json:

Note this is texture atlas containing all the cells:

babylonTerrainMaterial.diffuseTexture = new BabylonTexture { name = atlasLabel, samplingMode = BabylonTexture.SamplingMode.NEAREST_NEAREST_MIPLINEAR };

babylonTerrainMaterial.diffuseTexture.uScale = 1;
babylonTerrainMaterial.diffuseTexture.vScale = 1;
babylonTerrainMaterial.diffuseTexture.uOffset = 0;
babylonTerrainMaterial.diffuseTexture.vOffset = 0;

I also tried NOT specifying the samplingMode (what is the default ???)

 What do you mean 'nearest' there are MANY nearest enums... 

BabylonTexture.SamplingMode.NEAREST_NEAREST

Is that all you need to do for sampleMode just set it on the babylon texture ?

How do you turn off mips?

 

Link to comment
Share on other sites

new Texture(url, scene, noMipmap, invertY, samplingMode, onLoad, onError, buffer, deleteBuffer, format);
and 
 NEAREST_SAMPLINGMODE
so:

 new BABYLON.Texture(url, scene, true, false, 1);

or using your method I would assume:
new BabylonTexture { name = atlasLabel, noMipmap = true,  samplingMode = BabylonTexture.SamplingMode.NEAREST_SAMPLINGMODE}


I am saying to make these changes just to see how it effects the tiling for the moment.  Ideally there would be 'padding' between each texture that we could sample but that's a different method and takes a little more scripting.  Once I see how this effects the results I can help more.

Link to comment
Share on other sites

The babylon entities does not have NEAREST_SAMPLINGMODE... But I added it... It was using NEAREST_NEAREST_MIPLINEAR which BOTH = 1;

FYI

public enum SamplingMode
{
 NEAREST_SAMPLINGMODE = 1,
 // Constants
 NEAREST_NEAREST_MIPLINEAR = 1, // nearest is mag = nearest and min = nearest and mip = linear
 LINEAR_LINEAR_MIPNEAREST = 2, // Bilinear is mag = linear and min = linear and mip = nearest
 LINEAR_LINEAR_MIPLINEAR = 3, // Trilinear is mag = linear and min = linear and mip = linear
 NEAREST_NEAREST_MIPNEAREST = 4,
 NEAREST_LINEAR_MIPNEAREST = 5,
 NEAREST_LINEAR_MIPLINEAR = 6,
 NEAREST_LINEAR = 7,
 NEAREST_NEAREST = 8,
 LINEAR_NEAREST_MIPNEAREST = 9,
 LINEAR_NEAREST_MIPLINEAR = 10,
 LINEAR_LINEAR = 11,
 LINEAR_NEAREST = 12
}

So the sampling mode was always 1

I will need to modify the babylon engine to support 'noMipmap' as part of th 'parsedTexture' options BUT it has to be used at construction  because it private _noMipMap so cannot set anywhere but construction... But not sure best place to do so

Apparently you CAN NOT set noMipmode from the Texture json... This is a problem ... Everything is serialized into the scene json none of the textures are created at runtime with code. The toolkits primary focus is to serialize native babylon scene files.

I looked at babylonTexture.ts - Parse Function ... I am not sure where to add support for 'parsedTexture.noMipmap' because of the customType parsing option at top... Could you please modify this Parse function to support 'parsedTexture.noMipmap':

public static Parse(parsedTexture: any, scene: Scene, rootUrl: string): Nullable<BaseTexture> {
            if (parsedTexture.customType) {
                var customTexture = Tools.Instantiate(parsedTexture.customType);
                // Update Sampling Mode
                var parsedCustomTexture: any = customTexture.Parse(parsedTexture, scene, rootUrl);
                if (parsedTexture.samplingMode && parsedCustomTexture.updateSamplingMode && parsedCustomTexture._samplingMode) {
                    if (parsedCustomTexture._samplingMode !== parsedTexture.samplingMode) {
                        parsedCustomTexture.updateSamplingMode(parsedTexture.samplingMode);
                    }
                }
                return parsedCustomTexture;
            }

            if (parsedTexture.isCube) {
                return CubeTexture.Parse(parsedTexture, scene, rootUrl);
            }

            if (!parsedTexture.name && !parsedTexture.isRenderTarget) {
                return null;
            }

            var texture = SerializationHelper.Parse(() => {
                if (parsedTexture.mirrorPlane) {
                    var mirrorTexture = new MirrorTexture(parsedTexture.name, parsedTexture.renderTargetSize, scene);
                    mirrorTexture._waitingRenderList = parsedTexture.renderList;
                    mirrorTexture.mirrorPlane = Plane.FromArray(parsedTexture.mirrorPlane);

                    return mirrorTexture;
                } else if (parsedTexture.isRenderTarget) {
                    var renderTargetTexture = new RenderTargetTexture(parsedTexture.name, parsedTexture.renderTargetSize, scene);
                    renderTargetTexture._waitingRenderList = parsedTexture.renderList;

                    return renderTargetTexture;
                } else {
                    var texture: Texture;
                    if (parsedTexture.base64String) {
                        texture = Texture.CreateFromBase64String(parsedTexture.base64String, parsedTexture.name, scene);
                    } else {
                        texture = new Texture(rootUrl + parsedTexture.name, scene);
                    }

                    return texture;
                }
            }, parsedTexture, scene);

            // Update Sampling Mode
            if (parsedTexture.samplingMode) {
                var sampling: number = parsedTexture.samplingMode;
                if (texture._samplingMode !== sampling) {
                    texture.updateSamplingMode(sampling);
                }
            }

            // Animations
            if (parsedTexture.animations) {
                for (var animationIndex = 0; animationIndex < parsedTexture.animations.length; animationIndex++) {
                    var parsedAnimation = parsedTexture.animations[animationIndex];

                    texture.animations.push(Animation.Parse(parsedAnimation));
                }
            }

            return texture;
        }

 

Thanks Bro :)

 

Link to comment
Share on other sites

36 minutes ago, Pryme8 said:

new Texture(url, scene, noMipmap, invertY, samplingMode, onLoad, onError, buffer, deleteBuffer, format);
and 
 NEAREST_SAMPLINGMODE
so:

 new BABYLON.Texture(url, scene, true, false, 1);

or using your method I would assume:
new BabylonTexture { name = atlasLabel, noMipmap = true,  samplingMode = BabylonTexture.SamplingMode.NEAREST_SAMPLINGMODE}


I am saying to make these changes just to see how it effects the tiling for the moment.  Ideally there would be 'padding' between each texture that we could sample but that's a different method and takes a little more scripting.  Once I see how this effects the results I can help more.

Yo @Pryme8 ... I also have an 'Extrude' function I was using for debugging to give the texture a little padding... I was putting a solid green color as the padding to see the seam was because pixels on edge are different... but giving it a little padding and making all the padding the SAME COLOR would get rid of SEAMS... of course all the borders would be green, BUT NO SEAMS in the green border... I can do that again if like to try that... But I would have to modify engine to support noMipmap in parsing code first.

Can you take a look at the best place to do that in babylonTexture.ts - Static Parse function ???

Link to comment
Share on other sites

Yo @Pryme8 I made this change to Parse code to support noMipmap json option:

var nomipmap: boolean = false;
if (parsedTexture.noMipmap) {
    nomipmap = true;
}
var texture: Texture;
if (parsedTexture.base64String) {
   texture = Texture.CreateFromBase64String(parsedTexture.base64String, parsedTexture.name, scene, nomipmap);
} else {
   texture = new Texture(rootUrl + parsedTexture.name, scene, nomipmap);
}

Was always using sampling mode 1... But with noMipmap = true I get this:

5a0f362504507_ScreenShot2017-11-17at9_15_53AM.thumb.png.7b42cc98cdf83b97c4b36d68f98c9c27.png

 

NO EDGE SEAMS... But very sharp... Looking better... does that help ???

 

 

Link to comment
Share on other sites

4 minutes ago, Pryme8 said:

did you try: "new BabylonTexture { name = atlasLabel, noMipmap = true,  samplingMode = BabylonTexture.SamplingMode.NEAREST_SAMPLINGMODE}"

Yo @Pryme8 ... Yep... But Babylon.Entities do no support noMapmip.... And I had to add it to the babylonTexture.ts and babylon.entities

But after I did all that ... No edge seams... look above :)

So it seems to be something with mipmaps and edge seams , right ?

 

Link to comment
Share on other sites

So I think we fixed it then right?

Your Other Option is to generate mips but set the sampling mode to do NEAREST_NEAREST_MIPLINEAR and if that sample mode does not work, try the others that include Mip sampling and Nearest until you get the look your going for, but that is if you need the mipmaps (which is pretty default to include) 
 

Link to comment
Share on other sites

1 minute ago, Pryme8 said:

So I think we fixed it then right?

Your Other Option is to generate mips but set the sampling mode to do NEAREST_NEAREST_MIPLINEAR and if that sample mode does not work, try the others that include Mip sampling and Nearest until you get the look your going for.
 

NEAREST_NEAREST_MIPLINEAR and NEAREST_SAMPLINGMODE are BOTH equal to 1 ... I Will try other sampling modes as well... Do ou suggest one over the other?

Link to comment
Share on other sites

2 minutes ago, Pryme8 said:

https://en.wikipedia.org/wiki/Texture_filtering

Depends on if you are generating the mipmaps or not.  I was looking for this one article I had seen that explained all the sample modes and where they sample from, but I cant seem to find it right now.

What do you mean 'Generate The Mipmaps' ... Am I supposed to be doing something with the the ACTUAL pixels thats get encoded to png... 

And use that as the texture atlas tiles that I pack into one final texture atlas... I dont get part... Generate mipmaps myself... What that about ???

Link to comment
Share on other sites

Yo @Pryme8 .. So am I getting the edge seams because it thinks or wants mipmaps (because of noMipmap default false) and I am supposed be doing something to physically 'generate these mipmaps' and I am not... So the edge seams shows because the other mipmaps DONT exist...

When I say noMipmap = true it is always using main mipmap 0 so LOOKS VERY SHARP

Is that correct ??? 

Link to comment
Share on other sites

https://faculty.kaust.edu.sa/sites/markushadwiger/Documents/CS380_spring2015_lecture_12.pdf#page=4

ok what mipMaps are is basically an octree representation of the texture embeded into to memory.
so it turns the texture into something like this:
th.jpg.de34254014b0c023a1ee6e98d37639a2.jpg

This is for performance/bottle necking there is no reason to display or calculate the full texture if its way far away basically.  The system handles this on its own, and is a part of just the gl pipeline.

When you do not generate mips it keeps the texture as is no matter what the LOD step is. Which can create artifacts and is not the most efficient, but is the simplest to wrap your head around.

Now the sampling modes will need to change only if you generate mips this is because when it samples if it does nearest it will mess things up as the LOD level changes because you will want to sample from the same mip region as the the texture LOD.
 

Link to comment
Share on other sites

2 minutes ago, Pryme8 said:

https://faculty.kaust.edu.sa/sites/markushadwiger/Documents/CS380_spring2015_lecture_12.pdf#page=4

ok what mipMaps are is basically an octree representation of the texture embeded into to memory.
so it turns the texture into something like this:
th.jpg.de34254014b0c023a1ee6e98d37639a2.jpg

This is for performance/bottle necking there is no reason to display or calculate the full texture if its way far away basically.  The system handles this on its own, and is a part of just the gl pipeline.

When you do not generate mips it keeps the texture as is no matter what the LOD step is. Which can create artifacts and is not the most efficient.

Now the sampling modes will need to change only if you generate mips this is because when it samples if it does nearest it will mess things up as the LOD level changes because you will want to sample from the same mip region as the the texture LOD.
 

So how do I generate mipmaps in code (C# unity code I assume since that is where I encode the texture png files)...

Am I supposed to physically layout the png like above, I dont get how to generate the mipmap ... and most importantly how do I save all this mipmap as png ???

Link to comment
Share on other sites

Its automatically handled in the gl pipeline when you bind a texture.  Just bind the texture and set the noMipmaps to false (or its default) and the GPU creates the mipmaps and stores them in the memory.

If you have the flag set to true it does not generate them, and thats when you will have to use NEAREST_SAMPLING for it to work, it will only be if you need the texture to soften up some that you will want to generate the mips and then mess with the sampling mode until you find one that gets rid of the artifacts.

Link to comment
Share on other sites

15 minutes ago, Pryme8 said:

Its automatically handled in the gl pipeline when you bind a texture.  Just bind the texture and set the noMipmaps to false (or its default) and the GPU creates the mipmaps and stores them in the memory.

If you have the flag set to true it does not generate them, and thats when you will have to use NEAREST_SAMPLING for it to work, it will only be if you need the texture to soften up some that you will want to generate the mips and then mess with the sampling mode until you find one that gets rid of the artifacts.

Dude, Im sorry... I am totally lost. So I DONT need to physically do something with the texture image png to generate mipmaps.

If that is so, from the beginning I had NEAREST_NEAREST_MIPLINEAR and noMipmap was default to FALSE and that was showing edge seams.

So does that mean IT DID NOT AUTOMATICALLY generate mipmaps ???

Or do I just need to try (like you said before) every sample mode with MIP in it... ONE OF WILL HAVE TO WORK... Right???

I hope one works

Im lost :(

Link to comment
Share on other sites

No it was the sampling mode was just creating artifacts, try some of the other ones that include MIP in its sampling mode, and see what happens.  These are just quick fixes the real fix is a good amount of glsl scripting, but for the most part if you get the sample mode correct most of your problems should be fixed.

Link to comment
Share on other sites

5 minutes ago, Pryme8 said:

No it was the sampling mode was just creating artifacts, try some of the other ones that include MIP in its sampling mode, and see what happens.  These are just quick fixes the real fix is a good amount of glsl scripting, but for the most part if you get the sample mode correct most of your problems should be fixed.

I tried 1,2,3,4,5,6,9 and 10 all with MIP in it... Still leave edge seams with noMipmap = false ... Bummer :(

 

Link to comment
Share on other sites

Yo @Deltakosh ... It does not look like you have these problems with the particle system ANIMATESHEET where you use a cell Index to

get the cell... Can you chime in hear on how you got your texture atlas to work or how I can convert that code to use the UV Coords from a rectangle

instead of the whole cell index thing ???

14 minutes ago, Pryme8 said:

lame, yeah you would need to do a buffer around them. Its a little more complicated but doable.  I would recommend reading up on stuff like this: https://gamedev.stackexchange.com/questions/46963/how-to-avoid-texture-bleeding-in-a-texture-atlas

Do a buffer around them ??? 

Link to comment
Share on other sites

https://mtnphil.wordpress.com/2011/09/26/terrain-texture-atlas-construction/

see how it uses a "buffer" of data around the actual texture, its kinda a oddball thing to wrap your head around but this explains it decently.

and here is some discussion on to mip or not to mip
https://blogs.msdn.microsoft.com/shawnhar/2009/09/14/texture-filtering-mipmaps/

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...