OSL – ChannelSwitcher

An OSL shader for switching channels. You input two textures and then you can shuffle the RGBA channels around to make a new output. So for example you could have the red and green channels of texture A, green as a black output, and the alpha from texture B.
Or you could switch all the channels to use the red channel, so you’d have a monochrome output.

channelswitcher_rndr

Download link
http://www.rensheeren.com/osl/channelSwitcher_tex_v002.osl
Right-click and save as.

Features
– Switch or shuffle the channels from two inputs around.
– You also choose full white or black for a channel.
– Or invert the channel.

How to use
VRay:
– Create a VRay OSL Texture map.
– Load in the downloaded OSL shader.
– Plug in two maps, and set the switch modes.

channelswitcher_ui

channelswitcher_node

UI Properties
tex_input_1
– Texture input 1.
tex_input_2
– Texture input 2.
output_[channel]
– The channel to use for this specific output channel.
invert_[channel]
– Invert this channel.

Modes:
1 – red1
2 – green1
3 – blue1
4 – alpha1
5 – red2
6 – green2
7 – blue2
8 – alpha2
9 – one
10 – zero

Code

/*

channelSwitcher_tex_v002


By Rens Heeren (mail [at] rensheeren [dot] com)

Info Page: http://www.rensheeren.com/blog/osl-channelswitcher/


Use as an OSL texture, not as an OSL material.


An OSL shader for switching channels. You input two textures and then
you can shuffle the RGBA channels around to make a new output. So for example
you could have the red and green channels of texture A, green now as black, 
and the alpha from texture B.

Usage:
- Plug in two maps, and set the switch modes.

Modes:
1 - red1
2 - green1
3 - blue1
4 - alpha1
5 - red2
6 - green2
7 - blue2
8 - alpha2
9 - one
10 - zero



Use at your own risk.



2015-12-28 - v001 - Created (rh)
2016-05-29 - v002 - Added multi-renderer support. (rh)

*/


//////////////////////////////


float fn_channelMix(color c_in1, color c_in2, float f_in1, float f_in2, int i_switch, int i_invert)
{
	float f_mixout = 0.0;
	if (i_switch == 1){f_mixout = c_in1[0];}
	if (i_switch == 2){f_mixout = c_in1[1];}
	if (i_switch == 3){f_mixout = c_in1[3];}
	if (i_switch == 4){f_mixout = f_in1;}
	if (i_switch == 5){f_mixout = c_in2[0];}
	if (i_switch == 6){f_mixout = c_in2[1];}
	if (i_switch == 7){f_mixout = c_in2[2];}
	if (i_switch == 8){f_mixout = f_in2;}
	if (i_switch == 9){f_mixout = 1.0;}
	if (i_switch == 10){f_mixout = 0.0;}
	if (i_invert){f_mixout = 1.0 - f_mixout;}
	return f_mixout;
}


/////////////////////////////////


shader
channelSwitcher_tex_v002
(
#ifdef __VRAY_OSL__

	string tex_input1 = "",
	string tex_input2 = "",
	
#else
	
	color tex_input1 = color(0),
	color tex_input2 = color(0),
	float texAlpha_input1 = 0,
	float texAlpha_input2 = 0,
	
#endif
	
	int output_red = 1
	[[ string widget = "mapper",
	string description = "1-red1 / 2-green1 / 3-blue1 / 4-alpha1 / 5-red2 / 6-green2 / 7-blue2 / 8-alpha2 / 9-one / 10-zero",
	string options = "red1:1|green1:2|blue1:3|alpha1:4|red2:5|green2:6|blue2:7|alpha2:8|one:9|zero:10" ]],
	int invert_red = 0
	[[ string widget = "checkBox" ]],
	
	int output_green = 2
	[[ string widget = "mapper",
	string description = "1-red1 / 2-green1 / 3-blue1 / 4-alpha1 / 5-red2 / 6-green2 / 7-blue2 / 8-alpha2 / 9-one / 10-zero",
	string options = "red1:1|green1:2|blue1:3|alpha1:4|red2:5|green2:6|blue2:7|alpha2:8|one:9|zero:10" ]],
	int invert_green = 0
	[[ string widget = "checkBox" ]],
	
	int output_blue = 3
	[[ string widget = "mapper",
	string description = "1-red1 / 2-green1 / 3-blue1 / 4-alpha1 / 5-red2 / 6-green2 / 7-blue2 / 8-alpha2 / 9-one / 10-zero",
	string options = "red1:1|green1:2|blue1:3|alpha1:4|red2:5|green2:6|blue2:7|alpha2:8|one:9|zero:10" ]],
	int invert_blue = 0
	[[ string widget = "checkBox" ]],
	
	int output_alpha = 4
	[[ string widget = "mapper",
	string description = "1-red1 / 2-green1 / 3-blue1 / 4-alpha1 / 5-red2 / 6-green2 / 7-blue2 / 8-alpha2 / 9-one / 10-zero",
	string options = "red1:1|green1:2|blue1:3|alpha1:4|red2:5|green2:6|blue2:7|alpha2:8|one:9|zero:10" ]],
	int invert_alpha = 0
	[[ string widget = "checkBox" ]],
	
	string info_page = "www.rensheeren.com/blog/osl-channelswitcher/"
	  [[ string widget = "string" ]],
	
	output color out_RGB = color(0),
	output float out_A = 0.0
)


/////////////////////////////////////


{
	float f_a1 = 0.0;
	float f_a2 = 0.0;
	color c_rgb1 = color(0);
	color c_rgb2 = color(0);
	
	
#ifdef __VRAY_OSL__

	c_rgb1 = texture(tex_input1, u, v, "alpha", f_a1);
	c_rgb2 = texture(tex_input2, u, v, "alpha", f_a2);
	
#else
	
	c_rgb1 = tex_input1;
	c_rgb2 = tex_input2;
	f_a1 = texAlpha_input1;
	f_a2 = texAlpha_input2;
	
#endif
	
	
	
	int i_invR = invert_red;
	int i_invG = invert_green;
	int i_invB = invert_blue;
	int i_invA = invert_alpha;
	int i_switchR = output_red;
	int i_switchG = output_green;
	int i_switchB = output_blue;
	int i_switchA = output_alpha;
	
	float f_outR = fn_channelMix(c_rgb1, c_rgb2, f_a1, f_a2, i_switchR, i_invR);
	float f_outG = fn_channelMix(c_rgb1, c_rgb2, f_a1, f_a2, i_switchG, i_invG);
	float f_outB = fn_channelMix(c_rgb1, c_rgb2, f_a1, f_a2, i_switchB, i_invB);
	float f_outA = fn_channelMix(c_rgb1, c_rgb2, f_a1, f_a2, i_switchA, i_invA);
	
	out_RGB = color(f_outR, f_outG, f_outB);
	out_A = f_outA;	
}