Explorar el Código

VisualShader: Add LinearToSRGB and SRGBToLinear to ColorFunc node

tetrapod00 hace 10 meses
padre
commit
2191df0cea

+ 26 - 1
doc/classes/VisualShaderNodeColorFunc.xml

@@ -40,7 +40,32 @@
 			return vec3(r, g, b);
 			return vec3(r, g, b);
 			[/codeblock]
 			[/codeblock]
 		</constant>
 		</constant>
-		<constant name="FUNC_MAX" value="4" enum="Function">
+		<constant name="FUNC_LINEAR_TO_SRGB" value="4" enum="Function">
+			Converts color from linear color space to sRGB color space using the following formula:
+			[codeblock]
+			vec3 c = clamp(c, vec3(0.0), vec3(1.0));
+			const vec3 a = vec3(0.055f);
+			return mix((vec3(1.0f) + a) * pow(c.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * c.rgb, lessThan(c.rgb, vec3(0.0031308f)));
+			[/codeblock]
+			The Compatibility renderer uses a simpler formula:
+			[codeblock]
+			vec3 c = input;
+			return max(vec3(1.055) * pow(c, vec3(0.416666667)) - vec3(0.055), vec3(0.0));
+			[/codeblock]
+		</constant>
+		<constant name="FUNC_SRGB_TO_LINEAR" value="5" enum="Function">
+			Converts color from sRGB color space to linear color space using the following formula:
+			[codeblock]
+			vec3 c = input;
+			return mix(pow((c.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), c.rgb * (1.0 / 12.92), lessThan(c.rgb, vec3(0.04045)));
+			[/codeblock]
+			The Compatibility renderer uses a simpler formula:
+			[codeblock]
+			vec3 c = input;
+			return c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);
+			[/codeblock]
+		</constant>
+		<constant name="FUNC_MAX" value="6" enum="Function">
 			Represents the size of the [enum Function] enum.
 			Represents the size of the [enum Function] enum.
 		</constant>
 		</constant>
 	</constants>
 	</constants>

+ 2 - 0
editor/plugins/visual_shader_editor_plugin.cpp

@@ -6775,8 +6775,10 @@ VisualShaderEditor::VisualShaderEditor() {
 
 
 	add_options.push_back(AddOption("Grayscale", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Grayscale", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Grayscale function."), { VisualShaderNodeColorFunc::FUNC_GRAYSCALE }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("HSV2RGB", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeColorFunc::FUNC_HSV2RGB, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("HSV2RGB", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts HSV vector to RGB equivalent."), { VisualShaderNodeColorFunc::FUNC_HSV2RGB, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+	add_options.push_back(AddOption("LinearToSRGB", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts color from linear to sRGB color space."), { VisualShaderNodeColorFunc::FUNC_LINEAR_TO_SRGB }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("RGB2HSV", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeColorFunc::FUNC_RGB2HSV, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("RGB2HSV", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts RGB vector to HSV equivalent."), { VisualShaderNodeColorFunc::FUNC_RGB2HSV, VisualShaderNodeVectorFunc::OP_TYPE_VECTOR_3D }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Sepia", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Sepia", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Sepia function."), { VisualShaderNodeColorFunc::FUNC_SEPIA }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
+	add_options.push_back(AddOption("SRGBToLinear", "Color/Functions", "VisualShaderNodeColorFunc", TTR("Converts color from sRGB to linear color space."), { VisualShaderNodeColorFunc::FUNC_SRGB_TO_LINEAR }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 
 
 	add_options.push_back(AddOption("Burn", "Color/Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Burn", "Color/Operators", "VisualShaderNodeColorOp", TTR("Burn operator."), { VisualShaderNodeColorOp::OP_BURN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Darken", "Color/Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));
 	add_options.push_back(AddOption("Darken", "Color/Operators", "VisualShaderNodeColorOp", TTR("Darken operator."), { VisualShaderNodeColorOp::OP_DARKEN }, VisualShaderNode::PORT_TYPE_VECTOR_3D));

+ 26 - 1
scene/resources/visual_shader_nodes.cpp

@@ -3243,6 +3243,29 @@ String VisualShaderNodeColorFunc::generate_code(Shader::Mode p_mode, VisualShade
 			code += "		" + p_output_vars[0] + " = vec3(r, g, b);\n";
 			code += "		" + p_output_vars[0] + " = vec3(r, g, b);\n";
 			code += "	}\n";
 			code += "	}\n";
 			break;
 			break;
+		case FUNC_LINEAR_TO_SRGB:
+			code += "	{\n";
+			if (RenderingServer::get_singleton()->is_low_end()) {
+				code += "		vec3 c = " + p_input_vars[0] + ";\n";
+				code += "		" + p_output_vars[0] + " = max(vec3(1.055) * pow(c, vec3(0.416666667)) - vec3(0.055), vec3(0.0));\n";
+			} else {
+				code += "		vec3 c = clamp(" + p_input_vars[0] + ", vec3(0.0), vec3(1.0));\n";
+				code += "		const vec3 a = vec3(0.055f);\n";
+				code += "		" + p_output_vars[0] + " = mix((vec3(1.0f) + a) * pow(c.rgb, vec3(1.0f / 2.4f)) - a, 12.92f * c.rgb, lessThan(c.rgb, vec3(0.0031308f)));\n";
+			}
+			code += "	}\n";
+			break;
+		case FUNC_SRGB_TO_LINEAR:
+			code += "	{\n";
+			if (RenderingServer::get_singleton()->is_low_end()) {
+				code += "		vec3 c = " + p_input_vars[0] + ";\n";
+				code += "		" + p_output_vars[0] + " = c * (c * (c * 0.305306011 + 0.682171111) + 0.012522878);\n";
+			} else {
+				code += "		vec3 c = " + p_input_vars[0] + ";\n";
+				code += "		" + p_output_vars[0] + " = mix(pow((c.rgb + vec3(0.055)) * (1.0 / (1.0 + 0.055)), vec3(2.4)), c.rgb * (1.0 / 12.92), lessThan(c.rgb, vec3(0.04045)));\n";
+			}
+			code += "	}\n";
+			break;
 		default:
 		default:
 			break;
 			break;
 	}
 	}
@@ -3273,12 +3296,14 @@ void VisualShaderNodeColorFunc::_bind_methods() {
 	ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeColorFunc::set_function);
 	ClassDB::bind_method(D_METHOD("set_function", "func"), &VisualShaderNodeColorFunc::set_function);
 	ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeColorFunc::get_function);
 	ClassDB::bind_method(D_METHOD("get_function"), &VisualShaderNodeColorFunc::get_function);
 
 
-	ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Grayscale,HSV2RGB,RGB2HSV,Sepia"), "set_function", "get_function");
+	ADD_PROPERTY(PropertyInfo(Variant::INT, "function", PROPERTY_HINT_ENUM, "Grayscale,HSV2RGB,RGB2HSV,Sepia,LinearToSRGB,SRGBToLinear"), "set_function", "get_function");
 
 
 	BIND_ENUM_CONSTANT(FUNC_GRAYSCALE);
 	BIND_ENUM_CONSTANT(FUNC_GRAYSCALE);
 	BIND_ENUM_CONSTANT(FUNC_HSV2RGB);
 	BIND_ENUM_CONSTANT(FUNC_HSV2RGB);
 	BIND_ENUM_CONSTANT(FUNC_RGB2HSV);
 	BIND_ENUM_CONSTANT(FUNC_RGB2HSV);
 	BIND_ENUM_CONSTANT(FUNC_SEPIA);
 	BIND_ENUM_CONSTANT(FUNC_SEPIA);
+	BIND_ENUM_CONSTANT(FUNC_LINEAR_TO_SRGB);
+	BIND_ENUM_CONSTANT(FUNC_SRGB_TO_LINEAR);
 	BIND_ENUM_CONSTANT(FUNC_MAX);
 	BIND_ENUM_CONSTANT(FUNC_MAX);
 }
 }
 
 

+ 2 - 0
scene/resources/visual_shader_nodes.h

@@ -1353,6 +1353,8 @@ public:
 		FUNC_HSV2RGB,
 		FUNC_HSV2RGB,
 		FUNC_RGB2HSV,
 		FUNC_RGB2HSV,
 		FUNC_SEPIA,
 		FUNC_SEPIA,
+		FUNC_LINEAR_TO_SRGB,
+		FUNC_SRGB_TO_LINEAR,
 		FUNC_MAX,
 		FUNC_MAX,
 	};
 	};