Browse Source

Merge pull request #43906 from Chaosus/vs_sdf

Added SDF nodes to visual shader
Rémi Verschelde 4 years ago
parent
commit
eb77d0cf1b

+ 15 - 0
doc/classes/VisualShaderNodeSDFRaymarch.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeSDFRaymarch" inherits="VisualShaderNode" version="4.0">
+	<brief_description>
+		 SDF raymarching algorithm to be used within the visual shader graph.
+	</brief_description>
+	<description>
+		 Casts a ray against the screen SDF (signed-distance field) and returns the distance travelled.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+	</methods>
+	<constants>
+	</constants>
+</class>

+ 15 - 0
doc/classes/VisualShaderNodeSDFToScreenUV.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeSDFToScreenUV" inherits="VisualShaderNode" version="4.0">
+	<brief_description>
+		A function to convert a SDF (signed-distance field) to screen UV, to be used within the visual shader graph.
+	</brief_description>
+	<description>
+		Translates to [code]sdf_to_screen_uv(sdf_pos)[/code] in the shader language.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+	</methods>
+	<constants>
+	</constants>
+</class>

+ 15 - 0
doc/classes/VisualShaderNodeScreenUVToSDF.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeScreenUVToSDF" inherits="VisualShaderNode" version="4.0">
+	<brief_description>
+		A function to convert screen UV to a SDF (signed-distance field), to be used within the visual shader graph.
+	</brief_description>
+	<description>
+		Translates to [code]screen_uv_to_sdf(uv)[/code] in the shader language. If the UV port isn't connected, [code]SCREEN_UV[/code] is used instead.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+	</methods>
+	<constants>
+	</constants>
+</class>

+ 15 - 0
doc/classes/VisualShaderNodeTextureSDF.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTextureSDF" inherits="VisualShaderNode" version="4.0">
+	<brief_description>
+		Performs a SDF (signed-distance field) texture lookup within the visual shader graph.
+	</brief_description>
+	<description>
+		Translates to [code]texture_sdf(sdf_pos)[/code] in the shader language.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+	</methods>
+	<constants>
+	</constants>
+</class>

+ 15 - 0
doc/classes/VisualShaderNodeTextureSDFNormal.xml

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<class name="VisualShaderNodeTextureSDFNormal" inherits="VisualShaderNode" version="4.0">
+	<brief_description>
+		Performs a SDF (signed-distance field) normal texture lookup within the visual shader graph.
+	</brief_description>
+	<description>
+		Translates to [code]texture_sdf_normal(sdf_pos)[/code] in the shader language.
+	</description>
+	<tutorials>
+	</tutorials>
+	<methods>
+	</methods>
+	<constants>
+	</constants>
+</class>

+ 11 - 0
editor/plugins/visual_shader_editor_plugin.cpp

@@ -44,6 +44,7 @@
 #include "scene/gui/panel.h"
 #include "scene/gui/panel.h"
 #include "scene/main/window.h"
 #include "scene/main/window.h"
 #include "scene/resources/visual_shader_nodes.h"
 #include "scene/resources/visual_shader_nodes.h"
+#include "scene/resources/visual_shader_sdf_nodes.h"
 #include "servers/display_server.h"
 #include "servers/display_server.h"
 #include "servers/rendering/shader_types.h"
 #include "servers/rendering/shader_types.h"
 
 
@@ -3671,7 +3672,17 @@ VisualShaderEditor::VisualShaderEditor() {
 	add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
 	add_options.push_back(AddOption("FloatUniform", "Scalar", "Variables", "VisualShaderNodeFloatUniform", TTR("Scalar floating-point uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR));
 	add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
 	add_options.push_back(AddOption("IntUniform", "Scalar", "Variables", "VisualShaderNodeIntUniform", TTR("Scalar integer uniform."), -1, VisualShaderNode::PORT_TYPE_SCALAR_INT));
 
 
+	// SDF
+	{
+		add_options.push_back(AddOption("ScreenUVToSDF", "SDF", "", "VisualShaderNodeScreenUVToSDF", TTR("Converts screen UV to a SDF."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("SDFRaymarch", "SDF", "", "VisualShaderNodeSDFRaymarch", TTR("Casts a ray against the screen SDF and returns the distance travelled."), -1, -1, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("SDFToScreenUV", "SDF", "", "VisualShaderNodeSDFToScreenUV", TTR("Converts a SDF to screen UV."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("TextureSDF", "SDF", "", "VisualShaderNodeTextureSDF", TTR("Performs a SDF texture lookup."), -1, VisualShaderNode::PORT_TYPE_SCALAR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+		add_options.push_back(AddOption("TextureSDFNormal", "SDF", "", "VisualShaderNodeTextureSDFNormal", TTR("Performs a SDF normal texture lookup."), -1, VisualShaderNode::PORT_TYPE_VECTOR, TYPE_FLAGS_FRAGMENT | TYPE_FLAGS_LIGHT, Shader::MODE_CANVAS_ITEM));
+	}
+
 	// TEXTURES
 	// TEXTURES
+
 	cubemap_node_option_idx = add_options.size();
 	cubemap_node_option_idx = add_options.size();
 	add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
 	add_options.push_back(AddOption("CubeMap", "Textures", "Functions", "VisualShaderNodeCubemap", TTR("Perform the cubic texture lookup."), -1, -1));
 	curve_node_option_idx = add_options.size();
 	curve_node_option_idx = add_options.size();

+ 7 - 0
scene/register_scene_types.cpp

@@ -175,6 +175,7 @@
 #include "scene/resources/video_stream.h"
 #include "scene/resources/video_stream.h"
 #include "scene/resources/visual_shader.h"
 #include "scene/resources/visual_shader.h"
 #include "scene/resources/visual_shader_nodes.h"
 #include "scene/resources/visual_shader_nodes.h"
+#include "scene/resources/visual_shader_sdf_nodes.h"
 #include "scene/resources/world_2d.h"
 #include "scene/resources/world_2d.h"
 #include "scene/resources/world_3d.h"
 #include "scene/resources/world_3d.h"
 #include "scene/resources/world_margin_shape_3d.h"
 #include "scene/resources/world_margin_shape_3d.h"
@@ -602,6 +603,12 @@ void register_scene_types() {
 	ClassDB::register_class<VisualShaderNodeCompare>();
 	ClassDB::register_class<VisualShaderNodeCompare>();
 	ClassDB::register_class<VisualShaderNodeMultiplyAdd>();
 	ClassDB::register_class<VisualShaderNodeMultiplyAdd>();
 
 
+	ClassDB::register_class<VisualShaderNodeSDFToScreenUV>();
+	ClassDB::register_class<VisualShaderNodeScreenUVToSDF>();
+	ClassDB::register_class<VisualShaderNodeTextureSDF>();
+	ClassDB::register_class<VisualShaderNodeTextureSDFNormal>();
+	ClassDB::register_class<VisualShaderNodeSDFRaymarch>();
+
 	ClassDB::register_class<ShaderMaterial>();
 	ClassDB::register_class<ShaderMaterial>();
 	ClassDB::register_virtual_class<CanvasItem>();
 	ClassDB::register_virtual_class<CanvasItem>();
 	ClassDB::register_class<CanvasTexture>();
 	ClassDB::register_class<CanvasTexture>();

+ 1 - 0
scene/resources/visual_shader.cpp

@@ -33,6 +33,7 @@
 #include "core/templates/vmap.h"
 #include "core/templates/vmap.h"
 #include "servers/rendering/shader_types.h"
 #include "servers/rendering/shader_types.h"
 #include "visual_shader_nodes.h"
 #include "visual_shader_nodes.h"
+#include "visual_shader_sdf_nodes.h"
 
 
 bool VisualShaderNode::is_simple_decl() const {
 bool VisualShaderNode::is_simple_decl() const {
 	return simple_decl;
 	return simple_decl;

+ 283 - 0
scene/resources/visual_shader_sdf_nodes.cpp

@@ -0,0 +1,283 @@
+/*************************************************************************/
+/*  visual_shader_sdf_nodes.cpp                                          */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "visual_shader_sdf_nodes.h"
+
+// VisualShaderNodeSDFToScreenUV
+
+String VisualShaderNodeSDFToScreenUV::get_caption() const {
+	return "SDFToScreenUV";
+}
+
+int VisualShaderNodeSDFToScreenUV::get_input_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_input_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSDFToScreenUV::get_input_port_name(int p_port) const {
+	return "sdf_pos";
+}
+
+int VisualShaderNodeSDFToScreenUV::get_output_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeSDFToScreenUV::PortType VisualShaderNodeSDFToScreenUV::get_output_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeSDFToScreenUV::get_output_port_name(int p_port) const {
+	return "";
+}
+
+String VisualShaderNodeSDFToScreenUV::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+	return "\t" + p_output_vars[0] + " = vec3(sdf_to_screen_uv(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeSDFToScreenUV::VisualShaderNodeSDFToScreenUV() {
+}
+
+// VisualShaderNodeScreenUVToSDF
+
+String VisualShaderNodeScreenUVToSDF::get_caption() const {
+	return "ScreenUVToSDF";
+}
+
+int VisualShaderNodeScreenUVToSDF::get_input_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_input_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeScreenUVToSDF::get_input_port_name(int p_port) const {
+	return "uv";
+}
+
+int VisualShaderNodeScreenUVToSDF::get_output_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeScreenUVToSDF::PortType VisualShaderNodeScreenUVToSDF::get_output_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeScreenUVToSDF::get_output_port_name(int p_port) const {
+	return "";
+}
+
+String VisualShaderNodeScreenUVToSDF::get_input_port_default_hint(int p_port) const {
+	if (p_port == 0) {
+		return "default";
+	}
+	return "";
+}
+
+String VisualShaderNodeScreenUVToSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+	return "\t" + p_output_vars[0] + " = vec3(screen_uv_to_sdf(" + (p_input_vars[0] == String() ? "SCREEN_UV" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeScreenUVToSDF::VisualShaderNodeScreenUVToSDF() {
+}
+
+// VisualShaderNodeTextureSDF
+
+String VisualShaderNodeTextureSDF::get_caption() const {
+	return "TextureSDF";
+}
+
+int VisualShaderNodeTextureSDF::get_input_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_input_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDF::get_input_port_name(int p_port) const {
+	return "sdf_pos";
+}
+
+int VisualShaderNodeTextureSDF::get_output_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeTextureSDF::PortType VisualShaderNodeTextureSDF::get_output_port_type(int p_port) const {
+	return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeTextureSDF::get_output_port_name(int p_port) const {
+	return "";
+}
+
+String VisualShaderNodeTextureSDF::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+	return "\t" + p_output_vars[0] + " = texture_sdf(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + ");\n";
+}
+
+VisualShaderNodeTextureSDF::VisualShaderNodeTextureSDF() {
+}
+
+// VisualShaderNodeTextureSDFNormal
+
+String VisualShaderNodeTextureSDFNormal::get_caption() const {
+	return "TextureSDFNormal";
+}
+
+int VisualShaderNodeTextureSDFNormal::get_input_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_input_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDFNormal::get_input_port_name(int p_port) const {
+	return "sdf_pos";
+}
+
+int VisualShaderNodeTextureSDFNormal::get_output_port_count() const {
+	return 1;
+}
+
+VisualShaderNodeTextureSDFNormal::PortType VisualShaderNodeTextureSDFNormal::get_output_port_type(int p_port) const {
+	return PORT_TYPE_VECTOR;
+}
+
+String VisualShaderNodeTextureSDFNormal::get_output_port_name(int p_port) const {
+	return "";
+}
+
+String VisualShaderNodeTextureSDFNormal::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+	return "\t" + p_output_vars[0] + " = vec3(texture_sdf_normal(" + (p_input_vars[0] == String() ? "vec2(0.0)" : p_input_vars[0] + ".xy") + "), 0.0f);\n";
+}
+
+VisualShaderNodeTextureSDFNormal::VisualShaderNodeTextureSDFNormal() {
+}
+
+// VisualShaderNodeSDFRaymarch
+
+String VisualShaderNodeSDFRaymarch::get_caption() const {
+	return "SDFRaymarch";
+}
+
+int VisualShaderNodeSDFRaymarch::get_input_port_count() const {
+	return 2;
+}
+
+VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_input_port_type(int p_port) const {
+	if (p_port == 0 || p_port == 1) {
+		return PORT_TYPE_VECTOR;
+	}
+	return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeSDFRaymarch::get_input_port_name(int p_port) const {
+	if (p_port == 0) {
+		return "from_pos";
+	} else if (p_port == 1) {
+		return "to_pos";
+	}
+	return String();
+}
+
+int VisualShaderNodeSDFRaymarch::get_output_port_count() const {
+	return 3;
+}
+
+VisualShaderNodeSDFRaymarch::PortType VisualShaderNodeSDFRaymarch::get_output_port_type(int p_port) const {
+	if (p_port == 0) {
+		return PORT_TYPE_SCALAR;
+	} else if (p_port == 1) {
+		return PORT_TYPE_BOOLEAN;
+	} else if (p_port == 2) {
+		return PORT_TYPE_VECTOR;
+	}
+	return PORT_TYPE_SCALAR;
+}
+
+String VisualShaderNodeSDFRaymarch::get_output_port_name(int p_port) const {
+	if (p_port == 0) {
+		return "distance";
+	} else if (p_port == 1) {
+		return "hit";
+	} else if (p_port == 2) {
+		return "end_pos";
+	}
+	return String();
+}
+
+String VisualShaderNodeSDFRaymarch::generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview) const {
+	String code;
+
+	code += "\t{\n";
+
+	if (p_input_vars[0] == String()) {
+		code += "\t\tvec2 __from_pos = vec2(0.0f);\n";
+	} else {
+		code += "\t\tvec2 __from_pos = " + p_input_vars[0] + ".xy;\n";
+	}
+
+	if (p_input_vars[1] == String()) {
+		code += "\t\tvec2 __to_pos = vec2(0.0f);\n";
+	} else {
+		code += "\t\tvec2 __to_pos = " + p_input_vars[1] + ".xy;\n";
+	}
+
+	code += "\n\t\tvec2 __at = __from_pos;\n";
+	code += "\t\tfloat __max_dist = distance(__from_pos, __to_pos);\n";
+	code += "\t\tvec2 __dir = normalize(__to_pos - __from_pos);\n\n";
+
+	code += "\t\tfloat __accum = 0.0f;\n";
+	code += "\t\twhile(__accum < __max_dist) {\n";
+	code += "\t\t\tfloat __d = texture_sdf(__at);\n";
+	code += "\t\t\t__accum += __d;\n";
+	code += "\t\t\tif (__d < 0.01f) {\n";
+	code += "\t\t\t\tbreak;\n";
+	code += "\t\t\t}\n";
+	code += "\t\t\t__at += __d * __dir;\n";
+	code += "\t\t}\n";
+
+	code += "\t\tfloat __dist = min(__max_dist, __accum);\n";
+	code += "\t\t" + p_output_vars[0] + " = __dist;\n";
+	code += "\t\t" + p_output_vars[1] + " = __accum < __max_dist;\n";
+	code += "\t\t" + p_output_vars[2] + " = vec3(__from_pos + __dir * __dist, 0.0f);\n";
+
+	code += "\t}\n";
+
+	return code;
+}
+
+VisualShaderNodeSDFRaymarch::VisualShaderNodeSDFRaymarch() {
+	simple_decl = false;
+}

+ 132 - 0
scene/resources/visual_shader_sdf_nodes.h

@@ -0,0 +1,132 @@
+/*************************************************************************/
+/*  visual_shader_sdf_nodes.h                                            */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef VISUAL_SHADER_SDF_NODES_H
+#define VISUAL_SHADER_SDF_NODES_H
+
+#include "scene/resources/visual_shader.h"
+
+class VisualShaderNodeSDFToScreenUV : public VisualShaderNode {
+	GDCLASS(VisualShaderNodeSDFToScreenUV, VisualShaderNode);
+
+public:
+	virtual String get_caption() const override;
+
+	virtual int get_input_port_count() const override;
+	virtual PortType get_input_port_type(int p_port) const override;
+	virtual String get_input_port_name(int p_port) const override;
+
+	virtual int get_output_port_count() const override;
+	virtual PortType get_output_port_type(int p_port) const override;
+	virtual String get_output_port_name(int p_port) const override;
+
+	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+	VisualShaderNodeSDFToScreenUV();
+};
+
+class VisualShaderNodeScreenUVToSDF : public VisualShaderNode {
+	GDCLASS(VisualShaderNodeScreenUVToSDF, VisualShaderNode);
+
+public:
+	virtual String get_caption() const override;
+
+	virtual int get_input_port_count() const override;
+	virtual PortType get_input_port_type(int p_port) const override;
+	virtual String get_input_port_name(int p_port) const override;
+
+	virtual int get_output_port_count() const override;
+	virtual PortType get_output_port_type(int p_port) const override;
+	virtual String get_output_port_name(int p_port) const override;
+
+	virtual String get_input_port_default_hint(int p_port) const override;
+	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+	VisualShaderNodeScreenUVToSDF();
+};
+
+class VisualShaderNodeTextureSDF : public VisualShaderNode {
+	GDCLASS(VisualShaderNodeTextureSDF, VisualShaderNode);
+
+public:
+	virtual String get_caption() const override;
+
+	virtual int get_input_port_count() const override;
+	virtual PortType get_input_port_type(int p_port) const override;
+	virtual String get_input_port_name(int p_port) const override;
+
+	virtual int get_output_port_count() const override;
+	virtual PortType get_output_port_type(int p_port) const override;
+	virtual String get_output_port_name(int p_port) const override;
+
+	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+	VisualShaderNodeTextureSDF();
+};
+
+class VisualShaderNodeTextureSDFNormal : public VisualShaderNode {
+	GDCLASS(VisualShaderNodeTextureSDFNormal, VisualShaderNode);
+
+public:
+	virtual String get_caption() const override;
+
+	virtual int get_input_port_count() const override;
+	virtual PortType get_input_port_type(int p_port) const override;
+	virtual String get_input_port_name(int p_port) const override;
+
+	virtual int get_output_port_count() const override;
+	virtual PortType get_output_port_type(int p_port) const override;
+	virtual String get_output_port_name(int p_port) const override;
+
+	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+	VisualShaderNodeTextureSDFNormal();
+};
+
+class VisualShaderNodeSDFRaymarch : public VisualShaderNode {
+	GDCLASS(VisualShaderNodeSDFRaymarch, VisualShaderNode);
+
+public:
+	virtual String get_caption() const override;
+
+	virtual int get_input_port_count() const override;
+	virtual PortType get_input_port_type(int p_port) const override;
+	virtual String get_input_port_name(int p_port) const override;
+
+	virtual int get_output_port_count() const override;
+	virtual PortType get_output_port_type(int p_port) const override;
+	virtual String get_output_port_name(int p_port) const override;
+
+	virtual String generate_code(Shader::Mode p_mode, VisualShader::Type p_type, int p_id, const String *p_input_vars, const String *p_output_vars, bool p_for_preview = false) const override;
+
+	VisualShaderNodeSDFRaymarch();
+};
+
+#endif // VISUAL_SHADER_SDF_NODES_H