Hello everyone! Today I have an inquiry regarding Compute Shaders.
My intention is to whiten the texture of a character in editor to then apply color variations on runtime:
The problem, however, is that I cannot find any shader I am comfortable with.
What I am using right now is a combination of a grayscale + gradient computer shaders, but there are some noisy artifacts.
Since i’m not a shader expert, I’m not sure what is the best option to do the effect I’m searching for (keep the detail of the texture while cleaning the main color). I’m not looking to a perfect result, but I would like to achieve at least clean colors. Maybe something like an edge-detecting shader?
Anyway, here’s what I’m currently using:
Grayscaling
#pragma kernel CSMain
// ( CPU -> GPU )
Texture2D inputTexture;
// ( GPU -> CPU )
RWTexture2D <float4> outputTexture;
int textWidth;
int textHeight;
float Luminance(float3 c)
{
return dot(c, float3(0.22, 0.707, 0.071));
}
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float R = dot(inputTexture[id.xy].r, float3(0.22, 0.707, 0.071)) ;
float G = dot(inputTexture[id.xy].g, float3(0.22, 0.707, 0.071));
float B = dot(inputTexture[id.xy].b, float3(0.22, 0.707, 0.071));
outputTexture[id.xy] = float4(R,G,B, 1);
}
Grading
#pragma kernel CSMain
// ( CPU -> GPU )
Texture2D inputTexture;
// ( GPU -> CPU )
RWTexture2D <float4> outputTexture;
int textWidth;
int textHeight;
float gradientStrenght;
[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
float4 outputColor;
if (id.x == 0 || id.y == 0 || id.x == textWidth - 1 || id.y == textHeight - 1)
{
outputColor = float4(0, 0, 0, 1);
}
else
{
float3 c = inputTexture[float2(id.x - 1, id.y - 1)];
float3 cSampleNegXNegY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x, id.y - 1)];
float3 cSampleZerXNegY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x + 1, id.y - 1)];
float3 cSamplePosXNegY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x - 1, id.y)];
float3 cSampleNegXZerY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x + 1, id.y)];
float3 cSamplePosXZerY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x - 1, id.y + 1)];
float3 cSampleNegXPosY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x, id.y + 1)];
float3 cSampleZerXPosY = float3(c.r, c.g, c.g);
c = inputTexture[float2(id.x + 1, id.y + 1)];
float3 cSamplePosXPosY = float3(c.r, c.g, c.g);
float fSampleNegXNegY = cSampleNegXNegY.x;
float fSampleZerXNegY = cSampleZerXNegY.x;
float fSamplePosXNegY = cSamplePosXNegY.x;
float fSampleNegXZerY = cSampleNegXZerY.x;
float fSamplePosXZerY = cSamplePosXZerY.x;
float fSampleNegXPosY = cSampleNegXPosY.x;
float fSampleZerXPosY = cSampleZerXPosY.x;
float fSamplePosXPosY = cSamplePosXPosY.x;
float edgeX = (fSampleNegXNegY - fSamplePosXNegY) * 0.25 + (fSampleNegXZerY - fSamplePosXZerY) * 0.5 + (fSampleNegXPosY - fSamplePosXPosY) * 0.25;
float edgeY = (fSampleNegXNegY - fSampleNegXPosY) * 0.25 + (fSampleZerXNegY - fSampleZerXPosY) * 0.5 + (fSamplePosXNegY - fSamplePosXPosY) * 0.25;
float fValue = (edgeX + edgeY) / 2.0f;
fValue = 1 - (fValue / gradientStrenght);
outputColor = float4(fValue, fValue, fValue, 1.0);
}
outputTexture[id.xy] = outputColor;
}