The task is: shader takes in a constant color, then generates pixel colors according to their positions by replacing two of four color components (RGBA) with texture coordinates. With hardcoded component set it will be like:
float4 inputColor : register(c0);
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = 0;
color.a = inputColor.a;
color.r = inputColor.r;
color.g = uv.x;
color.b = uv.y;
return color;
}
Now I'd like to pass in a parameter(s) specifying which components should be replaced with uv.x and uv.y. Let's say inputColor has -1 and -2 in these components. Or there are uint xIndex and yIndex parameters specifying positions in vector4 to be replaced. HLSL does not allow "color[xIndex] = uv.x".
Currently I've done that in ugly way with a bunch of if-else. But I feel like there is some cross-product or matrix multiplication solution. Any ideas?
You could work with two additional vectors as channelmasks. It works like indexing, but with vector operators.
float4 inputColor : register(c0);
float4 uvx_mask : register(c1); //e.g. (0,0,1,0)
float4 uvy_mask : register(c2); // e.g. (0,0,0,1)
float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 color = 0;
// replacing uvx channel with uv.x
color = lerp(inputColor, uv.x * uvx_mask, uvx_mask);
// replacing uvy channel with uv.y
color = lerp(color , uv.y * uvy_mask, uvy_mask);
return color; //in this example (inputColor.r, inputColor.g, uv.x, uv.y)
}
If you need even the last bit of performance you could work alternative with the preprocessor (#define, #ifdef) to build the right code on demand.