Color comparison in pixel shaders

in pixel shaders at the moment I use the following way to check if two colors are equal:

if (color1.r == color2.r && color1.g == color2.g && color1.b == color2.b)

I wonder if there is a simple way, something like:

if (color1 == color2)

or maybe:

if (color1.rgb == color2.rgb)

Am I asking too much?

What are you trying to do on a higher level? There’s probably a better way to do it.

Mine is a generic question. Since I know little about the HLSL language, I was wondering if there is a method / function / sub that compares two colors to see if they are equal.
In particular, my pixel shader is a simple color replacer. Here is the code:

sampler TextureSampler;

struct PixelShaderOutput
	float4 Position : SV_POSITION;
	float4 Color : COLOR0;
	float2 TextureCoordinates : TEXCOORD0;

float4 OldColor; // Parameter
float4 NewColor; // Parameter

float4 Main(PixelShaderOutput input) : COLOR0
	float4 color = tex2D(TextureSampler, input.TextureCoordinates);
	if (color.a)
		if (color.r == OldColor.r && color.g == OldColor.g && color.b == OldColor.b) // Is there a way to simplify this line?
			color = NewColor;
		color *= input.Color;
	return color;

		PixelShader = compile ps_4_0_level_9_3 Main();

Well if you are trying to get rid of the if statement and replace a color based on rgb i guess maybe something like so.

// 1 or 0 only.
float lerpFlag = saturate( sign(abs( (OldColor.r + OldColor.g + OldColor.b) - (color.r + color.g + color.b))) );
return lerp(NewColor, color, lerpFlag);

Though i dunno what you are trying to say with the color there? If its just supposed to be more then zero then execute? Then just get the sign of it and multiply it with the lerp flag. * sign(color.a);

There’s the any function which tells you if any of the components in a vector are non-zero.

bool isEqual = !any(col1 - col2);

This doesn’t work, because the components can add up to the same number, even if the colors are different.

1 Like

the components can add up to the same number

eh that’s what i get for not testing could be fixed.

float lerpFlag = saturate( sign(abs( ((OldColor.r) + (OldColor.g+2.0f) + (OldColor.b+4.0f)) - (color.r + (color.g+2.0f) + (color.b +4.0f) ))) );


I didn’t know about any that is pretty handy.
Though that raises a question is the bool actually a value like 0 or 1?.

To answer the initial question, similar to any there’s all:

if (color1.r == color2.r && color1.g == color2.g && color1.b == color2.b)

would become

if (all(color1 == color2))

The all function is what I was looking for. And thanks to Jjagg here I get the HLSL documentation.
Thank you all…

1 Like

That does indeed look a lot better than the any version I posted.

I just want to add that if you want to find close color then you can treat it as point in 3d space and do something like if(distanceSquared(color1, color2) < 16)…