adding custom pipeline for water (what a journey to do so...)

This commit is contained in:
2025-06-02 00:00:08 +02:00
parent ce9335ba6a
commit f6decee5fa
22 changed files with 355 additions and 122 deletions

View File

@@ -2,6 +2,8 @@
#include <Block.h>
#include <World.h>
#include <ScopCore.h>
#define POS_TO_INDEX(posx, posz) (posx * CHUNK_SIZE.x + posz)
constexpr Scop::Vec2ui SPRITE_SIZE = { 16, 16 };
@@ -29,6 +31,11 @@ enum class Side : std::uint8_t
Side
};
struct WaterData
{
float time;
};
Scop::Vec2f GetAtlasOffset(BlockType type, Side side)
{
Scop::Vec2ui pos = BLOCKS_TO_ATLAS[static_cast<std::uint32_t>(type)][static_cast<std::uint8_t>(side)];
@@ -80,7 +87,7 @@ void Chunk::GenerateMesh()
std::vector<std::uint32_t>& index_data = (is_water ? m_water_mesh_index_data : m_mesh_index_data);
std::uint32_t& offset = (is_water ? water_offset : mesh_offset);
Scop::Vec4f base_color = is_water ? Scop::Vec4f{ 0.3f, 0.5f, 0.5f, 0.8f } : Scop::Vec4f{ 1.0f };
Scop::Vec4f base_color = is_water ? Scop::Vec4f{ 0.3f, 0.1f, 0.05f, 0.98f } : Scop::Vec4f{ 1.0f };
std::uint32_t invalid_limit = is_water ? static_cast<std::uint32_t>(BlockType::Air) : static_cast<std::uint32_t>(BlockType::Water);
if(GetBlock(Scop::Vec3i(x, y, z + 1)) <= invalid_limit)
@@ -333,6 +340,19 @@ void Chunk::UploadMesh()
actor.SetScale(Scop::Vec3f{ 2.0f });
actor.SetPosition(Scop::Vec3f(m_position.x, 0.0f, m_position.y));
actor.SetIsOpaque(false);
actor.SetCustomPipeline({
.pipeline = m_world.GetWaterPipeline(),
.data{ sizeof(WaterData) }
});
std::memset(actor.GetCustomPipeline()->data.GetData(), 0, actor.GetCustomPipeline()->data.GetSize());
auto object_update = [](Scop::NonOwningPtr<Scop::Scene> scene, Scop::NonOwningPtr<Scop::Actor> actor, Scop::Inputs& input, float delta)
{
WaterData* data = actor->GetCustomPipeline()->data.GetDataAs<WaterData>();
data->time += delta;
};
using actor_hook = std::function<void(Scop::NonOwningPtr<Scop::Actor>)>;
actor.AttachScript(std::make_shared<Scop::NativeActorScript>(actor_hook{}, object_update, actor_hook{}));
p_water_actor = &actor;
}
}

View File

@@ -6,8 +6,18 @@
#include <World.h>
#include <Utils.h>
World::World(Scop::Scene& scene) : m_noisecollection(42), m_fps_counter(), m_scene(scene), m_previous_chunk_position(-1000, 10000)
World::World(Scop::Scene& scene) : m_noisecollection(42), p_water_pipeline(std::make_shared<Scop::GraphicPipeline>()), m_fps_counter(), m_scene(scene), m_previous_chunk_position(-1000, 10000)
{
p_water_vertex_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/WaterVertex.spv", Scop::ShaderType::Vertex, Scop::DefaultForwardVertexShaderLayout);
p_water_fragment_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/WaterFragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout);
Scop::GraphicPipelineDescriptor pipeline_descriptor;
pipeline_descriptor.vertex_shader = p_water_vertex_shader;
pipeline_descriptor.fragment_shader = p_water_fragment_shader;
pipeline_descriptor.clear_color_attachments = false;
pipeline_descriptor.name = "water_forward_pass_pipeline";
p_water_pipeline->Init(pipeline_descriptor);
Scop::Vec2ui32 map_size;
Scop::MaterialTextures material_params;
material_params.albedo = std::make_shared<Scop::Texture>(Scop::LoadBMPFile(GetResourcesPath() / "atlas.bmp", map_size), map_size.x, map_size.y);

View File

@@ -36,6 +36,8 @@ class World
[[nodiscard]] inline Scop::Scene& GetScene() noexcept { return m_scene; }
[[nodiscard]] inline std::shared_ptr<Scop::Material> GetBlockMaterial() const { return p_block_material; }
[[nodiscard]] inline std::shared_ptr<Scop::GraphicPipeline> GetWaterPipeline() const { return p_water_pipeline; }
[[nodiscard]] Scop::NonOwningPtr<Chunk> GetChunk(Scop::Vec2i position);
[[nodiscard]] NoiseCollection& GetNoiseGenerator() noexcept { return m_noisecollection; }
@@ -52,6 +54,9 @@ class World
std::unordered_map<Scop::Vec2i, Chunk> m_chunks;
ThreadSafeQueue<std::reference_wrapper<Chunk>> m_chunks_to_upload;
std::shared_ptr<Scop::Material> p_block_material;
std::shared_ptr<Scop::GraphicPipeline> p_water_pipeline;
std::shared_ptr<Scop::Shader> p_water_vertex_shader;
std::shared_ptr<Scop::Shader> p_water_fragment_shader;
Scop::Scene& m_scene;
Scop::Vec2i m_previous_chunk_position;
Scop::Vec2i m_current_chunk_position;

View File

@@ -9,8 +9,8 @@ int main(int ac, char** av)
{
Scop::ScopEngine engine(ac, av, "Vox", 0, 0, GetExecutablePath().parent_path().parent_path() / "ScopEngine/Assets");
Scop::Scene& splash_scene = SplashScreen();
std::shared_ptr<Scop::Shader> shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Fragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout);
std::shared_ptr<Scop::Shader> post_process_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/PostProcess.spv", Scop::ShaderType::Fragment, Scop::PostProcessShaderLayout);
std::shared_ptr<Scop::Shader> shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/Fragment.spv", Scop::ShaderType::Fragment, Scop::DefaultShaderLayout);
std::shared_ptr<Scop::Shader> post_process_shader = Scop::LoadShaderFromFile(GetExecutablePath().parent_path().parent_path() / "Resources/Shaders/Build/PostProcess.spv", Scop::ShaderType::Fragment, Scop::PostProcessShaderLayout);
Scop::SceneDescriptor main_scene_desc;
main_scene_desc.fragment_shader = shader;

View File

@@ -2,11 +2,16 @@ NAME = vox
SRCS += $(wildcard $(addsuffix /*.cpp, ./Application))
SHADER_SRCS = $(wildcard $(addsuffix /*.nzsl, ./Resources/Shaders))
BIN_DIR = Bin
OBJ_DIR = Objects
RES_DIR = Resources
SHADER_DIR = Resources/Shaders/Build
SHADER_MODULE_DIR = ScopEngine/Assets/Shaders/Modules
OBJS = $(addprefix $(OBJ_DIR)/, $(SRCS:.cpp=.o))
SPVS = $(addprefix $(SHADER_DIR)/, $(SHADER_SRCS:.nzsl=.spv))
CXX = clang++
CXXFLAGS = -std=c++20 -I ScopEngine/Runtime/Includes -I Application -I ScopEngine/ThirdParty/KVF -I ScopEngine/ThirdParty -D KVF_IMPL_VK_NO_PROTOTYPES
@@ -58,15 +63,25 @@ $(OBJ_DIR)/%.o: %.cpp
all: $(NAME)
$(NAME): $(OBJ_DIR) $(BIN_DIR) engine $(OBJS)
@printf "$(COLOR)($(_BOLD)100%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)Resources/Fragment.nzsl$(_RESET)\n"
@$(NZSLC) --compile=spv Resources/Fragment.nzsl -o Resources/ --optimize --module="ScopEngine/Assets/Shaders/Modules"
@printf "$(COLOR)($(_BOLD)100%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)Resources/Screen.nzsl$(_RESET)\n"
@$(NZSLC) --compile=spv Resources/PostProcess.nzsl -o Resources/ --optimize --module="ScopEngine/Assets/Shaders/Modules"
$(NAME): $(OBJ_DIR) $(BIN_DIR) shaders engine $(OBJS)
@printf "Linking $(_BOLD)$(NAME)$(_RESET)\n"
@$(CXX) -o $(BIN_DIR)/$(NAME) $(OBJS) $(LDFLAGS)
@printf "$(_BOLD)$(NAME)$(_RESET) compiled $(COLOR)$(_BOLD)successfully$(_RESET)\n"
SPVS_TOTAL = $(words $(SPVS))
N_SPVS := $(shell find $(SHADERS_DIR) -type f -name '*.spv.h' 2>/dev/null | wc -l)
SPVS_TOTAL := $(shell echo $$(( $(SPVS_TOTAL) - $(N_SPVS) )))
ifeq ($(SPVS_TOTAL), 0) # Same
SPVS_TOTAL := 1
endif
CURR_SPV = 0
$(SHADER_DIR)/%.spv: %.nzsl
@$(eval CURR_SPV=$(shell echo $$(( $(CURR_SPV) + 1 ))))
@$(eval PERCENT=$(shell echo $$(( $(CURR_SPV) * 100 / $(SPVS_TOTAL) ))))
@printf "$(COLOR)($(_BOLD)%3s%%$(_RESET)$(COLOR)) $(_RESET)Compiling $(_BOLD)$<$(_RESET)\n" "$(PERCENT)"
@$(NZSLC) --compile=spv $< -o $(SHADER_DIR) --optimize --module=$(SHADER_MODULE_DIR)
engine:
@make -j$(JOBS) -C ScopEngine DEBUG=$(DEBUG) --no-print-directory
@@ -76,10 +91,18 @@ $(OBJ_DIR):
$(BIN_DIR):
@mkdir -p $(BIN_DIR)
$(SHADER_DIR):
@mkdir -p $(SHADER_DIR)
shaders: $(SHADER_DIR) $(SPVS)
run:
@$(BIN_DIR)/$(NAME) $(RES_DIR)/42.obj
re-shaders:
clean-shaders:
@$(RM) $(SHADER_DIR)
re-shaders: clean-shaders shaders
@make -C ScopEngine re-shaders
clean:
@@ -92,4 +115,4 @@ fclean: clean
re: fclean all
.PHONY: all run clean fclean re re-shaders
.PHONY: all run clean fclean re clean-shaders re-shaders

39
Resources/Shaders/WaterFragment.nzsl git.filemode.normal_file
View File

@@ -0,0 +1,39 @@
[nzsl_version("1.0")]
module;
struct VertOut
{
[location(0)] color: vec4[f32],
[location(1)] uv: vec2[f32],
[location(2)] time: f32,
[builtin(position)] pos: vec4[f32]
}
struct FragmentData
{
dissolve_texture_factor: f32,
dissolve_black_white_colors_factor: f32,
dissolve_normals_colors_factor: f32,
}
struct FragOut
{
[location(0)] color: vec4[f32]
}
external
{
[set(1), binding(0)] u_albedo: sampler2D[f32],
[set(1), binding(1)] u_fragment_data: uniform[FragmentData],
}
[entry(frag)]
fn main(input: VertOut) -> FragOut
{
if(input.color.a == 0.0)
discard;
let output: FragOut;
output.color = input.color * u_albedo.Sample(input.uv) * vec4[f32](sin(input.time), 1.0, cos(input.time), 1.0);
return output;
}

49
Resources/Shaders/WaterVertex.nzsl git.filemode.normal_file
View File

@@ -0,0 +1,49 @@
[nzsl_version("1.0")]
module;
import ViewerData from ScopEngine.ViewerData;
struct VertIn
{
[location(0)] pos: vec4[f32],
[location(1)] color: vec4[f32],
[location(2)] normal: vec4[f32],
[location(3)] uv: vec2[f32]
}
struct VertOut
{
[location(0)] color: vec4[f32],
[location(1)] uv: vec2[f32],
[location(2)] time: f32,
[builtin(position)] pos: vec4[f32]
}
struct ModelData
{
matrix: mat4[f32],
normal: mat4[f32],
}
struct CustomData
{
time: f32,
}
external
{
[set(0), binding(0)] viewer_data: uniform[ViewerData],
[set(0), binding(1)] data: uniform[CustomData],
model: push_constant[ModelData]
}
[entry(vert)]
fn main(input: VertIn) -> VertOut
{
let output: VertOut;
output.color = input.color;
output.uv = input.uv;
output.time = data.time;
output.pos = viewer_data.view_proj_matrix * model.matrix * input.pos;
return output;
}

View File

@@ -1,12 +1,14 @@
#ifndef __SCOP_GRAPHICS_ACTOR__
#define __SCOP_GRAPHICS_ACTOR__
#include <optional>
#include <Core/UUID.h>
#include <Maths/Vec3.h>
#include <Maths/Vec4.h>
#include <Maths/Quaternions.h>
#include <Core/Script.h>
#include <Maths/Quaternions.h>
#include <Graphics/Model.h>
#include <Core/UUID.h>
namespace Scop
{
@@ -17,7 +19,9 @@ namespace Scop
public:
struct CustomPipeline
{
std::shared_ptr<Shader> shader;
std::shared_ptr<GraphicPipeline> pipeline;
std::shared_ptr<DescriptorSet> set;
std::shared_ptr<UniformBuffer> data_uniform_buffer;
CPUBuffer data;
};
@@ -33,6 +37,7 @@ namespace Scop
inline void SetOrientation(Quatf orientation) noexcept { m_orientation = orientation; }
inline void SetVisibility(bool show) noexcept { m_is_visible = show; }
inline void SetIsOpaque(bool opaque) noexcept { m_is_opaque = opaque; }
inline void SetCustomPipeline(const CustomPipeline& pipeline) { m_custom_pipeline = pipeline; }
[[nodiscard]] inline const Vec3f& GetPosition() const noexcept { return m_position; }
[[nodiscard]] inline const Vec3f& GetScale() const noexcept { return m_scale; }
@@ -42,6 +47,7 @@ namespace Scop
[[nodiscard]] inline std::uint64_t GetUUID() const noexcept { return m_uuid; }
[[nodiscard]] inline bool IsVisible() const noexcept { return m_is_visible; }
[[nodiscard]] inline bool IsOpaque() const noexcept { return m_is_opaque; }
[[nodiscard]] inline std::optional<CustomPipeline>& GetCustomPipeline() { return m_custom_pipeline; }
~Actor();
@@ -55,6 +61,7 @@ namespace Scop
Vec3f m_scale = Vec3f{ 1.0f, 1.0f, 1.0f };
std::shared_ptr<ActorScript> p_script;
std::uint64_t m_uuid;
std::optional<CustomPipeline> m_custom_pipeline;
bool m_is_visible = true;
bool m_is_opaque = true;
};

View File

@@ -6,6 +6,7 @@
#include <kvf.h>
#include <Graphics/Enums.h>
#include <Renderer/Image.h>
#include <Utils/NonOwningPtr.h>
#include <Renderer/Pipelines/Shader.h>
@@ -21,11 +22,11 @@ namespace Scop
NonOwningPtr<DepthImage> depth = nullptr;
NonOwningPtr<class Renderer> renderer = nullptr;
std::string name = {};
VkCullModeFlagBits culling = VK_CULL_MODE_FRONT_BIT;
VkPolygonMode mode = VK_POLYGON_MODE_FILL;
CullMode culling = CullMode::Front;
bool no_vertex_inputs = false;
bool depth_test_equal = false;
bool clear_color_attachments = true;
bool wireframe = false;
};
class GraphicPipeline : public Pipeline
@@ -33,7 +34,7 @@ namespace Scop
public:
GraphicPipeline() = default;
void Init(const GraphicPipelineDescriptor& descriptor);
void Init(GraphicPipelineDescriptor descriptor);
bool BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array<float, 4> clear) noexcept;
void EndPipeline(VkCommandBuffer command_buffer) noexcept override;
void Destroy() noexcept;
@@ -41,6 +42,8 @@ namespace Scop
[[nodiscard]] inline VkPipeline GetPipeline() const override { return m_pipeline; }
[[nodiscard]] inline VkPipelineLayout GetPipelineLayout() const override { return m_pipeline_layout; }
[[nodiscard]] inline VkPipelineBindPoint GetPipelineBindPoint() const override { return VK_PIPELINE_BIND_POINT_GRAPHICS; }
[[nodiscard]] inline bool IsPipelineBound() const noexcept { return s_bound_pipeline == this; }
[[nodiscard]] inline GraphicPipelineDescriptor& GetDescription() noexcept { return m_description; }
inline ~GraphicPipeline() noexcept { Destroy(); }
@@ -52,16 +55,14 @@ namespace Scop
bool BindPipeline(VkCommandBuffer) noexcept override { return false; };
private:
std::vector<NonOwningPtr<Texture>> m_attachments;
static inline GraphicPipeline* s_bound_pipeline = nullptr;
GraphicPipelineDescriptor m_description;
std::vector<VkFramebuffer> m_framebuffers;
std::vector<VkClearValue> m_clears;
std::shared_ptr<Shader> p_vertex_shader;
std::shared_ptr<Shader> p_fragment_shader;
VkRenderPass m_renderpass = VK_NULL_HANDLE;
VkPipeline m_pipeline = VK_NULL_HANDLE;
VkPipelineLayout m_pipeline_layout = VK_NULL_HANDLE;
NonOwningPtr<class Renderer> p_renderer;
NonOwningPtr<DepthImage> p_depth;
};
}

View File

@@ -4,16 +4,20 @@
#include <vector>
#include <cstdint>
#include <filesystem>
#include <unordered_map>
#include <kvf.h>
#include <Maths/Mat4.h>
#include <Utils/NonOwningPtr.h>
namespace Scop
{
struct ShaderSetLayout
{
std::vector<std::pair<int, VkDescriptorType> > binds;
std::unordered_map<int, VkDescriptorType> binds;
ShaderSetLayout(std::vector<std::pair<int, VkDescriptorType> > b) : binds(std::move(b)) {}
ShaderSetLayout(std::unordered_map<int, VkDescriptorType> b) : binds(std::move(b)) {}
inline bool operator==(const ShaderSetLayout& rhs) const { return binds == rhs.binds; }
};
@@ -28,10 +32,10 @@ namespace Scop
struct ShaderLayout
{
std::vector<std::pair<int, ShaderSetLayout> > set_layouts;
std::unordered_map<int, ShaderSetLayout> set_layouts;
std::vector<ShaderPushConstantLayout> push_constants;
ShaderLayout(std::vector<std::pair<int, ShaderSetLayout> > s, std::vector<ShaderPushConstantLayout> pc) : set_layouts(std::move(s)), push_constants(std::move(pc)) {}
ShaderLayout(std::unordered_map<int, ShaderSetLayout> s, std::vector<ShaderPushConstantLayout> pc) : set_layouts(std::move(s)), push_constants(std::move(pc)) {}
};
enum class ShaderType
@@ -57,6 +61,9 @@ namespace Scop
[[nodiscard]] inline const ShaderPipelineLayoutPart& GetPipelineLayout() const noexcept { return m_pipeline_layout_part; }
[[nodiscard]] inline VkShaderModule GetShaderModule() const noexcept { return m_module; }
[[nodiscard]] inline VkShaderStageFlagBits GetShaderStage() const noexcept { return m_stage; }
[[nodiscard]] inline NonOwningPtr<class GraphicPipeline> GetGraphicPipelineInUse() const noexcept { return p_pipeline_in_use; }
inline void SetPipelineInUse(NonOwningPtr<class GraphicPipeline> pipeline) noexcept { p_pipeline_in_use = pipeline; }
void Destroy();
@@ -73,10 +80,22 @@ namespace Scop
std::vector<VkDescriptorSetLayout> m_set_layouts;
VkShaderStageFlagBits m_stage;
VkShaderModule m_module = VK_NULL_HANDLE;
NonOwningPtr<class GraphicPipeline> p_pipeline_in_use = nullptr;
};
std::shared_ptr<Shader> LoadShaderFromFile(const std::filesystem::path& filepath, ShaderType type, ShaderLayout layout);
static const ShaderLayout DefaultForwardVertexShaderLayout(
{
{ 0,
ShaderSetLayout({
{ 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
{ 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER },
})
}
}, { ShaderPushConstantLayout({ 0, sizeof(Mat4f) * 2 }) }
);
static const Scop::ShaderLayout DefaultShaderLayout(
{
{ 1,

View File

@@ -33,5 +33,7 @@ namespace Scop
{
if(p_script)
p_script->OnQuit(this);
if(m_custom_pipeline.has_value() && m_custom_pipeline->data_uniform_buffer)
m_custom_pipeline->data_uniform_buffer->Destroy();
}
}

View File

@@ -165,7 +165,7 @@ namespace Scop
if(m_descriptor.post_process_shader)
{
m_post_process.set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.post_process_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
m_post_process.set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.post_process_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Fragment);
m_post_process.data_buffer = std::make_shared<UniformBuffer>();
m_post_process.data_buffer->Init(m_descriptor.post_process_data_size, m_name + "_post_process_data_buffer");
}
@@ -178,13 +178,13 @@ namespace Scop
m_forward.matrices_buffer = std::make_shared<UniformBuffer>();
m_forward.matrices_buffer->Init(sizeof(ViewerData), m_name + "_matrice_buffer");
m_forward.matrices_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(vertex_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Vertex);
m_forward.matrices_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex);
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
{
m_forward.matrices_set->SetUniformBuffer(i, 0, m_forward.matrices_buffer->Get(i));
m_forward.matrices_set->Update(i);
}
m_forward.albedo_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
m_forward.albedo_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(m_descriptor.fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment);
for(auto& child : m_scene_children)
child.Init(renderer);

View File

@@ -84,13 +84,17 @@ namespace Scop
}
std::vector<VkDescriptorSetLayoutBinding> bindings(layout.binds.size());
for(std::size_t i = 0; i < layout.binds.size(); i++)
{
bindings[i].binding = layout.binds[i].first;
bindings[i].descriptorCount = 1;
bindings[i].descriptorType = layout.binds[i].second;
bindings[i].pImmutableSamplers = nullptr;
bindings[i].stageFlags = vulkan_shader_stage;
std::size_t i = 0;
for(auto& [bind, type] : layout.binds)
{
bindings[i].binding = bind;
bindings[i].descriptorCount = 1;
bindings[i].descriptorType = type;
bindings[i].pImmutableSamplers = nullptr;
bindings[i].stageFlags = vulkan_shader_stage;
i++;
}
}
VkDescriptorSetLayout vulkan_layout = kvfCreateDescriptorSetLayout(RenderCore::Get().GetDevice(), bindings.data(), bindings.size());

View File

@@ -2,47 +2,58 @@
#include <Renderer/RenderCore.h>
#include <Renderer/Renderer.h>
#include <Renderer/Vertex.h>
#include <Graphics/Enums.h>
#include <Core/EventBus.h>
#include <Core/Logs.h>
namespace Scop
{
void GraphicPipeline::Init(const GraphicPipelineDescriptor& descriptor)
void GraphicPipeline::Init(GraphicPipelineDescriptor descriptor)
{
if(!descriptor.vertex_shader || !descriptor.fragment_shader)
FatalError("Vulkan: invalid shaders");
m_attachments = descriptor.color_attachments;
p_vertex_shader = descriptor.vertex_shader;
p_fragment_shader = descriptor.fragment_shader;
p_renderer = descriptor.renderer;
p_depth = descriptor.depth;
m_description = std::move(descriptor);
m_description.vertex_shader->SetPipelineInUse(this);
m_description.fragment_shader->SetPipelineInUse(this);
std::vector<VkPushConstantRange> push_constants;
std::vector<VkDescriptorSetLayout> set_layouts;
push_constants.insert(push_constants.end(), p_vertex_shader->GetPipelineLayout().push_constants.begin(), p_vertex_shader->GetPipelineLayout().push_constants.end());
push_constants.insert(push_constants.end(), p_fragment_shader->GetPipelineLayout().push_constants.begin(), p_fragment_shader->GetPipelineLayout().push_constants.end());
set_layouts.insert(set_layouts.end(), p_vertex_shader->GetPipelineLayout().set_layouts.begin(), p_vertex_shader->GetPipelineLayout().set_layouts.end());
set_layouts.insert(set_layouts.end(), p_fragment_shader->GetPipelineLayout().set_layouts.begin(), p_fragment_shader->GetPipelineLayout().set_layouts.end());
push_constants.insert(push_constants.end(), m_description.vertex_shader->GetPipelineLayout().push_constants.begin(), m_description.vertex_shader->GetPipelineLayout().push_constants.end());
push_constants.insert(push_constants.end(), m_description.fragment_shader->GetPipelineLayout().push_constants.begin(), m_description.fragment_shader->GetPipelineLayout().push_constants.end());
set_layouts.insert(set_layouts.end(), m_description.vertex_shader->GetPipelineLayout().set_layouts.begin(), m_description.vertex_shader->GetPipelineLayout().set_layouts.end());
set_layouts.insert(set_layouts.end(), m_description.fragment_shader->GetPipelineLayout().set_layouts.begin(), m_description.fragment_shader->GetPipelineLayout().set_layouts.end());
m_pipeline_layout = kvfCreatePipelineLayout(RenderCore::Get().GetDevice(), set_layouts.data(), set_layouts.size(), push_constants.data(), push_constants.size());
CreateFramebuffers(m_attachments, descriptor.clear_color_attachments);
CreateFramebuffers(m_description.color_attachments, m_description.clear_color_attachments);
VkPhysicalDeviceFeatures features{};
RenderCore::Get().vkGetPhysicalDeviceFeatures(RenderCore::Get().GetPhysicalDevice(), &features);
VkCullModeFlags cullmode;
switch(m_description.culling)
{
case CullMode::None: cullmode = VK_CULL_MODE_NONE; break;
case CullMode::Back: cullmode = VK_CULL_MODE_BACK_BIT; break;
case CullMode::Front: cullmode = VK_CULL_MODE_FRONT_BIT; break;
case CullMode::FrontAndBack: cullmode = VK_CULL_MODE_FRONT_AND_BACK; break;
default: break;
}
KvfGraphicsPipelineBuilder* builder = kvfCreateGPipelineBuilder();
kvfGPipelineBuilderAddShaderStage(builder, p_vertex_shader->GetShaderStage(), p_vertex_shader->GetShaderModule(), "main");
kvfGPipelineBuilderAddShaderStage(builder, p_fragment_shader->GetShaderStage(), p_fragment_shader->GetShaderModule(), "main");
kvfGPipelineBuilderAddShaderStage(builder, m_description.vertex_shader->GetShaderStage(), m_description.vertex_shader->GetShaderModule(), "main");
kvfGPipelineBuilderAddShaderStage(builder, m_description.fragment_shader->GetShaderStage(), m_description.fragment_shader->GetShaderModule(), "main");
kvfGPipelineBuilderSetInputTopology(builder, VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST);
kvfGPipelineBuilderSetCullMode(builder, descriptor.culling, VK_FRONT_FACE_CLOCKWISE);
kvfGPipelineBuilderSetCullMode(builder, cullmode, VK_FRONT_FACE_CLOCKWISE);
kvfGPipelineBuilderEnableAlphaBlending(builder);
if(p_depth)
kvfGPipelineBuilderEnableDepthTest(builder, (descriptor.depth_test_equal ? VK_COMPARE_OP_EQUAL : VK_COMPARE_OP_LESS), true);
if(m_description.depth)
kvfGPipelineBuilderEnableDepthTest(builder, (m_description.depth_test_equal ? VK_COMPARE_OP_EQUAL : VK_COMPARE_OP_LESS), true);
else
kvfGPipelineBuilderDisableDepthTest(builder);
if(features.fillModeNonSolid)
kvfGPipelineBuilderSetPolygonMode(builder, descriptor.mode, 1.0f);
if(m_description.wireframe && features.fillModeNonSolid)
kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_LINE, 1.0f);
else
kvfGPipelineBuilderSetPolygonMode(builder, VK_POLYGON_MODE_FILL, 1.0f);
if(features.sampleRateShading)
@@ -50,7 +61,7 @@ namespace Scop
else
kvfGPipelineBuilderSetMultisampling(builder, VK_SAMPLE_COUNT_1_BIT);
if(!descriptor.no_vertex_inputs)
if(!m_description.no_vertex_inputs)
{
VkVertexInputBindingDescription binding_description = Vertex::GetBindingDescription();
auto attributes_description = Vertex::GetAttributeDescriptions();
@@ -65,7 +76,7 @@ namespace Scop
name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
name_info.objectType = VK_OBJECT_TYPE_PIPELINE;
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_pipeline);
name_info.pObjectName = descriptor.name.data();
name_info.pObjectName = m_description.name.data();
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
name_info.objectType = VK_OBJECT_TYPE_RENDER_PASS;
@@ -73,10 +84,10 @@ namespace Scop
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
name_info.objectType = VK_OBJECT_TYPE_SHADER_MODULE;
name_info.objectHandle = reinterpret_cast<std::uint64_t>(p_vertex_shader->GetShaderModule());
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_description.vertex_shader->GetShaderModule());
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
name_info.objectHandle = reinterpret_cast<std::uint64_t>(p_fragment_shader->GetShaderModule());
name_info.objectHandle = reinterpret_cast<std::uint64_t>(m_description.fragment_shader->GetShaderModule());
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
name_info.objectType = VK_OBJECT_TYPE_FRAMEBUFFER;
@@ -85,7 +96,7 @@ namespace Scop
name_info.objectHandle = reinterpret_cast<std::uint64_t>(fb);
RenderCore::Get().vkSetDebugUtilsObjectNameEXT(RenderCore::Get().GetDevice(), &name_info);
}
Message("Vulkan: % graphics pipeline created", descriptor.name);
Message("Vulkan: % graphics pipeline created", m_description.name);
#else
Message("Vulkan: graphics pipeline created");
#endif
@@ -93,6 +104,13 @@ namespace Scop
bool GraphicPipeline::BindPipeline(VkCommandBuffer command_buffer, std::size_t framebuffer_index, std::array<float, 4> clear) noexcept
{
if(s_bound_pipeline != nullptr)
{
Error("Vulkan: cannot bind a graphics pipeline because another one have not been unbound");
return false;
}
s_bound_pipeline = this;
TransitionAttachments(command_buffer);
VkFramebuffer fb = m_framebuffers[framebuffer_index];
@@ -120,7 +138,7 @@ namespace Scop
m_clears[i].color.float32[3] = clear[3];
}
if(p_depth)
if(m_description.depth)
m_clears.back().depthStencil = VkClearDepthStencilValue{ 1.0f, 0 };
kvfBeginRenderPass(m_renderpass, command_buffer, fb, fb_extent, m_clears.data(), m_clears.size());
@@ -130,7 +148,10 @@ namespace Scop
void GraphicPipeline::EndPipeline(VkCommandBuffer command_buffer) noexcept
{
if(s_bound_pipeline != this)
return;
RenderCore::Get().vkCmdEndRenderPass(command_buffer);
s_bound_pipeline = nullptr;
}
void GraphicPipeline::Destroy() noexcept
@@ -151,16 +172,14 @@ namespace Scop
Message("Vulkan: renderpass destroyed");
kvfDestroyPipeline(RenderCore::Get().GetDevice(), m_pipeline);
p_vertex_shader.reset();
p_fragment_shader.reset();
m_attachments.clear();
m_description.vertex_shader.reset();
m_description.fragment_shader.reset();
m_description.color_attachments.clear();
m_framebuffers.clear();
m_clears.clear();
m_renderpass = VK_NULL_HANDLE;
m_pipeline = VK_NULL_HANDLE;
m_pipeline_layout = VK_NULL_HANDLE;
p_renderer = nullptr;
p_depth = nullptr;
Message("Vulkan: graphics pipeline destroyed");
}
@@ -170,10 +189,10 @@ namespace Scop
std::vector<VkAttachmentDescription> attachments;
std::vector<VkImageView> attachment_views;
if(p_renderer)
if(m_description.renderer)
{
attachments.push_back(kvfBuildSwapchainAttachmentDescription(p_renderer->GetSwapchain().Get(), clear_attachments));
attachment_views.push_back(p_renderer->GetSwapchain().GetSwapchainImages()[0].GetImageView());
attachments.push_back(kvfBuildSwapchainAttachmentDescription(m_description.renderer->GetSwapchain().Get(), clear_attachments));
attachment_views.push_back(m_description.renderer->GetSwapchain().GetSwapchainImages()[0].GetImageView());
}
for(NonOwningPtr<Texture> image : render_targets)
@@ -182,10 +201,10 @@ namespace Scop
attachment_views.push_back(image->GetImageView());
}
if(p_depth)
if(m_description.depth)
{
attachments.push_back(kvfBuildAttachmentDescription(KVF_IMAGE_DEPTH, p_depth->GetFormat(), p_depth->GetLayout(), p_depth->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT));
attachment_views.push_back(p_depth->GetImageView());
attachments.push_back(kvfBuildAttachmentDescription(KVF_IMAGE_DEPTH, m_description.depth->GetFormat(), m_description.depth->GetLayout(), m_description.depth->GetLayout(), clear_attachments, VK_SAMPLE_COUNT_1_BIT));
attachment_views.push_back(m_description.depth->GetImageView());
}
m_renderpass = kvfCreateRenderPass(RenderCore::Get().GetDevice(), attachments.data(), attachments.size(), GetPipelineBindPoint());
@@ -193,9 +212,9 @@ namespace Scop
m_clears.resize(attachments.size());
Message("Vulkan: renderpass created");
if(p_renderer)
if(m_description.renderer)
{
for(const Image& image : p_renderer->GetSwapchain().GetSwapchainImages())
for(const Image& image : m_description.renderer->GetSwapchain().GetSwapchainImages())
{
attachment_views[0] = image.GetImageView();
m_framebuffers.push_back(kvfCreateFramebuffer(RenderCore::Get().GetDevice(), m_renderpass, attachment_views.data(), attachment_views.size(), { .width = image.GetWidth(), .height = image.GetHeight() }));
@@ -211,10 +230,10 @@ namespace Scop
void GraphicPipeline::TransitionAttachments(VkCommandBuffer cmd)
{
if(p_depth)
p_depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd);
if(m_description.depth)
m_description.depth->TransitionLayout(VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, cmd);
for(NonOwningPtr<Texture> image : m_attachments)
for(NonOwningPtr<Texture> image : m_description.color_attachments)
image->TransitionLayout(VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, cmd);
}
}

View File

@@ -31,16 +31,18 @@ namespace Scop
void Shader::GeneratePipelineLayout(ShaderLayout layout)
{
for(auto& [n, set] : layout.set_layouts)
for(auto& [_, set] : layout.set_layouts)
{
std::vector<VkDescriptorSetLayoutBinding> bindings(set.binds.size());
for(std::size_t i = 0; i < set.binds.size(); i++)
std::size_t i = 0;
for(auto& [bind, type] : set.binds)
{
bindings[i].binding = set.binds[i].first;
bindings[i].binding = bind;
bindings[i].descriptorCount = 1;
bindings[i].descriptorType = set.binds[i].second;
bindings[i].descriptorType = type;
bindings[i].pImmutableSamplers = nullptr;
bindings[i].stageFlags = m_stage;
i++;
}
m_set_layouts.emplace_back(kvfCreateDescriptorSetLayout(RenderCore::Get().GetDevice(), bindings.data(), bindings.size()));
Message("Vulkan: descriptor set layout created");

View File

@@ -49,8 +49,8 @@ namespace Scop
};
EventBus::RegisterListener({ functor, "__ScopRender2DPass" });
p_viewer_data_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_vertex_shader->GetShaderLayout().set_layouts[0].second,ShaderType::Vertex);
p_texture_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
p_viewer_data_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex);
p_texture_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment);
p_viewer_data_buffer = std::make_shared<UniformBuffer>();
p_viewer_data_buffer->Init(sizeof(ViewerData2D));
@@ -69,10 +69,10 @@ namespace Scop
pipeline_descriptor.vertex_shader = p_vertex_shader;
pipeline_descriptor.fragment_shader = p_fragment_shader;
pipeline_descriptor.color_attachments = { &render_target };
pipeline_descriptor.culling = VK_CULL_MODE_NONE;
pipeline_descriptor.culling = CullMode::None;
pipeline_descriptor.clear_color_attachments = false;
pipeline_descriptor.name = "2D_pass_pipeline";
m_pipeline.Init(pipeline_descriptor);
m_pipeline.Init(std::move(pipeline_descriptor));
}
std::uint32_t frame_index = renderer.GetCurrentFrameIndex();

View File

@@ -31,7 +31,7 @@ namespace Scop
};
EventBus::RegisterListener({ functor, "__ScopFinalPass" });
p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Fragment);
}
void FinalPass::Pass(Scene& scene, Renderer& renderer, Texture& render_target)
@@ -42,10 +42,10 @@ namespace Scop
pipeline_descriptor.vertex_shader = p_vertex_shader;
pipeline_descriptor.fragment_shader = p_fragment_shader;
pipeline_descriptor.renderer = &renderer;
pipeline_descriptor.culling = VK_CULL_MODE_NONE;
pipeline_descriptor.culling = CullMode::None;
pipeline_descriptor.no_vertex_inputs = true;
pipeline_descriptor.name = "final_pass_pipeline";
m_pipeline.Init(pipeline_descriptor);
m_pipeline.Init(std::move(pipeline_descriptor));
}
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();

View File

@@ -17,33 +17,48 @@ namespace Scop
void ForwardPass::Pass(Scene& scene, Renderer& renderer, class Texture& render_target)
{
Scene::ForwardData& data = scene.GetForwardData();
GraphicPipeline& pipeline = scene.GetPipeline();
if(pipeline.GetPipeline() == VK_NULL_HANDLE)
NonOwningPtr<GraphicPipeline> pipeline = &scene.GetPipeline();
if(scene.GetPipeline().GetPipeline() == VK_NULL_HANDLE)
{
GraphicPipelineDescriptor pipeline_descriptor;
pipeline_descriptor.vertex_shader = RenderCore::Get().GetDefaultVertexShader();
pipeline_descriptor.fragment_shader = scene.GetFragmentShader();
pipeline_descriptor.color_attachments = { &render_target };
pipeline_descriptor.depth = &scene.GetDepth();
if(scene.GetForwardData().wireframe)
pipeline_descriptor.mode = VK_POLYGON_MODE_LINE;
pipeline_descriptor.clear_color_attachments = false;
pipeline_descriptor.name = "forward_pass_pipeline";
switch(scene.GetDescription().culling)
{
case CullMode::None: pipeline_descriptor.culling = VK_CULL_MODE_NONE; break;
case CullMode::Back: pipeline_descriptor.culling = VK_CULL_MODE_BACK_BIT; break;
case CullMode::Front: pipeline_descriptor.culling = VK_CULL_MODE_FRONT_BIT; break;
case CullMode::FrontAndBack: pipeline_descriptor.culling = VK_CULL_MODE_FRONT_AND_BACK; break;
default: break;
}
pipeline.Init(pipeline_descriptor);
scene.GetPipeline().Init(std::move(pipeline_descriptor));
}
auto setup_model = [](const Actor& actor) -> ModelData {
auto render_actor = [&render_target, &renderer, &scene, &pipeline](Actor& actor)
{
Scene::ForwardData& data = scene.GetForwardData();
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();
std::shared_ptr<GraphicPipeline> custom_pipeline = (actor.GetCustomPipeline().has_value() ? actor.GetCustomPipeline()->pipeline : nullptr);
if(custom_pipeline && !custom_pipeline->IsPipelineBound())
{
pipeline->EndPipeline(cmd);
pipeline = actor.GetCustomPipeline()->pipeline.get();
if(pipeline->GetDescription().depth != NonOwningPtr<DepthImage>{ &scene.GetDepth() })
{
GraphicPipelineDescriptor descriptor = pipeline->GetDescription();
pipeline->Destroy();
descriptor.color_attachments = { &render_target };
descriptor.depth = &scene.GetDepth();
descriptor.renderer = nullptr;
descriptor.clear_color_attachments = false;
pipeline->Init(std::move(descriptor));
}
pipeline->BindPipeline(cmd, 0, {});
}
else if(!custom_pipeline && !scene.GetPipeline().IsPipelineBound())
{
pipeline->EndPipeline(cmd);
pipeline = &scene.GetPipeline();
pipeline->BindPipeline(cmd, 0, {});
}
ModelData model_data;
model_data.model_mat = Mat4f::Identity();
model_data.model_mat.SetTranslation(actor.GetPosition() - actor.GetModel().GetCenter());
@@ -51,36 +66,54 @@ namespace Scop
model_data.model_mat = Mat4f::Translate(-actor.GetModel().GetCenter()) * Mat4f::Rotate(actor.GetOrientation()) * model_data.model_mat;
model_data.normal_mat = model_data.model_mat;
model_data.normal_mat.Inverse().Transpose();
return model_data;
RenderCore::Get().vkCmdPushConstants(cmd, pipeline->GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data);
if(custom_pipeline)
{
if(!actor.GetCustomPipeline()->data_uniform_buffer)
{
actor.GetCustomPipeline()->data_uniform_buffer = std::make_shared<UniformBuffer>();
actor.GetCustomPipeline()->data_uniform_buffer->Init(actor.GetCustomPipeline()->data.GetSize(), "custom_data_buffer");
}
else
actor.GetCustomPipeline()->data_uniform_buffer->SetData(actor.GetCustomPipeline()->data, renderer.GetCurrentFrameIndex());
if(!actor.GetCustomPipeline()->set)
{
actor.GetCustomPipeline()->set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(custom_pipeline->GetDescription().vertex_shader->GetShaderLayout().set_layouts.at(0), ShaderType::Vertex);
for(std::size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++)
{
actor.GetCustomPipeline()->set->SetUniformBuffer(i, 0, data.matrices_buffer->Get(i));
actor.GetCustomPipeline()->set->SetUniformBuffer(i, 1, actor.GetCustomPipeline()->data_uniform_buffer->Get(i));
actor.GetCustomPipeline()->set->Update(i);
}
}
actor.GetModel().Draw(cmd, actor.GetCustomPipeline()->set, *pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex());
}
else
actor.GetModel().Draw(cmd, data.matrices_set, *pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex());
};
std::multimap<float, Actor&> sorted_actors;
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();
pipeline.BindPipeline(cmd, 0, {});
for(auto& [_, actor] : scene.GetActors())
{
if(!actor.IsVisible())
continue;
if(actor.IsOpaque())
{
auto model_data = setup_model(actor);
RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data);
actor.GetModel().Draw(cmd, data.matrices_set, pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex());
}
else
if(!actor.IsOpaque())
{
float distance = Vec3f::Distance(actor.GetPosition(), scene.GetCamera()->GetPosition());
sorted_actors.emplace(distance, const_cast<Actor&>(actor));
}
else
render_actor(const_cast<Actor&>(actor));
}
for(auto it = sorted_actors.rbegin(); it != sorted_actors.rend(); ++it)
{
if(!it->second.IsVisible())
continue;
auto model_data = setup_model(it->second);
RenderCore::Get().vkCmdPushConstants(cmd, pipeline.GetPipelineLayout(), VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(ModelData), &model_data);
it->second.GetModel().Draw(cmd, data.matrices_set, pipeline, data.albedo_set, renderer.GetDrawCallsCounterRef(), renderer.GetPolygonDrawnCounterRef(), renderer.GetCurrentFrameIndex());
render_actor(it->second);
}
pipeline.EndPipeline(cmd);
if(pipeline)
pipeline->EndPipeline(renderer.GetActiveCommandBuffer());
}
}

View File

@@ -41,11 +41,11 @@ namespace Scop
pipeline_descriptor.vertex_shader = p_vertex_shader;
pipeline_descriptor.fragment_shader = scene.GetDescription().post_process_shader;
pipeline_descriptor.color_attachments = { &m_render_texture };
pipeline_descriptor.culling = VK_CULL_MODE_NONE;
pipeline_descriptor.culling = CullMode::None;
pipeline_descriptor.clear_color_attachments = false;
pipeline_descriptor.no_vertex_inputs = true;
pipeline_descriptor.name = "post_process_pass_pipeline";
m_pipeline.Init(pipeline_descriptor);
m_pipeline.Init(std::move(pipeline_descriptor));
}
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();

View File

@@ -40,7 +40,7 @@ namespace Scop
EventBus::RegisterListener({ functor, "__ScopSkyboxPass" });
m_cube = CreateCube();
p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts[0].second, ShaderType::Fragment);
p_set = RenderCore::Get().GetDescriptorPoolManager().GetAvailablePool().RequestDescriptorSet(p_fragment_shader->GetShaderLayout().set_layouts.at(1), ShaderType::Fragment);
}
void SkyboxPass::Pass(Scene& scene, Renderer& renderer, class Texture& render_target)
@@ -55,11 +55,11 @@ namespace Scop
pipeline_descriptor.fragment_shader = p_fragment_shader;
pipeline_descriptor.color_attachments = { &render_target };
pipeline_descriptor.depth = &scene.GetDepth();
pipeline_descriptor.culling = VK_CULL_MODE_NONE;
pipeline_descriptor.culling = CullMode::None;
pipeline_descriptor.depth_test_equal = true;
pipeline_descriptor.clear_color_attachments = false;
pipeline_descriptor.name = "skybox_pass_pipeline";
m_pipeline.Init(pipeline_descriptor);
m_pipeline.Init(std::move(pipeline_descriptor));
}
VkCommandBuffer cmd = renderer.GetActiveCommandBuffer();