Shader angle between vectors calculation

Hi all

New to shaders but have started making what I think is working code heheh :slight_smile:

Im trying to calculate what colour a given pixel is given a set of discrete colours. i.e. I have defined:

Properties {
	_MainTex ("Base (RGB)", 2D) = "white" {}
	_Green ("Green", Color) = (0.1921, 0.5921, 0.0196, 0) 
	_Yellow ("Yellow", Color) = (0.9921, 0.9961, 0.0078, 0) 
	_Orange ("Orange", Color) = (0.9961, 0.3961, 0.0274, 0) 
	_Red ("Red", Color) = (0.8196, 0.0196, 0.0313, 0) 
	_Purple ("Purple", Color) = (0.3882, 0.0078, 0.3803, 0) 
	_Blue ("Blue", Color) = (0.01176, 0.2039, 0.6078, 0) 

Since colours are just 3d vectors I can find the angle between the current pixel’s colour and those 6, see which is smallest and it will be counted as ‘that’ colour.

My next part is:

fixed4 frag (v2f_img i) : COLOR

	fixed4 original = tex2D(_MainTex, i.uv);
	fixed4 output = tex2D(_MainTex, i.uv);
	float angleG = angleBetween(_Green, original);
	float angleY = angleBetween(_Yellow, original);
	float angleO = angleBetween(_Orange, original);
	float angleR = angleBetween(_Red, original);
	float angleP = angleBetween(_Purple, original);
	float angleB = angleBetween(_Blue, original);
	if(	   angleG < angleY 
		&& angleG < angleO 
		&& angleG < angleR 
		&& angleG < angleP 
		&& angleG < angleB) {
		output = fixed4(0,0,0,0);
	return output;

With the sub function:

inline float angleBetween(fixed4 colour, fixed4 original) {
	return acos(dot(colour, original)/(colour.length*original.length));

The string of compares in the if statement are to see if the colour is closest to green, ie. the angle between green and that colour is lower than the other 5, I just set it to black to test it working.

I have created a c# script which does the same check, the list of discrete colours, testing the angle and finding the lowest. And it works prefectly across the whole colour palette. But im stuck why its not working with this! I can set that if statement to a bunch of random compares so it is definitely changing values but I figured this logic would at least make all greenish pixels black.

Like I said, Im new to shaders so I may be doing something basic wrong :stuck_out_tongue:

Correct me if I’m wrong, but shouldn’t your comparisons be using > instead of <, since the dot product of two unit vectors increases in magnitude towards 1 as they point more in the same direction?

Ok found the problem. I was testing green by looking at my green grass. However it was calculating my grass was closer to yellow than green :stuck_out_tongue: so it was working, but the spread of the 6 colours is a bit close.

Solved :slight_smile: