MackeyK24 Posted April 8, 2017 Share Posted April 8, 2017 Yo @Deltakosh ... I am having trouble with apply terrain texture atlas tiling (texture.uScale and texture.vScale) at the shader for texture atlas... This is how i am having main UV coord offset for texture atlas: I have a vec4 (atlas1UV) containing the rectangle of the texture within the texture atlas (x, y, height, width). I also have a vec2 (atlas1Scale) that is the texture offset/tiling so atlasScale might be something like vec2(5,5) now i assume the default way openGL texture() function works is anything outside the 0 - 1 for uv causes the texture2D to 'REPEAT' the texture giving use tiling... But using a texture atlas going outside the 0 to 1 by multiplying uvcoord * scaleTile causes the texture() function to return the OTHER parts of the splats... This is the followingg snippet to get splat 1... WORKS except when i need scale or tiling: vec2 atlas1UV = vec2((vTerrainUV.x * atlasRect1.w) + atlasRect1.x, (vTerrainUV.y * atlasRect1.z) + atlasRect1.y); vec2 atlas1Scale = vec2(atlasInfo1.x, atlasInfo1.y); vec4 atlas1Color = texture2D(albedoSampler, atlas1UV * atlas1Scale + uvOffset); surfaceAlbedo = atlas1Color * baseColor1.r; How can i offset the scale or limit the region the texture() function uses so it can REPEAT the section from texture atlas... Or something like that... Anything... Otherwise i have to go back to using operate textures for each terrain splatmap (up to 4) and each texture splat (up to 12) and each normal splat (up to 12)... Thats 28 ADDITIONAL texture i would have to load into my splatmap shader (on top of the standard PBR textures ... if being used.. light light maps and reflection) So your browser would need at least 32 for the MAX_TEXTURE_IMAGE_UNITS (which are 16 on most browsers and 8 on iOS) for a fully loaded splatmap. TextureAtlas is perfect, can do all of texture now with just 1 additional texture to the PBR pipeline...SPLATMAP TEXTURE... the actuals splats and normals are encoded to the regular Albedo and Bump texture from the PBR Materials... got working except for applying scale like shown above... Please.... Any help... I have been working on this for weeks now and i can't seem to figure this last bit of scaling/tiling Pinging @Sebavan and @RaananW and @Wingnut ... This goes out to you guys as well. My current shader code: Terrain_Splatmap.fragment.fx Terrain_Splatmap.vertex.fx Please take a look at Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 Btw... Here is the full vertex and fragment shaders: Terrain_Splatmap.fragment.fx Terrain_Splatmap.vertex.fx Please take a look at Quote Link to comment Share on other sites More sharing options...
Wingnut Posted April 8, 2017 Share Posted April 8, 2017 Hi M. About the best I can do... is watch you do your work, Mackey. You are quite a bit more advanced than I am. But I sure enjoy reading about your issues and learning from you. And, I appreciate what you are doing. I'm honored that you think I matter... thanks! Wish I could be more helpful, but I'm not a shaders guy, and I have no idea what a splat map is. Ok. perhaps I do... now that I've read about it on the web. Yeah, blending over-layed textures - I'm definitely a fan of on-the-fly texture blending. @NasimiAsl did a real nice shader-blending of 2 materials, recently, and I loved it, and possibly that is why you included me in your ping-list, Mack. I appreciate that. I hope you find quick assistance on this logjam. Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 Yo @NasimiAsl ... Any thoughts from you on how to do tiling when using a Texture Atlas ? Note details above Quote Link to comment Share on other sites More sharing options...
Wingnut Posted April 8, 2017 Share Posted April 8, 2017 Here's Naz's blend demo and Rolento's thread. Naz did some excellent demos and teaching, in there, and so did @Dad72 and @BitOfGold. It's a cool thread... lots of trailblazing there. Mack, you've visited there before, I suspect. Quote Link to comment Share on other sites More sharing options...
BitOfGold Posted April 8, 2017 Share Posted April 8, 2017 I think that is a perfect solution if I understand it well! I think, first you have to get the fract() of uv. that gives you a 0..1 range. And multiply that with atlas rect scale, and after that add atlas rect position. I hope it helps. And I (still) hope this splatmap material will be available somehow outside of unity exporter Quote Link to comment Share on other sites More sharing options...
BitOfGold Posted April 8, 2017 Share Posted April 8, 2017 // Base splat colors vTerrainUV = fract(vTerrainUV); if (splatmapRects > 0.0) { vec2 baseUV1 = vec2(vTerrainUV.x * splatmapRect1.w) + splatmapRect1.x, (vTerrainUV.y * splatmapRect1.z) + splatmapRect1.y); baseColor1 = texture2D(splatmap, baseUV1 + uvOffset); } Something like this I think. Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 8, 2017 Share Posted April 8, 2017 2 hours ago, MackeyK24 said: Yo @NasimiAsl ... Any thoughts from you on how to do tiling when using a Texture Atlas ? Note details above http://www.babylonjs-playground.com/#1ODVTX#1 border problem http://www.babylonjs-playground.com/#1ODVTX#7 we have this conversation but we don't continue that for find good result any way i am now on custom material for a few days after that i make full support for atlas texture BitOfGold 1 Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 8, 2017 Share Posted April 8, 2017 http://www.babylonjs-playground.com/#1ODVTX#9 http://www.babylonjs-playground.com/#1ODVTX#13 Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 20 minutes ago, NasimiAsl said: http://www.babylonjs-playground.com/#1ODVTX#9 I don't see any calculations in shader code where you take "uScale" and "vScale" into account... This example above i don't see any shader code... The very first one ... i just don't see you using a "Scaling or Tiling" code Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 8, 2017 Share Posted April 8, 2017 1 minute ago, MackeyK24 said: I don't see any calculations in shader code where you take "uScale" and "vScale" into account... This example above i don't see any shader code... The very first one ... i just don't see you using a "Scaling or Tiling" code this calculated under ShaderBuilder and generated last result this just support Square table // rowIndex: row index for your wnated texture on table , columnIndex: coulmn index for your wnated texture on table , indexCount: row and column count on table \\ i can share all calculate about that (if you want for real texture atlas ) Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 31 minutes ago, NasimiAsl said: i can share all calculate about that (if you want for real texture atlas ) PLEASE... this is want i need to happen... Using albedo WITHOUT texture atlas i would use 'albedoScale' which is a vec2 with the texture.uScale and texture.vScale just like in per material... to make my terrain textures scale or tile or repeat or whatever you call it was this: surfaceAlbedo = texture2D(albedoSampler, vAlbedoUV * albedoScale + uvOffset); albedoScale might contain a value like vec2(5.0, 5.0)... So the texture would get 'tiled or repeated' now i have PACKED all my textures into an atlas and assign to albedoSampler... I also send a free uniforms to hold the rect info for the texture within the texture atlas so now to offset the vAlbedoUV ... I do this: vec2 newUV = vec2((vAlbedoUV.x * splatmapRect1.w) + splatmapRect1.x, (vAlbedoUV.y * splatmapRect1.z) + splatmapRect1.y); surfaceAlbedo = texture2D(albedoSampler, newUV * albedoScale + uvOffset); now if scale is ALWAYS 1.0 it works OK... still see border a bit... but the real problem is when i try to multiply the newUV with albedoScale like i was doing for NON texture atlas version... But that does not work ... show the other texture from texture atlas that above 1.0... So i MUST not supposed to APPLY scale at that line of code anymore... i guess it shout be already calculated into newUV ... I guess... That what i need help with... Applying the uScale and vScale for tile and repeat just like you normally for NON texture atlas: Basically convert this code to use Texture Atlas with tiling support: vec2 newUV = vec2((vAlbedoUV.x * splatmapRect1.w) + splatmapRect1.x, (vAlbedoUV.y * splatmapRect1.z) + splatmapRect1.y); surfaceAlbedo = texture2D(albedoSampler, newUV * albedoScale + uvOffset); Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 57 minutes ago, NasimiAsl said: http://www.babylonjs-playground.com/#1ODVTX#9 http://www.babylonjs-playground.com/#1ODVTX#13 Also... I am still a newbie.... I can't really read your shader code using that ShaderBuilder API... I can tell what is what Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 8, 2017 Share Posted April 8, 2017 HMM i dont know about albodo uv but you can convert any uv to atlas uv use with this : 1: float left = 128.;\ // sub Image position pixel float top = 384.;\ // sub Image position pixel float width = 128.;\ // sub Image size pixel float height = 64.;\ // sub Image size pixel float WIDTH = 512.;\ // image size float HEIGHT = 512.;\ // image size \ 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 = 4.;\ // sub Image repeat pixel float tile_y = 4.;\ // sub Image repeat pixel \ vec2 newUvAtlas = vec2( mod( vuv.x*tile_x , uv_w ) +uv_x , mod(vuv.y*tile_y ,uv_h)+uv_y );') http://www.babylonjs-playground.com/#1ODVTX#14 or float tile = 4.;\ vec2 newUvAtlas = vec2(uv_x,uv_y)+vec2(uv_w,uv_h)* fract(vuv*tile); http://www.babylonjs-playground.com/#1ODVTX#16 but you can see edges problem i have one way to fix that problem but i don't know that is good or not for that 1. : make new rep Photo from your old Pic 2 : use new photo in your atlas 3.: find tile edge : http://www.babylonjs-playground.com/#1ODVTX#20 4 : find edge uvs and replace that in current that is more mathematical stuff but we can make it like easy function http://www.babylonjs-playground.com/#1ODVTX#21 Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 Wow that seems like a lot of EXTRA work to get Texture Atlas to work... I can't just PHOTOSHOP the texture atlas to have those WRAPPING version of the texture either... these will be terrain textures used to paint the terrain splats with... I can't believe GLSL does not have some texture2D() that we could pass a rect to difine the actual area within the texture as a VIEWPORT so to speak then we do texture coordinates like normal. I guess i might just have to take BACK down the splatmapping down to 6 MAX splats (6 diffuse and 6 normals plus 1 mixmap for a total of 13 texture images units... plus 3 for PBR pipeline ) as separate textures this will MAX out the MAX_TEXTURE_IMAGE_UNITS ... Texture Atlas would have been sweet for terrains Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 8, 2017 Author Share Posted April 8, 2017 BTW... This worked... Just has borders... hopefully can figure out a better way to get rid of borders. But this DID work for tiling in the texture atlas: // Primary splat textures if (atlasInfos > 0.0 && atlasRects > 0.0) { float tile1 = 5.0; vec2 atlas1UV = vec2(atlasRect1.x, atlasRect1.y) + vec2(atlasRect1.w, atlasRect1.z) * fract(vTerrainUV * tile1); vec4 atlas1Color = texture2D(albedoSampler, atlas1UV + uvOffset); splatColor = atlas1Color * baseColor1.r; } Hope we get the border issue worked out WITHOUT some many manual steps to prepare the texture image Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 8, 2017 Share Posted April 8, 2017 i am glad anyway thanks i most check texture i think texture is change (a little blur ? maybe @Wingnut know something about it ) :Hm Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 9, 2017 Author Share Posted April 9, 2017 17 hours ago, NasimiAsl said: http://www.babylonjs-playground.com/#1ODVTX#7 we have this conversation but we don't continue that for find good result any way i am now on custom material This seems to be tiling ... i can't tell if there is border problem because the design of the texture... but if it is it is noticeable than the fract() version. So is all the magic in this code... i can't tell what is going on because of all the shader builder and dynamic string building as apposed to separate vertex and fragment .fx files.. So what is this stuffing doing ? Does it take a tile vale like tile = 4. into account ? From playground #7 var plan = BABYLON.Mesh.CreateGround("a", 50, 50, 10, scene); plan.material = new BABYLONX.ShaderBuilder() .SetUniform('tileInd','vec4') .InLine('vec2 newUv =vec2( mod( vuv.x*3.,1.0)/3.+1./3. , mod( vuv.y*3.,1.0)/3.+2./3.);') .Map({ path: 'http://i.imgur.com/vN2QxSo.jpg' ,uv:'newUv ' }) .InLine('\ float x_b = 0.;\ if(mod(newUv.x, 1. / 3.) < 0.1 / 3.0) x_b = mod(newUv.x, 1. / 3.) * 3. * 10.; \ else if(mod(newUv.x,1./3.) > 0.9 /3.0 ) x_b = 1.-(mod(newUv.x,1./3.)-0.9/3.)*3.*10.;\ else x_b = 1.;\ x_b = 1.-x_b;') .Reference(1,BABYLONX.Helper().Map({ path: 'http://i.imgur.com/vN2QxSo.jpg' , uv:'vec2( mod( vuv.x*3.+0.5,1.0)/3.+1./3. , mod( vuv.y*3.,1.0)/3.+2./3.) ' }).Build()) .InLine('\ float y_b = 0.;\ if(mod(newUv.y, 1. / 3.) < 0.1 / 3.0) y_b = mod(newUv.y, 1. / 3.) * 3. * 10.; \ else if(mod(newUv.y,1./3.) > 0.9 /3.0 ) y_b = 1.-(mod(newUv.y,1./3.)-0.9/3.)*3.*10.;\ else y_b = 1.;\ y_b = 1.-y_b;') .Reference(2,BABYLONX.Helper().Map({ path: 'http://i.imgur.com/vN2QxSo.jpg' , uv:'vec2( mod( vuv.x*3. ,1.0)/3.+1./3. , mod( vuv.y*3.+0.5,1.0)/3.+2./3.) ' }).Build()) .InLine('\ float xy_b = 0.;\ xy_b = min(x_b,y_b);') .Reference(3,BABYLONX.Helper().Map({ path: 'http://i.imgur.com/vN2QxSo.jpg' , uv:'vec2( mod( vuv.x*3.+0.5 ,1.0)/3.+1./3. , mod( vuv.y*3.+0.5,1.0)/3.+2./3.) ' }).Build()) .InLine('\ result = result*(1.-y_b)+result_2*y_b;\ result = result*(1.-x_b)+result_1*x_b;\ result = result*(1.-xy_b)+result_3*xy_b;\ ') //}) .BuildMaterial(scene); This seems to work... why did dis continue for good reason ??? Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 9, 2017 Author Share Posted April 9, 2017 18 hours ago, NasimiAsl said: HMM i dont know about albodo uv but you can convert any uv to atlas uv use with this : 1: float left = 128.;\ // sub Image position pixel float top = 384.;\ // sub Image position pixel float width = 128.;\ // sub Image size pixel float height = 64.;\ // sub Image size pixel float WIDTH = 512.;\ // image size float HEIGHT = 512.;\ // image size \ 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 = 4.;\ // sub Image repeat pixel float tile_y = 4.;\ // sub Image repeat pixel \ vec2 newUvAtlas = vec2( mod( vuv.x*tile_x , uv_w ) +uv_x , mod(vuv.y*tile_y ,uv_h)+uv_y );') http://www.babylonjs-playground.com/#1ODVTX#14 or float tile = 4.;\ vec2 newUvAtlas = vec2(uv_x,uv_y)+vec2(uv_w,uv_h)* fract(vuv*tile); http://www.babylonjs-playground.com/#1ODVTX#16 but you can see edges problem i have one way to fix that problem but i don't know that is good or not for that 1. : make new rep Photo from your old Pic 2 : use new photo in your atlas 3.: find tile edge : http://www.babylonjs-playground.com/#1ODVTX#20 4 : find edge uvs and replace that in current that is more mathematical stuff but we can make it like easy function http://www.babylonjs-playground.com/#1ODVTX#21 Yo @NasimiAsl ... Whatever your doing in here http://www.babylonjs-playground.com/#1ODVTX#21 looks like its working, but i still can really tell whats going on in all the ShaderBuilder text string building of the actual shader... can you send me the .fx files for this so i can study what is what... mayday put a few param names instead of all the HARD CODED values... had to tell what is supposed to be what? I actually have an array of all the texture right before i pack them in texture atlas... could i just take pixels from left edge and put them on right edge and take pixel from top edge and put on bottom edge... Is there some algorithm to iterate thru the pixels of an image and do that... and most of all WOULD THAT WORK i could image if something like that could work... would make the shader faster by not having to do as much math for each pixel at runtime instead of encoding that into the texture when i pack into texture map... What do you think? @Deltakosh What do think as well... Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted April 9, 2017 Share Posted April 9, 2017 hi again in github : https://github.com/BabylonJS/Extensions/tree/master/ShaderBuilder documentation : http://cdn.rawgit.com/RNasimiAsl/Extensions/master/ShaderBuilder/Documentation/ShaderBuilderReferences.html you can find the shader in BABYLON.Effect.ShaderStore BABYLON.Effect.ShadersStore["ShaderBuilder_1PixelShader"] BABYLON.Effect.ShadersStore["ShaderBuilder_1VertexShader"] and about other way i think i need test a not blur texture ( like ddr or bmp ) maybe for the border problem all hard terms define in this class export class ShaderMaterialHelperStatics { static Dark = false; static Light = true; static PrecisionHighMode = 'highp'; static PrecisionMediumMode = 'mediump'; static face_back = "!gl_FrontFacing"; static face_front = "gl_FrontFacing"; static AttrPosition = 'position'; static AttrNormal = 'normal'; static AttrUv = 'uv'; static AttrUv2 = 'uv2'; static AttrTypeForPosition = 'vec3'; static AttrTypeForNormal = 'vec3'; static AttrTypeForUv = 'vec2'; static AttrTypeForUv2 = 'vec2'; static uniformView = "view"; static uniformWorld = "world"; static uniformWorldView = "worldView"; static uniformViewProjection = "viewProjection"; static uniformWorldViewProjection = "worldViewProjection"; static uniformStandardType = "mat4"; static uniformFlags = "flags"; static Mouse = "mouse"; static Screen = "screen"; static Camera = "camera"; static Look = "look"; static Time = "time"; static GlobalTime = "gtime"; static Position = "pos"; static WorldPosition = "wpos"; static Normal = "nrm"; static WorldNormal = "wnrm"; static Uv = "vuv"; static Uv2 = "vuv2"; static Center = 'center'; static ReflectMatrix = "refMat"; static Texture2D = "txtRef_"; static TextureCube = "cubeRef_"; static IdentityHelper: number; constructor() { } } Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 9, 2017 Author Share Posted April 9, 2017 55 minutes ago, NasimiAsl said: and about other way i think i need test a not blur texture ( like ddr or bmp ) maybe for the border problem .png cleared up the blur... even the blending between splats look good.... ALTHOUGH I STILL HAVE BORDER PROBLEM... i don't understand your fixing up the image approach... can i do that i code since i have the width and height of each texture and an array to the actual pixels ??? Here is shot (WITH BORDER PROBLEM) but everything ELSE looks good to me Here is Unity Version of terrain in game editor: Here is my BabylonJS Toolkit Made Export of that terrain (STILL HAS BORDER PROBLEM... But everything else looks good): Not bad ehh All splatmaps packed in a single 4K texture atlas (small in size) All terrain splat textures encoded into another texture atlas 4k All normal maps encoded into another texture atlas 4k as well The old way... if you have a fully splatted with normal maps... that would require 28 texture just to have the actual splat mapping of the terrain (not to mention the light map and environment reflection textures too).. so up 30 separate textures would have to load and your browser would have to support at least 32 MAX_TEXTURE_IMAGE_UNITS (i think only 64-bit windows Chrome support 32... most others support 16 and IOS support 8) But now i only and 1 additional texture to the normal PBR pipeline used to render the terrain... and is 'SplatmapTexture' I stick the terrain texture atlas in 'albedoSampler' and the normals texture atlas in 'bumpSampler' and now only 3 total textures for the splatting and 2 or 3 for the PBR light map and reflection coming from the environment... for a total of only 6 MAX_TEXTURE_IMAGE_UNITS was used to produced the splatmap terrain you see above Just gotta figure out the border thing ANYBODY ... ANY THOUGHTS ON THE TEXTURE ATLAS TILING BORDER ISSUE ... PLEASE ... CHIME IN Wingnut 1 Quote Link to comment Share on other sites More sharing options...
BitOfGold Posted April 9, 2017 Share Posted April 9, 2017 I think you have two options:1. Padding When getting the texture data with Texture2D, the value it returns depends on the mipmap level (from 4k down to 2x2pixels), and trilinear filtering. This reads not one but from many texture values. So when u or v is near 1.0 or 0.0, you get the texture value from the edge of the other texture rectangle. And because of mipmapping, this is not one pixel (texel), can be many more nto the other texture rectangle. I think the only way this will work is padding the textures by some pixels, like in your 4k textures, use 1016x1016 rectangles with 4 pixel padding on every side (with the textures "mirrored out" on the sides) This works down to the 4th mipmap level, wich may be far enough. 2. Clamping You can clamp the u,v values like this vTerrainUV = clamp(fract(vTerrainUV),vec2(0.00390625),vec2(0.9960935)); This will dampen the border effect a bit (u,v stays within the texture in the first few mipmaps), but it will cause a 8 texel "band" in the texture. values are 4/1024, 1.0-4/1024 Or you can try this with 1/1024. Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 9, 2017 Author Share Posted April 9, 2017 1 hour ago, BitOfGold said: I think you have two options:1. Padding When getting the texture data with Texture2D, the value it returns depends on the mipmap level (from 4k down to 2x2pixels), and trilinear filtering. This reads not one but from many texture values. So when u or v is near 1.0 or 0.0, you get the texture value from the edge of the other texture rectangle. And because of mipmapping, this is not one pixel (texel), can be many more nto the other texture rectangle. I think the only way this will work is padding the textures by some pixels, like in your 4k textures, use 1018x1018 rectangles with 4 pixel padding on every side (with the textures "mirrored out" on the sides) This works down to the 4th mipmap level, wich may be far enough. 2. Clamping You can clamp the u,v values like this vTerrainUV = clamp(fract(vTerrainUV),vec2(0.00390625),vec2(0.9960935)); This will dampen the border effect a bit (u,v stays within the texture in the first few mipmaps), but it will cause a 8 texel "band" in the texture. values are 4/1024, 1.0-4/1024 Or you can try this with 1/1024. Yo @BitOfGold ... Check this out... This is my texture packing code in c# that i use to encoding all my texture... I add a section where i loop thru and have a source pixel buffer and a dest pixel buffer.... Can you please show me to add the image and mirror the edges ... this is the perfect spot to do that pixel work: // Encode Texture Atlas Padding List<Texture2D> paddingBuffer = new List<Texture2D>(); if (scalingBuffer.Count > 0) { foreach (var sourceTexture in scalingBuffer) { Color[] sourcePixels = sourceTexture.GetPixels(); Color[] paddingPixels = new Color[sourcePixels.Length]; Texture2D paddingTexture = new Texture2D(sourceTexture.width, sourceTexture.height, sourceTexture.format, false); // TODO: Encode Source Texture Pixel Buffer Into Padding Buffer With Padding And Mirrored Edges int index = 0; for (int y=0; y < sourceTexture.height; y++) { for (int x=0; x < sourceTexture.width; x++) { paddingPixels[index] = sourcePixels[index]; index++; } } paddingTexture.SetPixels(paddingPixels); paddingTexture.Apply(); paddingBuffer.Add(paddingTexture); } } if (paddingBuffer.Count > 0) { result = source.PackTextures(paddingBuffer.ToArray(), texturePadding, textureAtlasSize, false); source.Apply(); } Right now i just copy the exact pixel from source to dest... but this are (even if not this looping structure ... please change it to work) // TODO: Encode Source Texture Pixel Buffer Into Padding Buffer With Padding And Mirrored Edges int index = 0; for (int y=0; y < sourceTexture.height; y++) { for (int x=0; x < sourceTexture.width; x++) { paddingPixels[index] = sourcePixels[index]; index++; } } Dude... I would be your best friend Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 9, 2017 Author Share Posted April 9, 2017 Just for reference... Here is my Whole texture packing static function: public static Rect[] PackTextureAtlas(Texture2D source, Texture2D[] textures, int textureAtlasSize = 4096, int maxTextureImageSize = 0, bool bilinearScaling = true, int texturePadding = 0) { Rect[] result = null; if (textures != null && textures.Length > 0) { // Enforce Texture Packing Scale List<Texture2D> scalingBuffer = new List<Texture2D>(); foreach (var texture in textures) { Texture2D item = texture.Copy(); if (maxTextureImageSize > 0 && (item.width > maxTextureImageSize || item.height > maxTextureImageSize)) { if (bilinearScaling) { TextureScale.Bilinear(item, maxTextureImageSize, maxTextureImageSize); } else { TextureScale.Point(item, maxTextureImageSize, maxTextureImageSize); } } scalingBuffer.Add(item); } // Encode Texture Atlas Padding List<Texture2D> paddingBuffer = new List<Texture2D>(); if (scalingBuffer.Count > 0) { foreach (var sourceTexture in scalingBuffer) { Color[] sourcePixels = sourceTexture.GetPixels(); Color[] paddingPixels = new Color[sourcePixels.Length]; Texture2D paddingTexture = new Texture2D(sourceTexture.width, sourceTexture.height, sourceTexture.format, false); // TODO: Encode Source Texture Pixel Buffer Into Padding Buffer With Padding And Mirrored Edges int index = 0; for (int y=0; y < sourceTexture.height; y++) { for (int x=0; x < sourceTexture.width; x++) { paddingPixels[index] = sourcePixels[index]; index++; } } paddingTexture.SetPixels(paddingPixels); paddingTexture.Apply(); paddingBuffer.Add(paddingTexture); } } if (paddingBuffer.Count > 0) { result = source.PackTextures(paddingBuffer.ToArray(), texturePadding, textureAtlasSize, false); source.Apply(); } } return result; } Quote Link to comment Share on other sites More sharing options...
MackeyK24 Posted April 10, 2017 Author Share Posted April 10, 2017 19 hours ago, BitOfGold said: 1. Padding When getting the texture data with Texture2D, the value it returns depends on the mipmap level (from 4k down to 2x2pixels), and trilinear filtering. This reads not one but from many texture values. So when u or v is near 1.0 or 0.0, you get the texture value from the edge of the other texture rectangle. And because of mipmapping, this is not one pixel (texel), can be many more nto the other texture rectangle. I think the only way this will work is padding the textures by some pixels, like in your 4k textures, use 1016x1016 rectangles with 4 pixel padding on every side (with the textures "mirrored out" on the sides) This works down to the 4th mipmap level, wich may be far enough. @BitOfGold are you around... ? Can you explain this a little more... so when you use 1016 instead of 1024 ... A... Are you saying actually scale the whole image down from 1024 to 1016 B... Are you say just "wipe out" the first 4 pixels all around the 1024 image and then replace those wiped out pixel with copies from the the other side of the image.. Are you say i can just open a texture in paint program gram the first few pixels on the left edege copy them ... flip them... them move to the far right edge... What about over lapping corners ? BTW ... i only have the 1 base mip map level... I never encode any pixels in the other mipmap level... All my GetPixel and SetPixel code from unity only uses mipmap level 0... So i don't see there there could ever be more than 1 mipmap from the terrain splats coming from unity. I have access to the pixel data but don't quite understand what are saying i have to do to the image Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.