I am trying to implement a weight-based height blending shader. First, I try to find the 4 layers with the highest weight (layer alpha). Then mix from these 4 layers.
Below is my simplified code:
// find the 4 layers with the largest weight.
void find_max_layers(float2 texCoord, out int4 max_indics)
{
max_indics = int4(-1, -1, -1, -1);
max_weights = float4(.0001, .0001, .0001, .0001);
[unroll]
for (int Layer = 0; Layer < 2; ++Layer) // 2 is for test...
{
const int surfaceIndex = (int)cSurfaceIndex[Layer];
const float alpha = tLayerWeight.Sample(sLayerWeight, float3(texCoord, Layer)).r;
if (alpha > max_weights.x) {
max_indics = int4(surfaceIndex, max_indics.xyz);
max_weights = float4(alpha, max_weights.xyz);
}
else if (alpha > max_weights.y) {
max_indics.yzw = int3(surfaceIndex, max_indics.yz);
max_weights.yzw = float3(alpha, max_weights.yz);
}
else if (alpha > max_weights.z) {
max_indics.zw = int2(surfaceIndex, max_indics.z);
max_weights.zw = float2(alpha, max_weights.z);
}
else if (alpha > max_weights.w) {
max_indics.w = surfaceIndex;
max_weights.w = alpha;
}
}
}
// get surface albedo, normal, height.
half get_surface_color_normal_height(int surface, float3 texCoord, out half3 color)
{
const float surface_tiling[2] = { 64.0f,32.0f }; // hard coded for show my bugs.
const float tiling = surface_tiling[surface];
half4 color_h = tAlbedoMap.Sample(sLinearWrap, float3(texCoord.xy * tiling, surface));
color = color_h.rgb;
return color_h.w;
}
void blend_layers(float3 texCoord, out half3 albedo)
{
int4 surfaceIndics; // [0,1,-1,-1] or [1,0,-1,-1]
find_max_layers(texCoord.xy, surfaceIndics);
half3 colors[4] = { (half3)0 , (half3)0 , (half3)0 , (half3)0 };
/*A: works
if(surfaceIndics.x == 0)
{
get_surface_color_normal_height ( 0 , texCoord , colors [ 0 ] );
get_surface_color_normal_height ( 1 , texCoord , colors [ 1 ] );
}else
{
get_surface_color_normal_height (1 , texCoord , colors [ 0 ] );
get_surface_color_normal_height ( 0 , texCoord , colors [ 1 ] );
}*/
/*B:works
if(surfaceIndics.x == 0)
{
get_surface_color_normal_height ( 0 , texCoord , colors [ 0 ] );
get_surface_color_normal_height ( 1 , texCoord , colors [ 1 ] );
}else
{
get_surface_color_normal_height (0 , texCoord , colors [ 0 ] );
get_surface_color_normal_height ( 1 , texCoord , colors [ 1 ] );
}
*/
//C: error!!!
if (surfaceIndics.x != -1)
{
get_surface_color_normal_height(surfaceIndics.x, texCoord, colors[0]);
}
if (surfaceIndics.y != -1)
{
get_surface_color_normal_height(surfaceIndics.y, texCoord, colors[1]);
}
// output
albedo = (colors[0] + colors[1]) * 0.5;
}
Let me simplify the problem first, I have 2 textures 0,1 that need to be blended. function find_max_layers has only two return values:[0,1,-1,-1] or [1,0,-1,-1].
the code section A and B in function blend_layers works fine.
the output image is : A,B the right result
but the code section C in function blend_layers output unexpected results: C,the error result