Selective hue rotation (xy)

  • Posts: 59
1 week 6 days ago - 1 week 5 days ago #1 by crabshank
Allows hue rotations for 12 discrete colours, same as here .


#include "ReShadeUI.fxh";

uniform bool Red = true;
uniform float Red_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Orange = true;
uniform float Orange_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Yellow = true;
uniform float Yellow_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Chartreuse_Lime = true;
uniform float Chartreuse_Lime_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Green = true;
uniform float Green_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Spring_green = true;
uniform float Spring_green_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Cyan = true;
uniform float Cyan_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Azure__Sky_blue = true;
uniform float Azure__Sky_blue_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Blue = true;
uniform float Blue_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Violet__Purple = true;
uniform float Violet__Purple_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Magenta__Pink = true;
uniform float Magenta__Pink_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;
uniform bool Reddish_pink = true;
uniform float Reddish_pink_Rotate < __UNIFORM_SLIDER_FLOAT1
	ui_min = -180.0; ui_max=180.0;
> = 0;

#include "ReShade.fxh";

float3 rgb2hsv(float3 c)
{
    float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    float4 p = lerp(float4(c.bg, K.wz), float4(c.gb, K.xy), step(c.b, c.g));
    float4 q = lerp(float4(p.xyw, c.r), float4(c.r, p.yzx), step(p.x, c.r));
 
    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return float3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}


float3 hsv2rgb(float3 c)
{
    float4 K = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    float3 p = abs(frac(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * lerp(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
//Source: http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl

float3 rgb2xyY(float3 rgb){

    float3 rgbNew=float3(rgb.r,rgb.g,rgb.b); 

	float3 XYZ;

	rgbNew=(rgbNew > 0.0404482362771082)?pow(abs((rgbNew+0.055)/1.055),2.4):rgbNew/12.92;

		XYZ.x = dot(float3(0.4124564,0.3575761, 0.1804375), rgbNew);
		XYZ.y = dot(float3(0.2126729,0.7151522,0.072175), rgbNew);
		XYZ.z = dot(float3(0.0193339,0.119192,0.9503041), rgbNew);

	float XYZtot=XYZ.x+XYZ.y+XYZ.z;
	
	float x=XYZ.x/XYZtot;
	float y=XYZ.y/XYZtot;
	
	return float3(x,y,XYZ.y);

}
//Source: https://stackoverflow.com/a/45263428; http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html

float3 xyY2rgb(float3 xyY){

float Y=xyY.z;
float X=(Y/xyY.y)*xyY.x;
float Z=(Y/xyY.y)*(1-xyY.x-xyY.y);

float3 RGB;

 RGB.r = dot(float3(3.2404542,-1.5371385,-0.4985314),float3(X,Y,Z));
 RGB.g = dot(float3(-0.969266,1.8760108,0.041556),float3(X,Y,Z));
 RGB.b = dot(float3(0.0556434,-0.2040259,1.0572252),float3(X,Y,Z));

	RGB=( RGB > 0.00313066844250063 )?1.055 * pow(abs(RGB),1/2.4) - 0.055:12.92 *RGB;

return RGB;

}
//Source: http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html

float hue_rotate(float hue,float rot){rot*=pow(360,-1);float r=hue+rot;if(r<0){return 1+r;}else if(r>1){return r-1;}else{return r;}} 

float4 selHueRotPass(float4 vpos : SV_Position, float2 texcoord : TexCoord) : SV_Target
{

float4 c0=tex2D(ReShade::BackBuffer, texcoord);

float3 rgbLin=(c0.rgb > 0.0404482362771082)?pow(abs((c0.rgb+0.055)/1.055),2.4):c0.rgb/12.92;

float Y_og = dot(float3(0.2126729,0.7151522,0.072175), rgbLin);

float4 c1=c0;
float3 c0_hsv=rgb2hsv(c0.rgb);

int hue=floor(c0_hsv.x*3600);
int grey=(((c0.r==c0.g)&&(c0.g==c0.b))||(c0_hsv.y==0))?1:0;

float new_hue=0;

[flatten]if((hue>=3535)||(((hue>=0) && (hue<75))&&(grey==0))){
new_hue=((Red==true)&&(Red_Rotate!=0))?hue_rotate(c0_hsv.x,Red_Rotate):c0_hsv.x;
}else if((hue>=75) && (hue<375)){
new_hue=((Orange==true)&&(Orange_Rotate!=0))?hue_rotate(c0_hsv.x,Orange_Rotate):c0_hsv.x;
}else if((hue>=375) && (hue<675)){
new_hue=((Yellow==true)&&(Yellow_Rotate!=0))?hue_rotate(c0_hsv.x,Yellow_Rotate):c0_hsv.x;
}else if((hue>=675) && (hue<975)){
new_hue=((Chartreuse_Lime==true)&&(Chartreuse_Lime_Rotate!=0))?hue_rotate(c0_hsv.x,Chartreuse_Lime_Rotate):c0_hsv.x;
}else if((hue>=975) && (hue<1275)){
new_hue=((Green==true)&&(Green_Rotate!=0))?hue_rotate(c0_hsv.x,Green_Rotate):c0_hsv.x;
}else if((hue>=1275) && (hue<1575)){
new_hue=((Spring_green==true)&&(Spring_green_Rotate!=0))?hue_rotate(c0_hsv.x,Spring_green_Rotate):c0_hsv.x;
}else if((hue>=1575) && (hue<1875)){
new_hue=((Cyan==true)&&(Cyan_Rotate!=0))?hue_rotate(c0_hsv.x,Cyan_Rotate):c0_hsv.x;
}else if((hue>=1875) && (hue<2175)){
new_hue=((Azure__Sky_blue==true)&&(Azure__Sky_blue_Rotate!=0))?hue_rotate(c0_hsv.x,Azure__Sky_blue_Rotate):c0_hsv.x;
}else if((hue>=2175) && (hue<2475)){
new_hue=((Blue==true)&&(Blue_Rotate!=0))?hue_rotate(c0_hsv.x,Blue_Rotate):c0_hsv.x;
}else if((hue>=2475) && (hue<3075)){
new_hue=((Violet__Purple==true)&&(Violet__Purple_Rotate!=0))?hue_rotate(c0_hsv.x,Violet__Purple_Rotate):c0_hsv.x;
}else if((hue>=3075) && (hue<3375)){
new_hue=((Magenta__Pink==true)&&(Magenta__Pink_Rotate!=0))?hue_rotate(c0_hsv.x,Magenta__Pink_Rotate):c0_hsv.x;
}else if((hue>=3375) && (hue<3535)){
new_hue=((Reddish_pink==true)&&(Reddish_pink_Rotate!=0))?hue_rotate(c0_hsv.x,Reddish_pink_Rotate):c0_hsv.x;
}

c1.rgb=xyY2rgb(float3(rgb2xyY(hsv2rgb(float3(new_hue,c0_hsv.yz))).xy,Y_og));

return c1;

}

technique Selective_hue_rotate_xy
{
	pass
	{
		VertexShader = PostProcessVS;
		PixelShader = selHueRotPass;
	}
}

HLSL version here .

Please Log in or Create an account to join the conversation.