So I have written a shader that uses a 32x32x256 Texture3D as a texture atlas, to texture a marching cubes terrain. In the voxel data, the type of voxel, and therefore the texture tile used, is indicated to the shader by the alpha channel of the vertex color of the mesh.
All of this seems to work nicely, except that there is, what I assume to call “bleeding”, on any voxel that is adjacent to a different voxel type. All the other tiles of the atlas are ‘squished’, for lack of a better term, into that voxel’s texture.
Like so…
I havent the slightest clue as to how to approach a solution to these artifacts. Can anyone help me, or point me towards some helpful reading material?
Here is the shader
Properties {
_Tint("Tint", Color) = (0.25, 0.25, 0.25, 1)
_Atlas("Atlas 3D", 3D) = "clear" {}
_Side("Side", 2D) = "white" {}
_Top("Top", 2D) = "white" {}
_Bottom("Bottom", 2D) = "white" {}
_SideScale("Side Scale", Float) = 2
_TopScale("Top Scale", Float) = 2
_BottomScale ("Bottom Scale", Float) = 2
_Rows ("Row Count", Float) = 1
_Clms ("Column Count", FLoat) = 1
}
SubShader {
Tags {
"Queue"="Geometry"
"IgnoreProjector"="False"
"RenderType"="Opaque"
}
Cull Back
ZWrite On
CGPROGRAM
#pragma surface surf Lambert vertex:vert fullforwardshadows
#pragma exclude_renderers flash
#include "UnityCG.cginc"
sampler3D _Atlas;
sampler2D _Side, _Top, _Bottom;
float _SideScale, _TopScale, _BottomScale, _Rows, _Clms;
float4 _Tint;
struct Input {
float3 worldPos;
float3 worldNormal;
float4 color;
float3 tileUV;
};
void vert(inout appdata_full v, out Input o){
UNITY_INITIALIZE_OUTPUT (Input, o);
o.color = v.color;
o.tileUV = v.vertex.zxy + 0.5f ;
}
void surf (Input IN, inout SurfaceOutput o) {
float3 projNormal = saturate(pow(IN.worldNormal * 1.4, 4));
// SIDE X
float3 x = tex3D(_Atlas, frac(float3(IN.tileUV.x,IN.tileUV.z, IN.color.a * 256 * _SideScale ))) * abs(IN.worldNormal.x);
// TOP / BOTTOM
float3 y = 0;
if (IN.worldNormal.y > 0) {
y = tex3D(_Atlas, frac(float3(IN.tileUV.x,IN.tileUV.y, IN.color.a * 256 * _TopScale ))) * abs(IN.worldNormal.y);
} else {
y = tex3D(_Atlas, frac(float3(IN.tileUV.x,IN.tileUV.y, IN.color.a * 256 * _BottomScale ))) * abs(IN.worldNormal.y);
}
// SIDE Z
float3 z = tex3D(_Atlas, frac(float3(IN.tileUV.y,IN.tileUV.z, IN.color.a * 256 * _SideScale ))) * abs(IN.worldNormal.z);
// o.Albedo = z * 0.925f;
o.Albedo = _Tint * lerp(o.Albedo, z, projNormal.z * 0.925f);
o.Albedo = _Tint * lerp(o.Albedo, x, projNormal.x);
o.Albedo = _Tint * lerp(o.Albedo, y, projNormal.y);
}
ENDCG
}
Fallback "Diffuse"
}
Shouldn't it be
– cjdevIN.color.a * 255?