From aa9aa5a03863232cffef25ae8bb30d5d2081d911 Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 27 Nov 2024 11:55:55 +0100 Subject: [PATCH] feat(shader_graph): add geometry, texture_coordinate and vector_transform nodes --- assets/shaders/modules/entity.glsl | 1 + assets/shaders/modules/uv_data.glsl | 1 + assets/shaders/modules/vertex_data.glsl | 1 + .../rendering/shader_graph/nodes/geometry.hpp | 29 ++++++ .../shader_graph/nodes/texture_coordinate.hpp | 26 +++++ .../shader_graph/nodes/vector_transform.hpp | 43 +++++++++ core/client/src/c_engine.cpp | 15 ++- .../rendering/shader_graph/nodes/camera.cpp | 14 +-- .../src/rendering/shader_graph/nodes/fog.cpp | 8 +- .../rendering/shader_graph/nodes/geometry.cpp | 35 +++++++ .../rendering/shader_graph/nodes/object.cpp | 4 +- .../shader_graph/nodes/texture_coordinate.cpp | 25 +++++ .../src/rendering/shader_graph/nodes/time.cpp | 8 +- .../shader_graph/nodes/vector_transform.cpp | 96 +++++++++++++++++++ 14 files changed, 288 insertions(+), 18 deletions(-) create mode 100644 assets/shaders/modules/entity.glsl create mode 100644 assets/shaders/modules/uv_data.glsl create mode 100644 assets/shaders/modules/vertex_data.glsl create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp create mode 100644 core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp create mode 100644 core/client/src/rendering/shader_graph/nodes/geometry.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp create mode 100644 core/client/src/rendering/shader_graph/nodes/vector_transform.cpp diff --git a/assets/shaders/modules/entity.glsl b/assets/shaders/modules/entity.glsl new file mode 100644 index 000000000..266570539 --- /dev/null +++ b/assets/shaders/modules/entity.glsl @@ -0,0 +1 @@ +#include "/common/inputs/entity.glsl" diff --git a/assets/shaders/modules/uv_data.glsl b/assets/shaders/modules/uv_data.glsl new file mode 100644 index 000000000..ab4ed76e1 --- /dev/null +++ b/assets/shaders/modules/uv_data.glsl @@ -0,0 +1 @@ +#include "/common/inputs/textures/parallax_map.glsl" diff --git a/assets/shaders/modules/vertex_data.glsl b/assets/shaders/modules/vertex_data.glsl new file mode 100644 index 000000000..50674c1fa --- /dev/null +++ b/assets/shaders/modules/vertex_data.glsl @@ -0,0 +1 @@ +#include "/common/vertex_outputs/vertex_data.glsl" diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp new file mode 100644 index 000000000..06d57350d --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/geometry.hpp @@ -0,0 +1,29 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_GEOMETRY_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_GEOMETRY_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT GeometryNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_POSITION_WS = "position_ws"; + static constexpr const char *OUT_NORMAL_WS = "normal_ws"; + static constexpr const char *OUT_NORMAL_CS = "normal_cs"; + static constexpr const char *OUT_TANGENT_WS = "tangent_ws"; + + GeometryNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp new file mode 100644 index 000000000..c72284aa0 --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/texture_coordinate.hpp @@ -0,0 +1,26 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_TEXTURE_COORDINATE_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_TEXTURE_COORDINATE_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT TextureCoordinateNode : public pragma::shadergraph::Node { + public: + static constexpr const char *OUT_UV = "uv"; + + TextureCoordinateNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp b/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp new file mode 100644 index 000000000..b14dc1efa --- /dev/null +++ b/core/client/include/pragma/rendering/shader_graph/nodes/vector_transform.hpp @@ -0,0 +1,43 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#ifndef __PRAGMA_SHADER_GRAPH_NODES_VECTOR_TRANSFORM_HPP__ +#define __PRAGMA_SHADER_GRAPH_NODES_VECTOR_TRANSFORM_HPP__ + +#include "pragma/clientdefinitions.h" + +import pragma.shadergraph; + +namespace pragma::rendering::shader_graph { + class DLLCLIENT VectorTransformNode : public pragma::shadergraph::Node { + public: + enum class Type : uint8_t { + Vector = 0, + Point, + Normal, + }; + + enum class Space : uint8_t { + World = 0, + Object, + Camera, + }; + + static constexpr const char *IN_TRANSFORM_TYPE = "transformType"; + static constexpr const char *IN_CONVERT_FROM = "convertForm"; + static constexpr const char *IN_CONVERT_TO = "convertTo"; + static constexpr const char *IN_VECTOR = "vector"; + + static constexpr const char *OUT_VECTOR = "vector"; + + VectorTransformNode(const std::string_view &type); + + virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override; + }; +}; + +#endif diff --git a/core/client/src/c_engine.cpp b/core/client/src/c_engine.cpp index 90b05f34b..99f5e485d 100644 --- a/core/client/src/c_engine.cpp +++ b/core/client/src/c_engine.cpp @@ -112,7 +112,12 @@ static const auto SEPARATE_JOYSTICK_AXES = true; #include "pragma/rendering/shader_graph/nodes/object.hpp" #include "pragma/rendering/shader_graph/nodes/time.hpp" #include "pragma/rendering/shader_graph/nodes/pbr.hpp" +#include "pragma/rendering/shader_graph/nodes/image_texture.hpp" +#include "pragma/rendering/shader_graph/nodes/texture_coordinate.hpp" +#include "pragma/rendering/shader_graph/nodes/vector_transform.hpp" +#include "pragma/rendering/shader_graph/nodes/geometry.hpp" #include "pragma/rendering/shader_graph/modules/pbr.hpp" +#include "pragma/rendering/shader_graph/modules/image_texture.hpp" CEngine::CEngine(int argc, char *argv[]) : Engine(argc, argv), pragma::RenderContext(), m_nearZ(pragma::BaseEnvCameraComponent::DEFAULT_NEAR_Z), //10.0f), //0.1f @@ -197,16 +202,23 @@ CEngine::CEngine(int argc, char *argv[]) { auto regBase = std::make_shared(); regBase->RegisterNode("math"); + regBase->RegisterNode("combine_xyz"); + regBase->RegisterNode("separate_xyz"); + regBase->RegisterNode("vector_math"); + regBase->RegisterNode("mix"); auto regScene = std::make_shared(); regScene->RegisterNode("output"); - regScene->RegisterNode("combine_xyz"); regScene->RegisterNode("camera"); regScene->RegisterNode("fog"); regScene->RegisterNode("lightmap"); regScene->RegisterNode("object"); regScene->RegisterNode("time"); regScene->RegisterNode("pbr"); + regScene->RegisterNode("image_texture"); + regScene->RegisterNode("texture_coordinate"); + regScene->RegisterNode("vector_transform"); + regScene->RegisterNode("geometry"); auto shaderMat = pragma::rendering::shader_material::get_cache().Load("pbr"); auto node = std::make_shared("test", *shaderMat); @@ -222,6 +234,7 @@ CEngine::CEngine(int argc, char *argv[]) m_shaderGraphManager->RegisterGraphTypeManager("object", regScene); m_shaderGraphManager->GetModuleManager().RegisterFactory("pbr", [](prosper::Shader &shader) -> std::unique_ptr { return std::make_unique(shader); }); + m_shaderGraphManager->GetModuleManager().RegisterFactory("image_texture", [](prosper::Shader &shader) -> std::unique_ptr { return std::make_unique(shader); }); } } diff --git a/core/client/src/rendering/shader_graph/nodes/camera.cpp b/core/client/src/rendering/shader_graph/nodes/camera.cpp index dd67beafc..7d545b75d 100644 --- a/core/client/src/rendering/shader_graph/nodes/camera.cpp +++ b/core/client/src/rendering/shader_graph/nodes/camera.cpp @@ -27,12 +27,12 @@ CameraNode::CameraNode(const std::string_view &type) : Node {type} std::string CameraNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_POSITION) << " = u_renderSettings.posCam.xyz;\n"; - code << instance.GetOutputVarName(OUT_FOV) << " = u_renderSettings.posCam.w;\n"; - code << instance.GetOutputVarName(OUT_NEARZ) << " = u_renderSettings.nearZ;\n"; - code << instance.GetOutputVarName(OUT_FARZ) << " = u_renderSettings.farZ;\n"; - code << instance.GetOutputVarName(OUT_VIEW_MATRIX) << " = u_camera.V;\n"; - code << instance.GetOutputVarName(OUT_PROJECTION_MATRIX) << " = u_camera.P;\n"; - code << instance.GetOutputVarName(OUT_VIEW_PROJECTION_MATRIX) << " = u_camera.VP;\n"; + code << instance.GetGlslOutputDeclaration(OUT_POSITION) << " = u_renderSettings.posCam.xyz;\n"; + code << instance.GetGlslOutputDeclaration(OUT_FOV) << " = u_renderSettings.posCam.w;\n"; + code << instance.GetGlslOutputDeclaration(OUT_NEARZ) << " = u_renderSettings.nearZ;\n"; + code << instance.GetGlslOutputDeclaration(OUT_FARZ) << " = u_renderSettings.farZ;\n"; + code << instance.GetGlslOutputDeclaration(OUT_VIEW_MATRIX) << " = u_camera.V;\n"; + code << instance.GetGlslOutputDeclaration(OUT_PROJECTION_MATRIX) << " = u_camera.P;\n"; + code << instance.GetGlslOutputDeclaration(OUT_VIEW_PROJECTION_MATRIX) << " = u_camera.VP;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/fog.cpp b/core/client/src/rendering/shader_graph/nodes/fog.cpp index 868d0f789..9f1004929 100644 --- a/core/client/src/rendering/shader_graph/nodes/fog.cpp +++ b/core/client/src/rendering/shader_graph/nodes/fog.cpp @@ -23,9 +23,9 @@ FogNode::FogNode(const std::string_view &type) : Node {type} std::string FogNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_COLOR) << " = u_fog.color.rgb;\n"; - code << instance.GetOutputVarName(OUT_START_DISTANCE) << " = u_fog.start;\n"; - code << instance.GetOutputVarName(OUT_END_DISTANCE) << " = u_fog.end;\n"; - code << instance.GetOutputVarName(OUT_DENSITY) << " = u_fog.density;\n"; + code << instance.GetGlslOutputDeclaration(OUT_COLOR) << " = u_fog.color.rgb;\n"; + code << instance.GetGlslOutputDeclaration(OUT_START_DISTANCE) << " = u_fog.start;\n"; + code << instance.GetGlslOutputDeclaration(OUT_END_DISTANCE) << " = u_fog.end;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DENSITY) << " = u_fog.density;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/geometry.cpp b/core/client/src/rendering/shader_graph/nodes/geometry.cpp new file mode 100644 index 000000000..2d9790730 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/geometry.cpp @@ -0,0 +1,35 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/geometry.hpp" + +using namespace pragma::rendering::shader_graph; + +GeometryNode::GeometryNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_POSITION_WS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_NORMAL_WS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_NORMAL_CS, pragma::shadergraph::SocketType::Vector); + AddOutput(OUT_TANGENT_WS, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("vertex_data"); +} + +std::string GeometryNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + code << gn.GetGlslOutputDeclaration(OUT_POSITION_WS) << " = get_vertex_position_ws();\n"; + code << gn.GetGlslOutputDeclaration(OUT_NORMAL_WS) << " = get_vertex_normal();\n"; + code << gn.GetGlslOutputDeclaration(OUT_NORMAL_CS) << " = get_vertex_normal_cs();\n"; + + auto prefix = gn.GetBaseVarName() + "_"; + std::string tbn = prefix + "tbn"; + code << "mat3 " << tbn << " = get_tbn_matrix();\n"; + code << gn.GetGlslOutputDeclaration(OUT_TANGENT_WS) << " = normalize(" << tbn << "[0]);\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/object.cpp b/core/client/src/rendering/shader_graph/nodes/object.cpp index dc29994c6..87f6e344f 100644 --- a/core/client/src/rendering/shader_graph/nodes/object.cpp +++ b/core/client/src/rendering/shader_graph/nodes/object.cpp @@ -21,7 +21,7 @@ ObjectNode::ObjectNode(const std::string_view &type) : Node {type} std::string ObjectNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_MODEL_MATRIX) << " = u_instance.M;\n"; - code << instance.GetOutputVarName(OUT_COLOR) << " = u_instance.color;\n"; + code << instance.GetGlslOutputDeclaration(OUT_MODEL_MATRIX) << " = u_instance.M;\n"; + code << instance.GetGlslOutputDeclaration(OUT_COLOR) << " = u_instance.color;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp b/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp new file mode 100644 index 000000000..72a00d1a3 --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/texture_coordinate.cpp @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/texture_coordinate.hpp" + +using namespace pragma::rendering::shader_graph; + +TextureCoordinateNode::TextureCoordinateNode(const std::string_view &type) : Node {type} +{ + AddOutput(OUT_UV, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("uv_data"); +} + +std::string TextureCoordinateNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const +{ + std::ostringstream code; + code << instance.GetGlslOutputDeclaration(OUT_UV) << " = vec3(get_uv_coordinates(), 0.0);\n"; + return code.str(); +} diff --git a/core/client/src/rendering/shader_graph/nodes/time.cpp b/core/client/src/rendering/shader_graph/nodes/time.cpp index abb08998e..cdf8fb63d 100644 --- a/core/client/src/rendering/shader_graph/nodes/time.cpp +++ b/core/client/src/rendering/shader_graph/nodes/time.cpp @@ -23,9 +23,9 @@ TimeNode::TimeNode(const std::string_view &type) : Node {type} std::string TimeNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const { std::ostringstream code; - code << instance.GetOutputVarName(OUT_TIME) << " = u_time.time;\n"; - code << instance.GetOutputVarName(OUT_DELTA_TIME) << " = u_time.deltaTime;\n"; - code << instance.GetOutputVarName(OUT_REAL_TIME) << " = u_time.realTime;\n"; - code << instance.GetOutputVarName(OUT_DELTA_REAL_TIME) << " = u_time.deltaRealTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_TIME) << " = u_time.time;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DELTA_TIME) << " = u_time.deltaTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_REAL_TIME) << " = u_time.realTime;\n"; + code << instance.GetGlslOutputDeclaration(OUT_DELTA_REAL_TIME) << " = u_time.deltaRealTime;\n"; return code.str(); } diff --git a/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp b/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp new file mode 100644 index 000000000..98e359c9f --- /dev/null +++ b/core/client/src/rendering/shader_graph/nodes/vector_transform.cpp @@ -0,0 +1,96 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright (c) 2024 Silverlan + */ + +#include "stdafx_client.h" +#include "pragma/rendering/shader_graph/nodes/vector_transform.hpp" + +using namespace pragma::rendering::shader_graph; + +VectorTransformNode::VectorTransformNode(const std::string_view &type) : Node {type} +{ + AddSocketEnum(IN_TRANSFORM_TYPE, Type::Vector); + AddSocketEnum(IN_CONVERT_FROM, Space::World); + AddSocketEnum(IN_CONVERT_TO, Space::Object); + AddInput(IN_VECTOR, pragma::shadergraph::SocketType::Vector, Vector3 {0.f, 0.f, 0.f}); + AddOutput(OUT_VECTOR, pragma::shadergraph::SocketType::Vector); + + AddModuleDependency("camera"); + AddModuleDependency("entity"); +} + +std::string VectorTransformNode::DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &gn) const +{ + std::ostringstream code; + + auto vector = gn.GetInputNameOrValue(IN_VECTOR); + + auto type = *gn.GetConstantInputValue(IN_TRANSFORM_TYPE); + auto convertFrom = *gn.GetConstantInputValue(IN_CONVERT_FROM); + auto convertTo = *gn.GetConstantInputValue(IN_CONVERT_TO); + + if(convertFrom == convertTo) { + code << gn.GetGlslOutputDeclaration(OUT_VECTOR) << " = " << vector << ";\n"; + return code.str(); + } + + auto prefix = gn.GetBaseVarName() + "_"; + std::string matName = prefix + "mat"; + code << "mat4 " << matName << " = "; + switch(convertFrom) { + case Space::Object: + switch(convertTo) { + case Space::World: + code << "get_model_matrix()"; + break; + case Space::Camera: + code << "get_view_matrix() *get_model_matrix()"; + break; + } + break; + case Space::Camera: + switch(convertTo) { + case Space::World: + code << "inverse(get_view_matrix())"; + break; + case Space::Object: + code << "inverse(get_model_matrix()) *inverse(get_view_matrix())"; + break; + } + break; + case Space::World: + switch(convertTo) { + case Space::Object: + code << "inverse(get_model_matrix())"; + break; + case Space::Camera: + code << "get_view_matrix()"; + break; + } + break; + } + code << ";\n"; + + code << gn.GetGlslOutputDeclaration(OUT_VECTOR) << " = "; + switch(type) { + case Type::Vector: + // Vectors are transformed with the matrix, ignoring translation. + code << "(" << matName << " * vec4(" << vector << ", 0.0)).xyz"; + break; + + case Type::Normal: + // Normals require the inverse transpose of the matrix. + code << "(transpose(inverse(mat3(" << matName << "))) * " << vector << ")"; + break; + + case Type::Point: + // Points are fully transformed, including translation. + code << "(" << matName << " * vec4(" << vector << ", 1.0)).xyz"; + break; + } + code << ";\n"; + return code.str(); +}