Jump to content

Texture Atlas Tiling At the Shader


MackeyK24
 Share

Recommended Posts

Mipmapping Texture Atlases

Now the above technique works fine if the textures are filtered using GL_NEAREST or point filtering.  However, this method quickly runs into problems when combined with mipmapping.  There are basically two things that go wrong:

  1. Using an automatic mipmap generator like glGenerateMipmaps will cause blurring across texture atlas boundaries, creating visible texture seams at a distance.
  2. At the edge of a looped texture the LOD calculation will be off, and causing the GPU to use a much lower resolution mip level than it should.

read this : 

https://0fps.net/2013/07/09/texture-atlases-wrapping-and-mip-mapping/

Link to comment
Share on other sites

@MackeyK24 Sorry my monday is a bit rough.
1.) downscale the 1024x1024 texture to a 1016x1016. (this will be the rectangle size). Maybe you can do this in your exporter I don't really use unity, but I see something like this in your code: extureScale.Bilinear(item,
so maybe this can be done in the exporter.

2. Get a 1024x1024 place in the atlas texture, and place the 1016 texture in the center.
and fill the 4pixel border on every side with...
I think the best would be to repeat the texture on the sides, like this (image), so like a repeating 1016 texture in the middle of a 1024 place.




 

2017-04-10 12.51.54.jpg

Link to comment
Share on other sites

1 hour ago, BitOfGold said:

@MackeyK24 Sorry my monday is a bit rough.
1.) downscale the 1024x1024 texture to a 1016x1016. (this will be the rectangle size). Maybe you can do this in your exporter I don't really use unity, but I see something like this in your code: extureScale.Bilinear(item,
so maybe this can be done in the exporter.

2. Get a 1024x1024 place in the atlas texture, and place the 1016 texture in the center.
and fill the 4pixel border on every side with...
I think the best would be to repeat the texture on the sides, like this (image), so like a repeating 1016 texture in the middle of a 1024 place.




 

2017-04-10 12.51.54.jpg

 I wrote and extrude that function that does just... just for test purposes i color all the border color green so i can see the extrude and ALL border colors are the same exact color... with a padding of 32 pixels to really stand out... Now that should show a solid green block but it still shows the seems in between

Look at my texture atlas:

58eb770cdf570_ScreenShot2017-04-10at2_13_16AM.thumb.png.eb8d23c6226d2d8ecfd7019ade4cdea8.png

 

And the result still show seems

 

 

Link to comment
Share on other sites

And here is the shader snippet that gets the color using testuer2D():

vec2 atlas1FX = fract(vTerrainUV * atlasInfo1.xy);
atlas1UV = vec2((atlas1FX.x * atlasRect1.w) + atlasRect1.x, (atlas1FX.y * atlasRect1.z) + atlasRect1.y);
splatColor = texture2D(albedoSampler, atlas1UV + uvOffset) * baseColor1.r;

 

Maybe i need to offset some so it does not use the very first pixel...

 

I don't know.. Im getting frustrated with this and about to abandon Terrain Atlas for splatmap support and try to use texture array instead.... But that would restrict the BabylonJS Toolkit only supporting WebGL 2.0 for terrain splatmap.. I would have to fallback to a single surface texture of color for webgl... or may fallback to the regular babylon terrainMaterial.ts from the material library for WebGL 1.0 devices...

 

I was hoping that Texture Atlas would work so can support all devices and both all WebGL versions

 

Link to comment
Share on other sites

BTW... If i can ever get that seem problem solved... No Need to take texture out to a paint program for that... I have to code to do that for you... It is was produced the texture atlas above with green lines... I just to figure out mirror pixels... but this can all happen a t runtime real fast:

 

        public static Texture2D Extrude(this Texture2D source, int padding, TextureExtrude extrudeColor = TextureExtrude.Default)
        {
            int ratio = padding * 2;
            int width = source.width - ratio;
            int height = source.height - ratio;
            Vector2 tileSize = new Vector2(width, height);
            Vector2 borderSize = new Vector2(padding, padding);
            source.Scale(width, height, false);
            return source.Extrude(tileSize, borderSize, extrudeColor);
        }

        public static Texture2D Extrude(this Texture2D source, Vector2 tileSize, Vector2 borderSize, TextureExtrude extrudeColor = TextureExtrude.Default)
        {
            int cols = (int)Mathf.Floor(source.width / tileSize.x);
            int rows = (int)Mathf.Floor(source.height / tileSize.y);
            Color border = Color.black;
            switch(extrudeColor)
            {
                case TextureExtrude.White:
                    border = Color.white;
                    break;
                case TextureExtrude.Red:
                    border = Color.red;
                    break;
                case TextureExtrude.Green:
                    border = Color.green;
                    break;
                case TextureExtrude.Blue:
                    border = Color.blue;
                    break;
                case TextureExtrude.Yellow:
                    border = Color.yellow;
                    break;
                case TextureExtrude.Gray:
                    border = Color.gray;
                    break;
                default:
                    border = Color.black;
                    break;
            }
            Texture2D texture = new Texture2D((int)(cols * (tileSize.x + borderSize.x * 2f)), source.height, source.format, false);
            texture.filterMode = source.filterMode;
            for(int i = 0; i < cols; i++) {
                Color[] c1 = source.GetPixels((int)(i * tileSize.x), 0, 1, source.height);
                Color[] c2 = source.GetPixels((int)((i + 1) * tileSize.x - 1), 0, 1, source.height);
                // Format border pixels
                if (extrudeColor != TextureExtrude.Default && extrudeColor != TextureExtrude.Mirror) {
                    for (int index = 0; index < c1.Length; index++) {
                        c1[index] = border;
                    }
                    for (int index = 0; index < c2.Length; index++) {
                        c2[index] = border;
                    }
                } else if (extrudeColor == TextureExtrude.Mirror) {
                    // TODO: Mirror Edge Pixels
                }
                for(int j = 0; j < borderSize.x; j++) {
                    texture.SetPixels((int)(i * (tileSize.x + borderSize.x * 2) + j), 0, 1, source.height, c1);
                    texture.SetPixels((int)(i * (tileSize.x + borderSize.x * 2) + j + tileSize.x + borderSize.x), 0, 1, source.height, c2);
                }
                texture.SetPixels((int)(i * (tileSize.x + borderSize.x * 2) + borderSize.x), 0, (int)tileSize.x, source.height, source.GetPixels((int)(i * tileSize.x), 0, (int)tileSize.x, source.height));
            }
            
            Texture2D temp = texture;
            texture = new Texture2D(temp.width, (int)(rows * (tileSize.y + borderSize.y * 2f)), source.format, false);
            texture.filterMode =source.filterMode;
            for(int i = 0; i < rows; i++) {
                Color [] c1 = temp.GetPixels(0, (int)(i * tileSize.y), temp.width, 1);
                Color [] c2 = temp.GetPixels(0, (int)((i + 1) * tileSize.y - 1), temp.width, 1);
                // Format border pixels
                if (extrudeColor != TextureExtrude.Default && extrudeColor != TextureExtrude.Mirror) {
                    for (int index = 0; index < c1.Length; index++) {
                        c1[index] = border;
                    }
                    for (int index = 0; index < c2.Length; index++) {
                        c2[index] = border;
                    }
                } else if (extrudeColor == TextureExtrude.Mirror) {
                    // TODO: Mirror Edge Pixels
                }
                for(int j=0; j < borderSize.y; j++) {
                    texture.SetPixels(0, (int)(i * (tileSize.y + borderSize.y * 2) + j), temp.width, 1, c1);
                    texture.SetPixels(0, (int)(i * (tileSize.y + borderSize.y * 2) + j + tileSize.y + borderSize.y), temp.width, 1, c2);
                }
                texture.SetPixels(0, (int)(i * (tileSize.y + borderSize.y * 2) + borderSize.y), temp.width, (int)tileSize.y, temp.GetPixels(0, (int)(i * tileSize.y), temp.width, (int)tileSize.y));
            }

            return texture;                
        }

 

 

and my pack textures function uses the image.Extrude function as it packs the textures:

 

public static Rect[] PackTextureAtlas(Texture2D source, Texture2D[] textures, int textureAtlasSize = 4096, int maxTextureImageSize = 0, bool bilinearScaling = true, int texturePadding = 0, bool fixBorderEdges = false, bool removeAlpha = false, CopyFilterMode filterMode = CopyFilterMode.Source)
        {
            Rect[] result = null;
            if (textures != null && textures.Length > 0)
            {
                List<Texture2D> packingBuffer = new List<Texture2D>();
                foreach (var texture in textures)
                {
                    Texture2D item = texture.Copy(TextureFormat.RGBA32, filterMode);
                    if (maxTextureImageSize > 0 && (item.width > maxTextureImageSize || item.height > maxTextureImageSize))
                    {
                        item.Scale(maxTextureImageSize, maxTextureImageSize, bilinearScaling);
                    }
                    if (fixBorderEdges)
                    {
                        item = item.Extrude(32, TextureExtrude.Green);
                    }
                    packingBuffer.Add(item);
                }
                // Encode texture atlas package
                if (packingBuffer.Count > 0)
                {
                    result = source.PackTextures(packingBuffer.ToArray(), texturePadding, textureAtlasSize, false);
                    Color32[] copy = source.Copy(TextureFormat.RGBA32, filterMode).GetPixels32();
                    if (copy != null) {
                        if (removeAlpha) {
                            for (int index = 0; index < copy.Length; index++) {
                                copy[index].a = (byte)255.0f;
                            }
                        }
                        source.SetPixels32(copy);
                        source.Apply();
                    } else {
                        UnityEngine.Debug.LogWarning("===> Failed to format texture packing result copy for texture: " + source.name);
                    }
                }
            }
            return result;
        }

 

Works great and fast ... If can ever get seams problem fixed... will be awesome...  Hope i don't have to to texture arrays :(

 

Link to comment
Share on other sites

Yo @NasimiAsl no that i can extrude the edges and put a solid color, maybe this shader code from your example: xxx

But i don't under stand this at all... can pleas make a regular vertex and fragment shader .fx files so i can follow along with what is going on here:

var atlasMap = function(SB,path, x,y,w,h,W,H,tx,ty){
            
            return SB.InLine('\
            float left = '+BABYLONX.Shader.Print(x)+';\
            float top = '+BABYLONX.Shader.Print(y)+';\
            float width ='+BABYLONX.Shader.Print(w)+';\
            float height ='+BABYLONX.Shader.Print(h)+';\
            float WIDTH ='+BABYLONX.Shader.Print(W)+';\
            float HEIGHT = '+BABYLONX.Shader.Print(H)+';\
\
            float uv_w =  width / WIDTH;\
            float uv_h =  height / HEIGHT;\
            float uv_x =  left / WIDTH;\
            float uv_y =  1.-  top  / HEIGHT -uv_h;\
\
           float tile_x = '+BABYLONX.Shader.Print(tx)+';\
            float tile_y = '+BABYLONX.Shader.Print(ty)+';\
\
            vec2 newUvAtlas = vec2( mod( vuv.x*tile_x  , uv_w ) +uv_x  , mod(vuv.y*tile_y    ,uv_h)+uv_y  );\
            vec2 edgeUvAtlas_x = vec2( mod( vuv.x*tile_x +0.5*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile_y -0.0*uv_h  ,uv_h)+uv_y  );\
            vec2 edgeUvAtlas_y = vec2( mod( vuv.x*tile_x -0.0*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile_y -0.5*uv_h  ,uv_h)+uv_y  );\
             vec2 edgeUvAtlas_xy = vec2( mod( vuv.x*tile_x -0.5*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile_y -0.5*uv_h  ,uv_h)+uv_y  );')
              // make edge map
             .Map({ path: path ,  uv:'vec2(edgeUvAtlas_x)'  })
            .Reference(1) // keep edge  map in result_1 var
              .Map({ path: path ,  uv:'vec2(edgeUvAtlas_y)'  })
            .Reference(2) // keep edge  map in result_2 var
             .Map({ path: path ,  uv:'vec2(edgeUvAtlas_xy)'  })
            .Reference(3) // keep edge  map in result_2 var
            .Map({ path: path ,  uv:'vec2(newUvAtlas )'  })
           
           // FIND A EDGES
           .InLine('vec2 edge = vec2(  pow( 2.*abs((newUvAtlas.x-uv_x)/uv_w -0.5), 3.),  pow( 2.*abs((newUvAtlas.y-uv_y)/uv_h -0.5), 3.) ) ;')
          .Reference(4,' result = vec4(  edge.x ,edge.y,  max(edge.x,edge.y)  ,1.);')
            .Pink(4,' result =  result_1   ; ',{ rangeStep:-0.48,rangePower:0.48})
             .Cyan(4,' result =  result_2 ; ',{ rangeStep:-0.48,rangePower:0.48})
             .White(4,' result =  result_3  ; ',{ rangeStep:-0.48,rangePower:0.48}) ;
            
        
        };
 

 

What do you think ?

 

Link to comment
Share on other sites

4 minutes ago, NasimiAsl said:

:D

i wanna offer that first but i scared 

 the fast solution is fill border with some color but you most care about your tile pattern

http://www.babylonjs-playground.com/#1ODVTX#26

I really wish i could use this... but i have NO IDEA how to even read what going on here:

var atlasMap = function(SB,path, x,y,w,h,W,H,tx,ty){
            
            return SB.InLine('\
            float left = '+BABYLONX.Shader.Print(x)+';\
            float top = '+BABYLONX.Shader.Print(y)+';\
            float width ='+BABYLONX.Shader.Print(w)+';\
            float height ='+BABYLONX.Shader.Print(h)+';\
            float WIDTH ='+BABYLONX.Shader.Print(W)+';\
            float HEIGHT = '+BABYLONX.Shader.Print(H)+';\
\
            float uv_w =  width / WIDTH;\
            float uv_h =  height / HEIGHT;\
            float uv_x =  left / WIDTH;\
            float uv_y =  1.-  top  / HEIGHT -uv_h;\
\
           float tile_x = '+BABYLONX.Shader.Print(tx)+';\
            float tile_y = '+BABYLONX.Shader.Print(ty)+';\
\
            vec2 newUvAtlas = vec2( mod( vuv.x*tile_x  , uv_w ) +uv_x  , mod(vuv.y*tile_y    ,uv_h)+uv_y  );\
            ')  
            .Map({ path: path ,  uv:'vec2(newUvAtlas )'  })
           
           // FIND A EDGES
           .InLine('vec2 edge = vec2(  pow( 2.*abs((newUvAtlas.x-uv_x)/uv_w -0.5), max(3.,40.-min(length(camera-pos),40.))),  pow( 2.*abs((newUvAtlas.y-uv_y)/uv_h -0.5), max(3.,40.-min(length(camera-pos),40.))) ) ;\
           ')
          .Reference(4,' result = vec4(    max(edge.x,edge.y) ,0.,0. ,1.);')
            .Red(4,BABYLONX.Helper()
            // edge colors
            .Solid({r:0.5,g:0.43,b:0.3})
            
            .Build(),{rangeStep:-0.48});
        
        };
 

Can tell what is the vertex program ... what is the fragment program...what is the .MAP stuff... Sorry i just don't know that whole Shader Builder Thing :(

 

 

Link to comment
Share on other sites

Does anybody know about force GL_NEAREST or point filtering... I thought is was encoded in the image and the texture was created using Point Filter Mode then encoded as a png... I don't what else i can do to tell it NO MIPMAPS...

 

i guess this seam issue is if your are using mipmaps... Which i am not (i think)... i only encode pixels using SetPixels with NO mipmap enable and i DONT set use SetPixels(x, 1) or anything to set pixel in the other mipmap indexes ...

 

Man... I am almost about to give up here :(

 

Link to comment
Share on other sites

1 hour ago, Deltakosh said:

point filtering (or linear filtering) are filters used by the shader. It is not encoded inside the texture but it is defined when you create a Babylon texture:

http://www.babylonjs-playground.com/#58D3CB

I am trying to add 'SampleMode' to babylon entities so i can serialize the texture to use different sample mode... But i can tell in the Parse function for texture.ts when the actual contrcutor gets called for the texture... we have to be able to take the parsedTexture.samplingMode and pass it the constructor... cannot simply assign a new samplingMode after construction because is uses the samplingMode in the constructor... how should i handle setting samplingMode on serialized texture info that has to go thru the Texture.Parse system?

This is the current Parse... where could i implement a parsedTexture.samplingMode serialization and deserialization

 

UPDATE

Shit... Did not see this little guy:

 

public updateSamplingMode(samplingMode: number): void {
            if (!this._texture) {
                return;
            }

            this._samplingMode = samplingMode;
            this.getScene().getEngine().updateTextureSamplingMode(samplingMode, this._texture);
        }

 

i will use that :)

 

Link to comment
Share on other sites

12 hours ago, BitOfGold said:

@MackeyK24: yes that should show green without seams... :(
Where are your triangles?
Are you sure it's not some kind of vertex position error like rounding?
(Just guessing, but if triangle vertexes are not the same positon, that can create seams too)
 

Yo @BitOfGold

Could it have to do with the sampling mode... I think the default texture sampling mode is set to trilinear in babylon js... I don't actually make my textures with code... they are serialized into the scene file... I am adding sampling mode support to the babylon entities and for right now and tweaking out a fork of babylonjs to support serialized sampling mode property and will set that to NEAREST...

Maybe they sample mode WAS the problem the WHOLE time :(

 

Link to comment
Share on other sites

Well i can at least control the sample mode from babylon entities but... that still did not fix the issue ... even with same solid color  tile edges , i still get seems ... bars now more than the solid seam lines i got at first... but still shows those edge artifacts and i have either NO ADDITIONAL mipmaps in texture, i guess what is only considered the base mipmap level 0

@NasimiAsl ... You might be my last hope in getting this fixed... Your code from this example: http://www.babylonjs-playground.com/#1ODVTX#21 

which i just can't read... but what ever its doing... that looks like that could work... Now i extrude my edged and will come up with some mirror logic for padded area... but even with solid color ... what I'm looking for is to not see that seams... i can tweak the image seven ways from sunday to get the pattern to match after we get rid of those hard seam edges like you do for that example.

I know i asked before (no answer) but do think you can quickly pull that shader code out into a regular .fx files so i know what is what... Uniforms varying etc... I think i can take it and try to tweak my shader code to use your 'edge uv' type code you got (if i can just understand as far a a normal coded shader)... I know all this SB.Inline and .Map and .Referance stuff is really kool and easy to use from playground... But i am still so new to the game its like Chinese to me (Nothing wrong with it or Chinese ... i just don't understand either) :)

 

Link to comment
Share on other sites

Understanding ShaderBuilder

  1. requirment for make shader with shader builder:
    1. what we want    We most know what we want to make (like light, tile texture , reflect , effect , change some color  ... )

    2. how can we make  your algorithm and workflow in raw shader(cyos) for write that

    3. use shader Builder tools and helpers for write short code in javascript ( that is purpose of shader builder)

  2. output : what we need

    1. cpu side : we need def textures and uniforms array some settings here

    2. gpu side : fragment Body and vertex body 

  3. Fluent Interface : https://en.wikipedia.org/wiki/Fluent_interface

 

step 1 : always attach this file :

 https://github.com/BabylonJS/Extensions/blob/master/ShaderBuilder/Babylonx.ShaderBuilder.js to your heads

** in play ground use this structer https://www.babylonjs-playground.com/#G67XLZ#2

 

step 2 : you need initialize shader Builder :

 BABYLONX.ShaderBuilder.InitializeEngine();  

step 3 : make new  Instance

new BABYLONX.ShaderBuilder() 

step 4 : make your wanted material (your algorithm)  

step 5 : make babylon shader  material

BuildMaterial  or BuildPostProcess

 

---------------------- 

back to the post : http://www.babylonjs-playground.com/#1ODVTX#21 

 

erferferfe.jpg.1e58421fa78eff6385c5d2a5db1502dd.jpg

 

 

Link to comment
Share on other sites

Oh, CDN.rawgit is "down" right now, can't see... gateway timeout.  But I will look soon.  I looked at code... not sure what it is about.  AtlasMap?  hmm.

I see it LIVE, soon. 

Also, thx for your great talk about shaders/shaderBuilder... very good!

update:  Now I see PG.  Good blends.  Beautiful!  

Am I missing some important part?  (sorry) (I need more coffee)

Link to comment
Share on other sites

10 hours ago, NasimiAsl said:

Understanding ShaderBuilder

  1. requirment for make shader with shader builder:
    1. what we want    We most know what we want to make (like light, tile texture , reflect , effect , change some color  ... )

    2. how can we make  your algorithm and workflow in raw shader(cyos) for write that

    3. use shader Builder tools and helpers for write short code in javascript ( that is purpose of shader builder)

  2. output : what we need

    1. cpu side : we need def textures and uniforms array some settings here

    2. gpu side : fragment Body and vertex body 

  3. Fluent Interface : https://en.wikipedia.org/wiki/Fluent_interface

 

step 1 : always attach this file :

 https://github.com/BabylonJS/Extensions/blob/master/ShaderBuilder/Babylonx.ShaderBuilder.js to your heads

** in play ground use this structer https://www.babylonjs-playground.com/#G67XLZ#2

 

step 2 : you need initialize shader Builder :

 BABYLONX.ShaderBuilder.InitializeEngine();  

step 3 : make new  Instance

new BABYLONX.ShaderBuilder() 

step 4 : make your wanted material (your algorithm)  

step 5 : make babylon shader  material

BuildMaterial  or BuildPostProcess

 

---------------------- 

back to the post : http://www.babylonjs-playground.com/#1ODVTX#21 

 

erferferfe.jpg.1e58421fa78eff6385c5d2a5db1502dd.jpg

 

 

 So basically this just produces a 'Seamless Texture' ... I can really use ANY premade seamless texture then right... this just main tints the pattern when tiling ...

But any ways... If i understand you here... Basically make 9 copies of your texture in a 3 x 3 grid pattern then "Grab" the pixel in the center based on the original texture image width and height.. Crop out those pixels and use these as your "Seamless Texture"

But again... i think if i can get and use pre-made seamless texture i would be ok here...

Yo @NasimiAsl so i gess there is no chance to make that code regular readable shader code... Or at least pull out the math function that your are doing instead of using fract()

I know you sent in on this ShaderBuilder... But i don't really need to learn and use ANOTHER shader builder...i got my own in unity...

I just need to understand the math you are using to make tiling happen so i can use that math in my shader code to make seams go away.

 

Link to comment
Share on other sites

Hey, I'm very interested in this (getting a texture from a texture map to wrap) as a user, but I don't know what ShaderBuilder is, or what its implications are.

Am I correct in thinking that ShaderBuilder is some kind of tool to make experimenting with custom shaders easier (in the playground and so on), and if you wanted to do something like this for "real content" you'd want to make a ShaderMaterial, the way it's done in the tutorials? If so, is there a version of this effect that's built that way that I could try to hack on and figure out what it's doing?

If Babylon just knew how to do this as a feature, it would be dreamy... 

Link to comment
Share on other sites

Hi @fenomas and all.  I like MY explanation of ShaderBuilder... and @NasimiAsl gave me a LIKE, so perhaps I wasn't TOO far away from truth.  Sorry for the "kiddy-level" talking, if it feels like such.

I have been bothering Nasimi for a "print it" option, so that shaders which are appended-together, piece-by-piece, on-the-fly, with ShaderBuilder... could also be used as standard custom shaders.  Standard custom shaders are most-often stored in .fx files, in BABYLON.ShadersStore, or in html <script> elements.  You can think of ShaderBuilder as the 4th way to "store" shader code.

Perhaps one other thing might be useful to you, F.  Here is a post where Nasimi replied to my "Can we have a shader code printer?" -request.  He did not show me how to print it, but he printed it FOR me.  SO, I think we are seeing the end-result... of the shaderBuilder operations... that were used in that playground.  As you can see, the static shader code is HUGE by comparison to the ShaderBuilder code seen in that playground.

Perhaps this is an indicator of how much stuff ShaderBuilder does... behind the scenes.  Not necessarily any "effects magic", but instead... take care of some/all annoying "wrapper" and/or "template/boilerplate" stuff... things that make shader code stored in the other three methods... fat and unwieldy.  In other words, ShaderBuilder takes care of the annoying, repetitive base-requirements.  I think it still allows you to turn all the important "knobs".

Hope this helps a little.  You might want to take note of THIS good Dad72 question, and Naz's answer.  "you can make that from custom shader too".  In other words, yeah... you don't NEED to use ShaderBuilder to assemble the shader code on-the-fly (and compile and store in umm... engine._compiledEffects[name]._program?).  Instead, you can use "static" custom shader code, stored in any of the other three ways.

Link to comment
Share on other sites

5 hours ago, fenomas said:

 

Hey, I'm very interested in this (getting a texture from a texture map to wrap) as a user,

 

@MackeyK24 

http://www.babylonjs-playground.com/#Y0RQ2F#2

http://www.babylonjs-playground.com/#Y0RQ2F#7 short Code

              
vec4 getTileFromAtlasMap(sampler2D txtRef_0,vec2 tile ,vec2 pos,vec2 size,vec2 SIZE,vec2 vuv){
   
      vec4 result = vec4(0.);
     float uv_w =  size.x / SIZE.x;  
     float uv_h =  size.y / SIZE.y;   
     float uv_x =  pos.x / SIZE.x ;    
     float uv_y =  1.-  pos.y  / SIZE.y -uv_h; 

     tile.x = tile.x*uv_w*0.5;
     tile.y = tile.y*uv_h *(size.x/size.y)*0.5 ;
       

     vec2 newUvAtlas = vec2( mod( vuv.x*tile.x   , uv_w ) +uv_x  , mod(vuv.y*tile.y    ,uv_h)+uv_y  ); 
     vec2 edgeUvAtlas_x = vec2( mod( vuv.x*tile.x  +0.5*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile.y -0.0*uv_h  ,uv_h)+uv_y  );   
     vec2 edgeUvAtlas_y = vec2( mod( vuv.x*tile.x  -0.0*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile.y   -0.5*uv_h  ,uv_h)+uv_y  );  
     vec2 edgeUvAtlas_xy = vec2( mod( vuv.x*tile.x  -0.5*uv_w , uv_w ) +uv_x  , mod(vuv.y*tile.y  -0.5*uv_h  ,uv_h)+uv_y  );
     
                     vec4 color_2_ = texture2D(txtRef_0 ,edgeUvAtlas_x.xy*vec2(1.,1.)+vec2(0.,0.));
                      
                       result = vec4(color_2_.rgb , 1.); 
                       vec4 resHelp_2_ = result; vec4 result_1 = vec4(0.);
                  result_1 = result;result = resHelp_2_ ;
                 
                        vec4 color_3_ = texture2D(txtRef_0 ,edgeUvAtlas_y.xy*vec2(1.,1.)+vec2(0.,0.));
                       
                       result = vec4(color_3_.rgb , 1.); 
                      vec4 resHelp_3_ = result; vec4 result_2 = vec4(0.);
                  result_2 = result;result = resHelp_3_ ;  

                        vec4 color_4_ = texture2D(txtRef_0 ,edgeUvAtlas_xy.xy*vec2(1.,1.)+vec2(0.,0.));
                        
                       result = vec4(color_4_.rgb , 1.); 
                       vec4 resHelp_4_ = result; vec4 result_3 = vec4(0.);
                  result_3 = result;result = resHelp_4_ ; 
 
                        vec4 color_5_ = texture2D(txtRef_0 ,newUvAtlas.xy*vec2(1.,1.)+vec2(0.,0.));
                        
                       result = vec4(color_5_.rgb , 1.); 
                       vec2 edge = vec2(  pow( 2.*abs((newUvAtlas.x-uv_x)/uv_w -0.5), 3.),  pow( 2.*abs((newUvAtlas.y-uv_y)/uv_h -0.5), 3.) ) ;vec4 resHelp_5_ = result; vec4 result_4 = vec4(0.);
                 result = vec4(  edge.x ,edge.y,  max(edge.x,edge.y)  ,1.);
                 result_4 = result;
                 
                 result = resHelp_5_ ; 
                 
                 if( ((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))) > 0.5 + -0.48  && ((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))) < 0.5 - -0.48  && ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))) > 0.5 + -0.48  ) { vec4 oldrs_6_ = vec4(result);float al_6_ = max(0.0,min(1.0,(((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))) + ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))))/2.0 - (((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))))/1.0+(0.48))); float  l_6_ =  1.0-al_6_;   result =  result_1   ;  result = result*al_6_ +  oldrs_6_ * l_6_;    } if( ((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))) < 0.5 - -0.48  && ((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))) > 0.5 + -0.48  && ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))) > 0.5 + -0.48  ) { vec4 oldrs_7_ = vec4(result);float al_7_ = max(0.0,min(1.0,(((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))) + ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))))/2.0 - (((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))))/1.0+(0.48))); float  l_7_ =  1.0-al_7_;   result =  result_2 ;  result = result*al_7_ +  oldrs_7_ * l_7_;    } if( ((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))) > 0.5 + -0.48  && ((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))) > 0.5 + -0.48  && ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))) > 0.5 + -0.48  ) { vec4 oldrs_8_ = vec4(result);float al_8_ = max(0.0,min(1.0,(((result_4.x*1.-0.)>1.0 ? 0. : max(0.,(result_4.x*1.-0.))) + ((result_4.y*1.-0.)>1.0 ? 0. : max(0.,(result_4.y*1.-0.))) + ((result_4.z*1.-0.)>1.0 ? 0. : max(0.,(result_4.z*1.-0.))))/3.0+(0.48))); float  l_8_ =  1.0-al_8_;   result =  result_3  ;  result = result*al_8_ +  oldrs_8_ * l_8_;    } 
   return result;
} 

 getTileFromAtlasMap(

texture,

[ tile x,y ],

[ texture Position In AtlasMap ],

 [ inner texture Size In AtlasMap ]  ,

[  AtlasMap size ]

,vUV)

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...