Hey there,
im working on a terrain project. The terrain shader uses multiple textures and renders them depending on world height using triplanar mapping. This is the mapping function…
float3 triplanar(float3 pos, float scale, float3 blend, int texIndex) {
float3 scaled = pos / scale;
float3 x_projected = blend.x * UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaled.y, scaled.z, texIndex));
float3 y_projected = blend.y * UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaled.x, scaled.z, texIndex));
float3 z_projected = blend.z * UNITY_SAMPLE_TEX2DARRAY(baseTextures, float3(scaled.x, scaled.y, texIndex));
return x_projected + y_projected + z_projected;
}
To avoid tiling of implemented this techique from here…
float4 TextureNoTile(sampler2D tex, float2 uv)
{
float2 x = uv;
float v = 1.0; // Set your desired 'v' value here
float k = tex2D(_Variation, 0.05 * x).r; // cheap (cache-friendly) lookup
float2 duvdx = ddx(uv);
float2 duvdy = ddy(uv);
float l = k * 8.0;
float f = frac(l);
float ia = floor(l); // my method
float ib = ia + 1.0;
float2 offa = sin(float2(3.0, 7.0) * ia); // can replace with any other hash
float2 offb = sin(float2(3.0, 7.0) * ib); // can replace with any other hash
float4 cola = tex2Dgrad(tex, uv + v * offa, duvdx, duvdy);
float4 colb = tex2Dgrad(tex, uv + v * offb, duvdx, duvdy);
return lerp(cola, colb, smoothstep(0.2, 0.8, f - 0.1 * dot(cola - colb, 1.0)));
}
Tiling is no longer visible. Now I need to combine the shaders, but I see a few problems here:
-
I’m using about 5 texture layers for the terrain and I plan on targeting mobile. I feel like sampling twice for each layer to avoid tiling is pretty expensive especially for the plattform. Do you know of any techniques to avoid having so many gpu instructions to achieve this?
-
As far as I know UNITY_SAMPLE_TEX2DARRAY can not be called providing a gradient ddy/ddy. Is there another way without reimplement it. I didn’t find any resources explaining what TEX2DARRAY actually does behind the scenes. OR…
-
I would like to not use texture arrays at all as it is not supported on OpenGL ES 2.0. Is it a good idea to pack all textures into one instead, and sample with tex2Dgrad (offsetting the uvs for each layer). The number of textures are about 512x512 large.
Thank you for your help!