Add basic shader editing system
POC, only registered shader is the sky shader
This commit is contained in:
parent
e8032b8cf2
commit
e8fc757d99
18 changed files with 239 additions and 61 deletions
|
@ -1,3 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
|
||||
void draw_debug_ui();
|
||||
|
||||
void load_debug_options();
|
||||
void save_debug_options();
|
||||
|
||||
std::string_view get_shader_source_directory();
|
||||
|
|
|
@ -11,6 +11,13 @@
|
|||
#include "imgui_utility.hpp"
|
||||
#include "scene.hpp"
|
||||
#include "renderer.hpp"
|
||||
#include "file.hpp"
|
||||
|
||||
struct Options {
|
||||
std::string shader_source_path;
|
||||
};
|
||||
|
||||
static inline Options options;
|
||||
|
||||
void draw_general() {
|
||||
ImGui::Text("Platform: %s", platform::get_name());
|
||||
|
@ -145,6 +152,51 @@ void draw_renderer() {
|
|||
}
|
||||
}
|
||||
|
||||
static inline std::string selected_shader;
|
||||
static inline std::string loaded_shader_string;
|
||||
|
||||
void draw_shader_editor() {
|
||||
if(options.shader_source_path.empty()) {
|
||||
ImGui::Text("You haven't specified a shader source path yet. Please select one below:");
|
||||
if(ImGui::Button("Select Path")) {
|
||||
platform::open_dialog(false, [](std::string path) {
|
||||
// open_dialog() can't select folders yet, so use this as a workaround
|
||||
options.shader_source_path = file::Path(path).parent_path().string();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if(ImGui::BeginCombo("Select", nullptr)) {
|
||||
for(auto& shader : engine->get_renderer()->registered_shaders) {
|
||||
if(ImGui::Selectable(shader.filename.data())) {
|
||||
selected_shader = shader.filename;
|
||||
loaded_shader_string.clear();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
if(!selected_shader.empty()) {
|
||||
if(loaded_shader_string.empty()) {
|
||||
file::Path base_shader_path = options.shader_source_path;
|
||||
|
||||
shader_compiler.set_include_path(base_shader_path.string());
|
||||
|
||||
file::Path shader_path = file::Path(selected_shader);
|
||||
|
||||
auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl"));
|
||||
|
||||
loaded_shader_string = file->read_as_string();
|
||||
}
|
||||
|
||||
ImGui::InputTextMultiline("Source", &loaded_shader_string);
|
||||
|
||||
if(ImGui::Button("Reload"))
|
||||
engine->get_renderer()->reload_shader(selected_shader, loaded_shader_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void draw_debug_ui() {
|
||||
if(ImGui::Begin("General"))
|
||||
draw_general();
|
||||
|
@ -165,4 +217,21 @@ void draw_debug_ui() {
|
|||
draw_renderer();
|
||||
|
||||
ImGui::End();
|
||||
|
||||
if(ImGui::Begin("Shader Editor"))
|
||||
draw_shader_editor();
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
void load_debug_options() {
|
||||
// stub
|
||||
}
|
||||
|
||||
void save_debug_options() {
|
||||
// stub
|
||||
}
|
||||
|
||||
std::string_view get_shader_source_directory() {
|
||||
return options.shader_source_path;
|
||||
}
|
||||
|
|
|
@ -443,17 +443,17 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
MTLRenderPipelineDescriptor *pipelineDescriptor = [MTLRenderPipelineDescriptor new];
|
||||
|
||||
const bool has_vertex_stage = !info.shaders.vertex_path.empty() || !info.shaders.vertex_src.empty();
|
||||
const bool has_fragment_stage = !info.shaders.fragment_path.empty() || !info.shaders.fragment_src.empty();
|
||||
const bool has_vertex_stage = !info.shaders.vertex_src.empty();
|
||||
const bool has_fragment_stage = !info.shaders.fragment_src.empty();
|
||||
|
||||
if(has_vertex_stage) {
|
||||
id<MTLLibrary> vertexLibrary;
|
||||
{
|
||||
std::string vertex_src;
|
||||
if(info.shaders.vertex_path.empty()) {
|
||||
if(info.shaders.vertex_src.is_string()) {
|
||||
vertex_src = info.shaders.vertex_src.as_string();
|
||||
} else {
|
||||
const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_path);
|
||||
const auto vertex_path = utility::format("{}.msl", info.shaders.vertex_src.as_path().string());
|
||||
|
||||
auto file = file::open(file::internal_domain / vertex_path);
|
||||
if(file != std::nullopt) {
|
||||
|
@ -471,8 +471,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
id<MTLFunction> vertexFunc = [vertexLibrary newFunctionWithName:@"main0" constantValues:vertex_constants error:nil];
|
||||
|
||||
if(debug_enabled)
|
||||
vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_path.data()];
|
||||
if(debug_enabled && info.shaders.vertex_src.is_path())
|
||||
vertexFunc.label = [NSString stringWithFormat:@"%s", info.shaders.vertex_src.as_path().string().data()];
|
||||
|
||||
pipelineDescriptor.vertexFunction = vertexFunc;
|
||||
}
|
||||
|
@ -482,10 +482,10 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
id<MTLLibrary> fragmentLibrary;
|
||||
{
|
||||
std::string fragment_src;
|
||||
if(info.shaders.fragment_path.empty()) {
|
||||
if(info.shaders.fragment_src.is_string()) {
|
||||
fragment_src = info.shaders.fragment_src.as_string();
|
||||
} else {
|
||||
const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_path);
|
||||
const auto fragment_path = utility::format("{}.msl", info.shaders.fragment_src.as_path().string());
|
||||
|
||||
auto file = file::open(file::internal_domain / fragment_path);
|
||||
if(file != std::nullopt) {
|
||||
|
@ -504,8 +504,8 @@ GFXPipeline* GFXMetal::create_graphics_pipeline(const GFXGraphicsPipelineCreateI
|
|||
|
||||
id<MTLFunction> fragmentFunc = [fragmentLibrary newFunctionWithName:@"main0" constantValues:fragment_constants error:nil];
|
||||
|
||||
if(debug_enabled)
|
||||
fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_path.data()];
|
||||
if(debug_enabled && info.shaders.fragment_src.is_path())
|
||||
fragmentFunc.label = [NSString stringWithFormat:@"%s", info.shaders.fragment_src.as_path().string().data()];
|
||||
|
||||
pipelineDescriptor.fragmentFunction = fragmentFunc;
|
||||
}
|
||||
|
|
|
@ -157,8 +157,6 @@ struct GFXGraphicsPipelineCreateInfo {
|
|||
std::string label; // only used for debug
|
||||
|
||||
struct Shaders {
|
||||
std::string_view vertex_path, fragment_path;
|
||||
|
||||
ShaderSource vertex_src, fragment_src;
|
||||
|
||||
GFXShaderConstants vertex_constants, fragment_constants;
|
||||
|
|
3
engine/platform/CMakeLists.txt
Executable file
3
engine/platform/CMakeLists.txt
Executable file
|
@ -0,0 +1,3 @@
|
|||
add_library(Platform INTERFACE)
|
||||
target_include_directories(Platform INTERFACE include)
|
||||
target_link_libraries(Platform INTERFACE Utility)
|
|
@ -10,6 +10,7 @@
|
|||
#include "common.hpp"
|
||||
#include "render_options.hpp"
|
||||
#include "path.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
|
||||
namespace ui {
|
||||
class Screen;
|
||||
|
@ -128,7 +129,21 @@ public:
|
|||
GFXRenderPass* unormRenderPass = nullptr;
|
||||
GFXPipeline* renderToUnormTexturePipeline = nullptr;
|
||||
GFXRenderPass* viewportRenderPass = nullptr;
|
||||
|
||||
|
||||
ShaderSource register_shader(const std::string_view shader_file);
|
||||
void associate_shader_reload(const std::string_view shader_file, const std::function<void()> reload_function);
|
||||
void reload_shader(const std::string_view shader_file, const std::string_view shader_source);
|
||||
|
||||
struct RegisteredShader {
|
||||
std::string filename;
|
||||
std::string injected_shader_source;
|
||||
std::function<void()> reload_function;
|
||||
};
|
||||
|
||||
std::vector<RegisteredShader> registered_shaders;
|
||||
|
||||
bool reloading_shader = false;
|
||||
|
||||
private:
|
||||
void createDummyTexture();
|
||||
void createOffscreenResources();
|
||||
|
|
|
@ -27,9 +27,9 @@ DoFPass::DoFPass(GFX* gfx, Renderer* renderer) : renderer(renderer) {
|
|||
height_constant.value = extent.height;
|
||||
|
||||
GFXGraphicsPipelineCreateInfo create_info = {};
|
||||
create_info.shaders.vertex_path = "dof.vert";
|
||||
create_info.shaders.vertex_src = file::Path("dof.vert");
|
||||
create_info.shaders.vertex_constants = {width_constant, height_constant};
|
||||
create_info.shaders.fragment_path = "dof.frag";
|
||||
create_info.shaders.fragment_src = file::Path("dof.frag");
|
||||
|
||||
create_info.shader_input.bindings = {
|
||||
{0, GFXBindingType::StorageImage},
|
||||
|
|
|
@ -14,8 +14,8 @@ GaussianHelper::GaussianHelper(GFX* gfx, const prism::Extent extent) : extent(ex
|
|||
// pipeline
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Gaussian";
|
||||
pipelineInfo.shaders.vertex_path = "gaussian.vert";
|
||||
pipelineInfo.shaders.fragment_path = "gaussian.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("gaussian.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("gaussian.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ void ImGuiPass::initialize() {
|
|||
void ImGuiPass::resize(const prism::Extent extent) {
|
||||
GFXGraphicsPipelineCreateInfo createInfo;
|
||||
createInfo.label = "ImGui";
|
||||
createInfo.shaders.vertex_path = "imgui.vert";
|
||||
createInfo.shaders.fragment_path = "imgui.frag";
|
||||
createInfo.shaders.vertex_src = file::Path("imgui.vert");
|
||||
createInfo.shaders.fragment_src = file::Path("imgui.frag");
|
||||
|
||||
GFXVertexInput vertexInput = {};
|
||||
vertexInput.stride = sizeof(ImDrawVert);
|
||||
|
|
|
@ -36,7 +36,7 @@ ShaderSource get_shader(std::string filename, bool skinned, bool cubemap) {
|
|||
|
||||
GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateInfo createInfo, bool positions_only, bool cubemap) {
|
||||
// take vertex src
|
||||
std::string vertex_path = createInfo.shaders.vertex_path.data();
|
||||
std::string vertex_path = createInfo.shaders.vertex_src.as_path().string();
|
||||
vertex_path += ".glsl";
|
||||
|
||||
if (positions_only)
|
||||
|
@ -46,7 +46,6 @@ GFXPipeline* MaterialCompiler::create_static_pipeline(GFXGraphicsPipelineCreateI
|
|||
createInfo.label += "cubemap ver";
|
||||
|
||||
createInfo.shaders.vertex_src = get_shader(vertex_path, false, cubemap);
|
||||
createInfo.shaders.vertex_path = "";
|
||||
|
||||
if(positions_only) {
|
||||
createInfo.vertex_input.inputs = {
|
||||
|
@ -81,11 +80,10 @@ GFXPipeline* MaterialCompiler::create_skinned_pipeline(GFXGraphicsPipelineCreate
|
|||
createInfo.label += " (Skinned)";
|
||||
|
||||
// take vertex src
|
||||
std::string vertex_path = createInfo.shaders.vertex_path.data();
|
||||
std::string vertex_path = createInfo.shaders.vertex_src.as_path().string();
|
||||
vertex_path += ".glsl";
|
||||
|
||||
createInfo.shaders.vertex_src = get_shader(vertex_path, true, false);
|
||||
createInfo.shaders.vertex_path = "";
|
||||
|
||||
createInfo.shader_input.bindings.push_back({ 14, GFXBindingType::StorageBuffer });
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "frustum.hpp"
|
||||
#include "shadercompiler.hpp"
|
||||
#include "asset.hpp"
|
||||
#include "debug.hpp"
|
||||
|
||||
struct ElementInstance {
|
||||
Vector4 color;
|
||||
|
@ -710,8 +711,8 @@ void Renderer::create_mesh_pipeline(Material& material) {
|
|||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Mesh";
|
||||
pipelineInfo.shaders.vertex_path = "mesh.vert";
|
||||
pipelineInfo.shaders.fragment_path = "mesh.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("mesh.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("mesh.frag");
|
||||
|
||||
pipelineInfo.shaders.vertex_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant};
|
||||
pipelineInfo.shaders.fragment_constants = {materials_constant, lights_constant, spot_lights_constant, probes_constant};
|
||||
|
@ -738,7 +739,6 @@ void Renderer::create_mesh_pipeline(Material& material) {
|
|||
pipelineInfo.blending.dst_rgb = GFXBlendFactor::OneMinusSrcAlpha;
|
||||
|
||||
pipelineInfo.shaders.fragment_src = material_compiler.compile_material_fragment(material);
|
||||
pipelineInfo.shaders.fragment_path = "";
|
||||
|
||||
for (auto [index, texture] : material.bound_textures) {
|
||||
GFXShaderBinding binding;
|
||||
|
@ -852,8 +852,8 @@ void Renderer::createPostPipeline() {
|
|||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Post";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "post.vert";
|
||||
pipelineInfo.shaders.fragment_path = "post.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("post.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("post.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{4, GFXBindingType::PushConstant},
|
||||
|
@ -904,8 +904,8 @@ void Renderer::createFontPipeline() {
|
|||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Text";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "text.vert";
|
||||
pipelineInfo.shaders.fragment_path = "text.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("text.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("text.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
|
@ -950,8 +950,8 @@ void Renderer::createSkyPipeline() {
|
|||
pipelineInfo.label = "Sky";
|
||||
pipelineInfo.render_pass = offscreenRenderPass;
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "sky.vert";
|
||||
pipelineInfo.shaders.fragment_path = "sky.frag";
|
||||
pipelineInfo.shaders.vertex_src = register_shader("sky.vert");
|
||||
pipelineInfo.shaders.fragment_src = register_shader("sky.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::PushConstant}
|
||||
|
@ -964,14 +964,22 @@ void Renderer::createSkyPipeline() {
|
|||
pipelineInfo.depth.depth_mode = GFXDepthMode::LessOrEqual;
|
||||
|
||||
skyPipeline = gfx->create_graphics_pipeline(pipelineInfo);
|
||||
|
||||
associate_shader_reload("sky.vert", [this] {
|
||||
createSkyPipeline();
|
||||
});
|
||||
|
||||
associate_shader_reload("sky.frag", [this] {
|
||||
createSkyPipeline();
|
||||
});
|
||||
}
|
||||
|
||||
void Renderer::createUIPipeline() {
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "UI";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "ui.vert";
|
||||
pipelineInfo.shaders.fragment_path = "ui.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("ui.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("ui.frag");
|
||||
|
||||
pipelineInfo.rasterization.primitive_type = GFXPrimitiveType::TriangleStrip;
|
||||
|
||||
|
@ -1026,8 +1034,8 @@ void Renderer::createBRDF() {
|
|||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "BRDF";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "brdf.vert";
|
||||
pipelineInfo.shaders.fragment_path = "brdf.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("brdf.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("brdf.frag");
|
||||
|
||||
pipelineInfo.render_pass = brdfRenderPass;
|
||||
|
||||
|
@ -1100,3 +1108,64 @@ void Renderer::create_histogram_resources() {
|
|||
|
||||
average_luminance_texture = gfx->create_texture(texture_info);
|
||||
}
|
||||
|
||||
ShaderSource Renderer::register_shader(const std::string_view shader_file) {
|
||||
if(!reloading_shader) {
|
||||
RegisteredShader shader;
|
||||
shader.filename = shader_file;
|
||||
|
||||
registered_shaders.push_back(shader);
|
||||
}
|
||||
|
||||
std::string found_shader_source;
|
||||
for(auto& shader : registered_shaders) {
|
||||
if(shader.filename == shader_file) {
|
||||
found_shader_source = shader.injected_shader_source;
|
||||
}
|
||||
}
|
||||
|
||||
file::Path base_shader_path = get_shader_source_directory();
|
||||
|
||||
// if shader editor system is not initialized, use prebuilt shaders
|
||||
if(base_shader_path.empty())
|
||||
return file::Path(shader_file);
|
||||
|
||||
shader_compiler.set_include_path(base_shader_path.string());
|
||||
|
||||
file::Path shader_path = file::Path(shader_file);
|
||||
|
||||
ShaderStage stage;
|
||||
if(shader_path.extension() == ".vert")
|
||||
stage = ShaderStage::Vertex;
|
||||
else if(shader_path.extension() == ".frag")
|
||||
stage = ShaderStage::Fragment;
|
||||
|
||||
if(found_shader_source.empty()) {
|
||||
auto file = file::open(base_shader_path / shader_path.replace_extension(shader_path.extension().string() + ".glsl"));
|
||||
|
||||
return shader_compiler.compile(ShaderLanguage::GLSL, stage, file->read_as_string(), ShaderLanguage::MSL).value();
|
||||
} else {
|
||||
return shader_compiler.compile(ShaderLanguage::GLSL, stage, found_shader_source, ShaderLanguage::MSL).value();
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::associate_shader_reload(const std::string_view shader_file, const std::function<void()> reload_function) {
|
||||
if(reloading_shader)
|
||||
return;
|
||||
|
||||
for(auto& shader : registered_shaders) {
|
||||
if(shader.filename == shader_file)
|
||||
shader.reload_function = reload_function;
|
||||
}
|
||||
}
|
||||
|
||||
void Renderer::reload_shader(const std::string_view shader_file, const std::string_view shader_source) {
|
||||
for(auto& shader : registered_shaders) {
|
||||
if(shader.filename == shader_file) {
|
||||
shader.injected_shader_source = shader_source;
|
||||
reloading_shader = true;
|
||||
shader.reload_function();
|
||||
reloading_shader = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -399,8 +399,8 @@ void SceneCapture::createSkyResources() {
|
|||
pipelineInfo.label = "Sky Scene Capture";
|
||||
pipelineInfo.render_pass = renderPass;
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "sky.vert";
|
||||
pipelineInfo.shaders.fragment_path = "sky.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("sky.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("sky.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::PushConstant}
|
||||
|
@ -443,8 +443,8 @@ void SceneCapture::createIrradianceResources() {
|
|||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Irradiance Convolution";
|
||||
pipelineInfo.shaders.vertex_path = "irradiance.vert";
|
||||
pipelineInfo.shaders.fragment_path = "irradiance.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("irradiance.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("irradiance.frag");
|
||||
|
||||
GFXVertexInput input;
|
||||
input.stride = sizeof(Vector3);
|
||||
|
@ -495,8 +495,8 @@ void SceneCapture::createPrefilterResources() {
|
|||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Prefilter";
|
||||
pipelineInfo.shaders.vertex_path = "filter.vert";
|
||||
pipelineInfo.shaders.fragment_path = "filter.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("filter.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("filter.frag");
|
||||
|
||||
pipelineInfo.shaders.fragment_constants = {size_constant};
|
||||
|
||||
|
|
|
@ -315,7 +315,7 @@ void ShadowPass::create_pipelines() {
|
|||
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.shaders.vertex_constants = {point_light_max_constant};
|
||||
pipelineInfo.shaders.vertex_path = "shadow.vert";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("shadow.vert");
|
||||
|
||||
pipelineInfo.shaders.fragment_constants = { point_light_max_constant };
|
||||
//pipelineInfo.shaders.fragment_path = "shadow.frag";
|
||||
|
@ -360,7 +360,7 @@ void ShadowPass::create_pipelines() {
|
|||
{
|
||||
pipelineInfo.label = "Point Shadow";
|
||||
|
||||
pipelineInfo.shaders.fragment_path = "omnishadow.frag";
|
||||
pipelineInfo.shaders.fragment_src = file::Path("omnishadow.frag");
|
||||
|
||||
auto [static_pipeline, skinned_pipeline] = material_compiler.create_pipeline_permutations(pipelineInfo, true);
|
||||
|
||||
|
|
|
@ -112,8 +112,8 @@ void SMAAPass::create_pipelines() {
|
|||
|
||||
GFXGraphicsPipelineCreateInfo createInfo = {};
|
||||
createInfo.label = "SMAA Edge";
|
||||
createInfo.shaders.vertex_path = "edge.vert";
|
||||
createInfo.shaders.fragment_path = "edge.frag";
|
||||
createInfo.shaders.vertex_src = file::Path("edge.vert");
|
||||
createInfo.shaders.fragment_src = file::Path("edge.frag");
|
||||
|
||||
createInfo.render_pass = render_pass;
|
||||
|
||||
|
@ -130,8 +130,8 @@ void SMAAPass::create_pipelines() {
|
|||
edge_pipeline = gfx->create_graphics_pipeline(createInfo);
|
||||
|
||||
createInfo.label = "SMAA Blend";
|
||||
createInfo.shaders.vertex_path = "blend.vert";
|
||||
createInfo.shaders.fragment_path = "blend.frag";
|
||||
createInfo.shaders.vertex_src = file::Path("blend.vert");
|
||||
createInfo.shaders.fragment_src = file::Path("blend.frag");
|
||||
createInfo.shader_input.bindings.push_back({3, GFXBindingType::Texture});
|
||||
|
||||
blend_pipeline = gfx->create_graphics_pipeline(createInfo);
|
||||
|
|
|
@ -7,6 +7,8 @@ set(SRC
|
|||
|
||||
add_library(ShaderCompiler STATIC ${SRC})
|
||||
target_link_libraries(ShaderCompiler
|
||||
PUBLIC
|
||||
Platform
|
||||
PRIVATE
|
||||
Utility
|
||||
Log
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <string_view>
|
||||
#include <optional>
|
||||
|
||||
#include "file.hpp"
|
||||
|
||||
/// The shader stage that the shader is written in.
|
||||
enum class ShaderStage {
|
||||
Vertex,
|
||||
|
@ -41,8 +43,14 @@ public:
|
|||
ShaderSource(const ShaderSource& rhs) : source (rhs.source) {}
|
||||
ShaderSource(const std::string source_string) : source(source_string) {}
|
||||
ShaderSource(const std::vector<uint32_t> source_bytecode) : source(source_bytecode) {}
|
||||
|
||||
std::variant<std::monostate, std::string, std::vector<uint32_t>> source;
|
||||
ShaderSource(const file::Path shader_path) : source(shader_path) {}
|
||||
|
||||
std::variant<std::monostate, file::Path, std::string, std::vector<uint32_t>> source;
|
||||
|
||||
/// Returns a view of the shader source as a path.
|
||||
file::Path as_path() const {
|
||||
return std::get<file::Path>(source);
|
||||
}
|
||||
|
||||
/// Returns a view of the shader source as plaintext.
|
||||
std::string_view as_string() const {
|
||||
|
@ -57,6 +65,14 @@ public:
|
|||
bool empty() const {
|
||||
return std::holds_alternative<std::monostate>(source);
|
||||
}
|
||||
|
||||
bool is_path() const {
|
||||
return std::holds_alternative<file::Path>(source);
|
||||
}
|
||||
|
||||
bool is_string() const {
|
||||
return std::holds_alternative<std::string>(source);
|
||||
}
|
||||
};
|
||||
|
||||
/// Compiles GLSL shaders to a specified shader language offline or at runtime.
|
||||
|
|
|
@ -9,14 +9,14 @@
|
|||
#include "includer.hpp"
|
||||
#include "defaultresources.hpp"
|
||||
|
||||
static inline std::string include_path;
|
||||
static inline std::vector<std::string> include_path;
|
||||
|
||||
ShaderCompiler::ShaderCompiler() {
|
||||
glslang::InitializeProcess();
|
||||
}
|
||||
|
||||
void ShaderCompiler::set_include_path(const std::string_view path) {
|
||||
include_path = path;
|
||||
include_path.push_back(path.data());
|
||||
}
|
||||
|
||||
const std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_string, const EShLanguage shader_language, const CompileOptions& options) {
|
||||
|
@ -50,7 +50,8 @@ const std::vector<uint32_t> compile_glsl_to_spv(const std::string_view source_st
|
|||
EShMessages messages = (EShMessages) (EShMsgDefault);
|
||||
|
||||
DirStackFileIncluder includer;
|
||||
includer.pushExternalLocalDirectory(include_path);
|
||||
for(auto path : include_path)
|
||||
includer.pushExternalLocalDirectory(path);
|
||||
|
||||
if (!Shader.parse(&Resources, 100, false, messages, includer)) {
|
||||
console::error(System::Renderer, "{}", Shader.getInfoLog());
|
||||
|
|
|
@ -21,8 +21,8 @@ void DebugPass::initialize() {
|
|||
|
||||
{
|
||||
GFXGraphicsPipelineCreateInfo createInfo;
|
||||
createInfo.shaders.vertex_path = "debug.vert";
|
||||
createInfo.shaders.fragment_path = "debug.frag";
|
||||
createInfo.shaders.vertex_src = file::Path("debug.vert");
|
||||
createInfo.shaders.fragment_src = file::Path("debug.frag");
|
||||
|
||||
GFXVertexInput vertexInput = {};
|
||||
vertexInput.stride = sizeof(Vector3);
|
||||
|
@ -69,8 +69,8 @@ void DebugPass::initialize() {
|
|||
// pipeline
|
||||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "color.vert";
|
||||
pipelineInfo.shaders.fragment_path = "color.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("color.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("color.frag");
|
||||
|
||||
GFXVertexInput input;
|
||||
input.stride = sizeof(Vector3);
|
||||
|
@ -110,8 +110,8 @@ void DebugPass::initialize() {
|
|||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Sobel";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "color.vert";
|
||||
pipelineInfo.shaders.fragment_path = "color.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("color.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("color.frag");
|
||||
|
||||
GFXVertexInput input;
|
||||
input.stride = sizeof(Vector3);
|
||||
|
@ -142,8 +142,8 @@ void DebugPass::initialize() {
|
|||
GFXGraphicsPipelineCreateInfo pipelineInfo = {};
|
||||
pipelineInfo.label = "Billboard";
|
||||
|
||||
pipelineInfo.shaders.vertex_path = "billboard.vert";
|
||||
pipelineInfo.shaders.fragment_path = "billboard.frag";
|
||||
pipelineInfo.shaders.vertex_src = file::Path("billboard.vert");
|
||||
pipelineInfo.shaders.fragment_src = file::Path("billboard.frag");
|
||||
|
||||
pipelineInfo.shader_input.bindings = {
|
||||
{1, GFXBindingType::PushConstant},
|
||||
|
|
Reference in a new issue