Skip to content

Commit

Permalink
feat(shader_graph): add module system
Browse files Browse the repository at this point in the history
  • Loading branch information
Silverlan committed Nov 25, 2024
1 parent 7628e6d commit 7f43e2b
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 74 deletions.
1 change: 1 addition & 0 deletions assets/shaders/modules/pbr.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "/common/pbr/fs_pbr.glsl"
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ namespace pragma::rendering {
public:
ShaderGraphData(const std::string &typeName, const std::string &identifier, const std::shared_ptr<pragma::shadergraph::Graph> &graph) : m_typeName {typeName}, m_identifier {identifier}, m_graph {graph} {}
const std::string &GetIdentifier() const { return m_identifier; }
const std::string &GetTypeName() const { return m_typeName; }
const std::shared_ptr<pragma::shadergraph::Graph> &GetGraph() const { return m_graph; }
void GenerateGlsl();
private:
std::string m_typeName;
Expand All @@ -44,24 +46,30 @@ namespace pragma::rendering {
std::shared_ptr<pragma::shadergraph::NodeRegistry> m_nodeRegistry;
};

class ShaderGraphModuleManager;
class DLLCLIENT ShaderGraphManager {
public:
static constexpr const char *ROOT_GRAPH_PATH = "scripts/shader_data/graphs/";
static std::string GetShaderFilePath(const std::string &type, const std::string &identifier);
static std::string GetShaderGraphFilePath(const std::string &type, const std::string &identifier);

ShaderGraphManager() {}
~ShaderGraphManager() {}
ShaderGraphManager();
~ShaderGraphManager();
const std::unordered_map<std::string, std::shared_ptr<ShaderGraphTypeManager>> &GetShaderGraphTypeManagers() const { return m_shaderGraphTypeManagers; }
void RegisterGraphTypeManager(const std::string &type, std::shared_ptr<pragma::shadergraph::NodeRegistry> nodeRegistry);
std::shared_ptr<pragma::shadergraph::Graph> RegisterGraph(const std::string &type, const std::string &identifier);
std::shared_ptr<pragma::shadergraph::Graph> CreateGraph(const std::string &type) const;
std::shared_ptr<pragma::shadergraph::Graph> LoadShader(const std::string &identifier, std::string &outErr);
void ReloadShader(const std::string &identifier);
std::shared_ptr<ShaderGraphData> GetGraph(const std::string &identifier) const;
std::shared_ptr<pragma::shadergraph::NodeRegistry> GetNodeRegistry(const std::string &type) const;

ShaderGraphModuleManager &GetModuleManager();
const ShaderGraphModuleManager &GetModuleManager() const;
private:
std::unordered_map<std::string, std::shared_ptr<ShaderGraphTypeManager>> m_shaderGraphTypeManagers;
std::unordered_map<std::string, std::string> m_shaderNameToType;
std::unique_ptr<ShaderGraphModuleManager> m_moduleManager;
};
}

Expand Down
49 changes: 49 additions & 0 deletions core/client/include/pragma/rendering/shader_graph/module.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/* 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) 2021 Silverlan
*/

#ifndef __SHADER_GRAPH_MODULE_HPP__
#define __SHADER_GRAPH_MODULE_HPP__

#include <pragma/clientdefinitions.h>
#include "pragma/rendering/shaders/world/c_shader_scene.hpp"

namespace prosper {
class Shader;
}

namespace pragma {
class CSceneComponent;
class CRasterizationRendererComponent;
};

class CModelSubMesh;
namespace pragma::rendering {
class ShaderProcessor;
class DLLCLIENT ShaderGraphModule {
public:
ShaderGraphModule(prosper::Shader &shader) : m_shader(shader) {}
virtual ~ShaderGraphModule() {}
virtual void InitializeGfxPipelineDescriptorSets() = 0;
virtual void UpdateRenderFlags(CModelSubMesh &mesh, ShaderGameWorld::SceneFlags &inOutFlags) {}
virtual void RecordBindScene(ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const = 0;
protected:
prosper::Shader &m_shader;
};

class DLLCLIENT ShaderGraphModuleManager {
public:
using Factory = std::function<std::unique_ptr<ShaderGraphModule>(prosper::Shader &shader)>;
ShaderGraphModuleManager() {}
void RegisterFactory(const std::string &name, const Factory &factory);
std::unique_ptr<ShaderGraphModule> CreateModule(const std::string &name, prosper::Shader &shader) const;
const std::unordered_map<std::string, Factory> &GetFactories() const { return m_factories; }
private:
std::unordered_map<std::string, Factory> m_factories;
};
}

#endif
40 changes: 40 additions & 0 deletions core/client/include/pragma/rendering/shader_graph/modules/pbr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/* 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_MODULES_PBR_HPP__
#define __PRAGMA_SHADER_GRAPH_MODULES_PBR_HPP__

#include "pragma/clientdefinitions.h"
#include "pragma/rendering/shader_graph/module.hpp"

import pragma.shadergraph;

namespace pragma::rendering::shader_graph {
class DLLCLIENT PbrModule : public pragma::rendering::ShaderGraphModule {
public:
public:
enum class PBRBinding : uint32_t {
IrradianceMap = 0u,
PrefilterMap,
BRDFMap,

Count
};
PbrModule(prosper::Shader &shader);
virtual ~PbrModule() override;
virtual void InitializeGfxPipelineDescriptorSets() override;
virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override;
prosper::IDescriptorSet *GetReflectionProbeDescriptorSet(const pragma::CSceneComponent &scene, float &outIblStrength, ShaderGameWorld::SceneFlags &inOutSceneFlags) const;
prosper::IDescriptorSet &GetDefaultPbrDescriptorSet() const;
private:
prosper::DescriptorSetInfo m_pbrDescSetInfo;
static std::shared_ptr<prosper::IDescriptorSetGroup> g_defaultPbrDsg;
static size_t g_instanceCount;
};
};

#endif
31 changes: 31 additions & 0 deletions core/client/include/pragma/rendering/shader_graph/nodes/pbr.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/* 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_PBR_HPP__
#define __PRAGMA_SHADER_GRAPH_NODES_PBR_HPP__

#include "pragma/clientdefinitions.h"

import pragma.shadergraph;

namespace pragma::rendering::shader_graph {
class DLLCLIENT PbrNode : public pragma::shadergraph::Node {
public:
static constexpr const char *IN_ALBEDO_COLOR = "albedoColor";
static constexpr const char *IN_METALNESS = "metalness";
static constexpr const char *IN_ROUGHNESS = "roughness";
static constexpr const char *IN_AMBIENT_OCCLUSION = "ambientOcclusion";

static constexpr const char *OUT_COLOR = "color";

PbrNode(const std::string_view &type);

virtual std::string DoEvaluate(const pragma::shadergraph::Graph &graph, const pragma::shadergraph::GraphNode &instance) const override;
};
};

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,29 @@

class Texture;
namespace pragma {
namespace rendering {
class ShaderGraphModule;
};
class DLLCLIENT ShaderGraph : public ShaderGameWorldLightingPass {
public:
ShaderGraph(prosper::IPrContext &context, const std::string &identifier, const std::string &fsShader);
virtual ~ShaderGraph() override;

virtual void RecordBindScene(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer, prosper::IDescriptorSet &dsRenderSettings,
prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, const Vector4 &drawOrigin, ShaderGameWorld::SceneFlags &inOutSceneFlags) const override;
protected:
using ShaderGameWorldLightingPass::RecordDraw;
void RecordBindSceneDescriptorSets(rendering::ShaderProcessor &shaderProcessor, const pragma::CSceneComponent &scene, const pragma::CRasterizationRendererComponent &renderer, prosper::IDescriptorSet &dsScene, prosper::IDescriptorSet &dsRenderer,
prosper::IDescriptorSet &dsRenderSettings, prosper::IDescriptorSet &dsLights, prosper::IDescriptorSet &dsShadows, ShaderGameWorld::SceneFlags &inOutSceneFlags, float &outIblStrength) const;
virtual void OnPipelinesInitialized() override;
virtual void ClearShaderResources() override;
virtual void InitializeShaderResources() override;
virtual void InitializeGfxPipeline(prosper::GraphicsPipelineCreateInfo &pipelineInfo, uint32_t pipelineIdx) override;
virtual void InitializeMaterialData(const CMaterial &mat, const rendering::shader_material::ShaderMaterial &shaderMat, pragma::rendering::shader_material::ShaderMaterialData &inOutMatData) override;
virtual void UpdateRenderFlags(CModelSubMesh &mesh, SceneFlags &inOutFlags) override;
virtual void InitializeGfxPipelineDescriptorSets() override;
std::shared_ptr<prosper::IDescriptorSetGroup> InitializeMaterialDescriptorSet(CMaterial &mat, const prosper::DescriptorSetInfo &descSetInfo);

SceneFlags m_extRenderFlags = SceneFlags::None;
std::shared_ptr<prosper::IDescriptorSetGroup> m_defaultPbrDsg = nullptr;
std::vector<std::unique_ptr<rendering::ShaderGraphModule>> m_modules;
};
};

Expand Down
7 changes: 6 additions & 1 deletion core/client/src/c_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ namespace pragma::string {
#include "pragma/rendering/c_sci_gpu_timer_manager.hpp"
#include <pragma/rendering/scene/util_draw_scene_info.hpp>
#include "pragma/rendering/shaders/world/c_shader_textured.hpp"
#include "pragma/rendering/shader_graph_manager.hpp"
#include "pragma/rendering/shader_graph/manager.hpp"
#include <pragma/entities/environment/lights/c_env_light.h>
#include <pragma/input/input_binding_layer.hpp>
#include <pragma/lua/lua_error_handling.hpp>
Expand Down Expand Up @@ -111,6 +111,8 @@ static const auto SEPARATE_JOYSTICK_AXES = true;
#include "pragma/rendering/shader_graph/nodes/lightmap.hpp"
#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/modules/pbr.hpp"

CEngine::CEngine(int argc, char *argv[])
: Engine(argc, argv), pragma::RenderContext(), m_nearZ(pragma::BaseEnvCameraComponent::DEFAULT_NEAR_Z), //10.0f), //0.1f
Expand Down Expand Up @@ -204,6 +206,7 @@ CEngine::CEngine(int argc, char *argv[])
regScene->RegisterNode<pragma::rendering::shader_graph::LightmapNode>("lightmap");
regScene->RegisterNode<pragma::rendering::shader_graph::ObjectNode>("object");
regScene->RegisterNode<pragma::rendering::shader_graph::TimeNode>("time");
regScene->RegisterNode<pragma::rendering::shader_graph::PbrNode>("pbr");

auto shaderMat = pragma::rendering::shader_material::get_cache().Load("pbr");
auto node = std::make_shared<pragma::rendering::shader_graph::ShaderMaterialNode>("test", *shaderMat);
Expand All @@ -217,6 +220,8 @@ CEngine::CEngine(int argc, char *argv[])
m_shaderGraphManager = std::make_unique<pragma::rendering::ShaderGraphManager>();
m_shaderGraphManager->RegisterGraphTypeManager("post_processing", regPp);
m_shaderGraphManager->RegisterGraphTypeManager("object", regScene);

m_shaderGraphManager->GetModuleManager().RegisterFactory("pbr", [](prosper::Shader &shader) -> std::unique_ptr<pragma::rendering::ShaderGraphModule> { return std::make_unique<pragma::rendering::shader_graph::PbrModule>(shader); });
}
}

Expand Down
89 changes: 43 additions & 46 deletions core/client/src/lua/c_luaclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
#include "pragma/rendering/shaders/util/c_shader_compose_rma.hpp"
#include "pragma/rendering/shaders/post_processing/c_shader_pp_glow.hpp"
#include "pragma/rendering/shader_material/shader_material.hpp"
#include "pragma/rendering/shader_graph_manager.hpp"
#include "pragma/rendering/shader_graph/manager.hpp"
#include "pragma/lua/libraries/ludm.hpp"
#include <pragma/lua/lua_entity_component.hpp>
#include <shader/prosper_pipeline_create_info.hpp>
Expand Down Expand Up @@ -256,14 +256,15 @@ static void register_shader_graph(lua_State *l, luabind::module_ &modShader)
defGraphNode.def("GetDisplayName", &pragma::shadergraph::GraphNode::GetDisplayName);
defGraphNode.def("ClearInputValue", &pragma::shadergraph::GraphNode::ClearInputValue);
defGraphNode.def(
"SetInputValue", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName, luabind::object value) {
"SetInputValue", +[](pragma::shadergraph::GraphNode &graphNode, const std::string_view &inputName, luabind::object value) -> bool {
auto type = Lua::udm::determine_udm_type(value);
::udm::visit(type, [&graphNode, &inputName, &value](auto tag) {
return ::udm::visit(type, [&graphNode, &inputName, &value](auto tag) {
using T = typename decltype(tag)::type;
if constexpr(pragma::shadergraph::is_socket_type<T>()) {
auto val = luabind::object_cast<T>(value);
graphNode.SetInputValue(inputName, val);
return graphNode.SetInputValue(inputName, val);
}
return false;
});
});
defGraphNode.def(
Expand Down Expand Up @@ -487,48 +488,6 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI)
}
return 0;
}},
{"register_graph",
[](lua_State *l) {
std::string type = Lua::CheckString(l, 1);
std::string identifier = Lua::CheckString(l, 2);
auto &manager = c_engine->GetShaderGraphManager();
auto graph = manager.RegisterGraph(type, identifier);
Lua::Push(l, graph);
return 1;
}},
{"create_graph",
[](lua_State *l) {
std::string type = Lua::CheckString(l, 1);
auto &manager = c_engine->GetShaderGraphManager();
auto graph = manager.CreateGraph(type);
Lua::Push(l, graph);
return 1;
}},
{"get_graph",
[](lua_State *l) {
std::string identifier = Lua::CheckString(l, 1);
auto &manager = c_engine->GetShaderGraphManager();
auto graph = manager.GetGraph(identifier);
Lua::Push(l, graph);
return 1;
}},
{"reload_graph_shader",
[](lua_State *l) {
std::string identifier = Lua::CheckString(l, 1);
auto &manager = c_engine->GetShaderGraphManager();
manager.ReloadShader(identifier);
return 0;
}},
{"get_graph_node_registry",
[](lua_State *l) {
std::string type = Lua::CheckString(l, 1);
auto &manager = c_engine->GetShaderGraphManager();
auto reg = manager.GetNodeRegistry(type);
if(!reg)
return 0;
Lua::Push(l, reg);
return 1;
}},
{"get",
[](lua_State *l) {
auto *className = Lua::CheckString(l, 1);
Expand Down Expand Up @@ -572,6 +531,44 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI)
return 1;
}}});

modShader[luabind::def(
"register_graph", +[](const std::string &type, const std::string &identifier) -> std::shared_ptr<pragma::shadergraph::Graph> {
auto &manager = c_engine->GetShaderGraphManager();
return manager.RegisterGraph(type, identifier);
})];
modShader[luabind::def(
"create_graph", +[](const std::string &type) -> std::shared_ptr<pragma::shadergraph::Graph> {
auto &manager = c_engine->GetShaderGraphManager();
return manager.CreateGraph(type);
})];
modShader[luabind::def(
"get_graph", +[](const std::string &identifier) -> std::shared_ptr<pragma::shadergraph::Graph> {
auto &manager = c_engine->GetShaderGraphManager();
auto graphData = manager.GetGraph(identifier);
if(!graphData)
return nullptr;
return graphData->GetGraph();
})];
modShader[luabind::def(
"reload_graph_shader", +[](const std::string &identifier) {
auto &manager = c_engine->GetShaderGraphManager();
manager.ReloadShader(identifier);
})];
modShader[luabind::def(
"get_graph_node_registry", +[](const std::string &type) -> std::shared_ptr<pragma::shadergraph::NodeRegistry> {
auto &manager = c_engine->GetShaderGraphManager();
return manager.GetNodeRegistry(type);
})];
modShader[luabind::def(
"load_shader_graph", +[](const std::string &identifier) -> std::pair<std::shared_ptr<pragma::shadergraph::Graph>, std::optional<std::string>> {
auto &manager = c_engine->GetShaderGraphManager();
std::string err;
auto graph = manager.LoadShader(identifier, err);
if(!graph)
return {nullptr, std::optional<std::string> {err}};
return {graph, std::optional<std::string> {}};
})];

// These have to match shaders/modules/fs_tonemapping.gls!
enum class ToneMapping : uint8_t {
None = 0,
Expand Down
Loading

0 comments on commit 7f43e2b

Please sign in to comment.