diff --git a/Assets/Scenes/Scene2.shade b/Assets/Scenes/Scene2.shade index 6e794990..4f925833 100644 --- a/Assets/Scenes/Scene2.shade +++ b/Assets/Scenes/Scene2.shade @@ -172,10 +172,12 @@ Rotation Speed: 0.0309999995 Rotation Decay: 0.0199999996 Texture Asset ID: 0 + Custom Vertex Shader Asset ID: 44202416 + Custom Fragment Shader Asset ID: 42315398 Custom Update Shader Asset ID: 0 - Color Tint: {x: 0, y: 1, z: 0.56387639, w: 1} - Color Tint Range: {x: 0.5, y: 0.5, z: 0.5, w: 0} - Color Decay: {x: 0, y: 0, z: 0, w: 0} + Color Tint: {x: 0.46696043, y: 1, z: 0, w: 1} + Color Tint Range: {x: 1, y: 0, z: 0, w: 0} + Color Decay: {x: -1, y: -1, z: -1, w: 0} Acceleration: {x: 0, y: 0, z: 0} IsActive: true Scripts: ~ \ No newline at end of file diff --git a/Assets/Shaders/ParticleRounded_FS.glsl b/Assets/Shaders/ParticleRounded_FS.glsl new file mode 100644 index 00000000..6de4dc8b --- /dev/null +++ b/Assets/Shaders/ParticleRounded_FS.glsl @@ -0,0 +1,27 @@ +#version 460 core +#extension GL_EXT_nonuniform_qualifier : require + +layout (location = 0) out vec4 fragColor; + +layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global) + +// between shader stages +layout(location = 0) in struct +{ + vec2 uv; // location = 0 +} In; + +// material stuff +layout(location = 1) flat in struct +{ + uint textureIndex; + vec4 color; +} InFlat; + +void main () +{ + fragColor = vec4 (texture(textures [nonuniformEXT(InFlat.textureIndex)], In.uv)) * InFlat.color; + + if (fragColor.a < 0.01f) + discard; +} diff --git a/Assets/Shaders/ParticleRounded_FS.shshaderb b/Assets/Shaders/ParticleRounded_FS.shshaderb new file mode 100644 index 00000000..59049d0c Binary files /dev/null and b/Assets/Shaders/ParticleRounded_FS.shshaderb differ diff --git a/Assets/Shaders/ParticleRounded_FS.shshaderb.shmeta b/Assets/Shaders/ParticleRounded_FS.shshaderb.shmeta new file mode 100644 index 00000000..b5720806 --- /dev/null +++ b/Assets/Shaders/ParticleRounded_FS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: ParticleRounded_FS +ID: 42315398 +Type: 2 diff --git a/Assets/Shaders/ParticleRounded_VS.glsl b/Assets/Shaders/ParticleRounded_VS.glsl new file mode 100644 index 00000000..414648e7 --- /dev/null +++ b/Assets/Shaders/ParticleRounded_VS.glsl @@ -0,0 +1,107 @@ +#version 460 core + +struct GenericData +{ + //! Delta time + float dt; + + //! Elapsed time of the application + float elapsedTime; + + //! Viewport width of the scene (excluding imgui, that means smaller than window) + uint viewportWidth; + + //! Ditto but for height + uint viewportHeight; +}; + +struct ParticleData +{ + vec4 position; + vec4 orientationSpeedDecay; + vec4 velocity; + vec4 acceleration; + vec4 scaleAndDecay; + vec4 colorTint; + vec4 colorDecay; + float life; + uint textureIndex; +}; + +layout (set = 0, binding = 0) uniform GenericDataBuffer +{ + GenericData data; +} genericDataBuffer; + + +layout(set = 1, binding = 0) uniform CameraData +{ + vec4 position; + mat4 vpMat; + mat4 viewMat; + mat4 projMat; +} cameraData; + +// output buffer not needed +layout (std430, set = 2, binding = 2) coherent restrict buffer ParticlesOutputBuffer +{ + ParticleData data[]; +} outputParticles; + +layout (std430, set = 2, binding = 4) coherent restrict buffer IndicesData +{ + uint indices[]; +}; + +// between shader stages +layout(location = 0) out struct +{ + vec2 uv; // location = 0 +} Out; + +// material stuff +layout(location = 1) out struct +{ + uint textureIndex; // location = 1 + vec4 color; // location = 2 +} OutFlat; + +vec2 CreateQuad (in uint vertexID) +{ + uint b = 1 << vertexID; + return vec2 ((0x3 & b) != 0, (0x9 & b) != 0); +} + +void main() +{ + // Create a quad and its texture coordinates + Out.uv = CreateQuad (gl_VertexIndex); + vec3 vertexPos = vec3 (Out.uv - vec2(0.5f), 0.0f); + vertexPos.y *= 0.5f; + + ParticleData particle = outputParticles.data[indices[gl_InstanceIndex]]; + + vec3 normalized = normalize (vec3 (particle.velocity.xyz)); + float pitch = acos (dot (normalized.xyz, normalize (vec3 (normalized.x, 0.0f, normalized.z)))); + + float angle = pitch; + // float angle = atan (normalized.y, normalized.x); + vec2 particleScaleData = particle.scaleAndDecay.xy; // x and y + + mat3 rotate = mat3 (1.0f); + rotate[0][0] = cos(angle); + rotate[0][1] = sin(angle); + rotate[1][0] = -sin(angle); + rotate[1][1] = cos(angle); + + vec3 particlePos = rotate * vertexPos; + + vec3 viewRight = normalize (vec3 (cameraData.viewMat[0][0], cameraData.viewMat[1][0], cameraData.viewMat[2][0])); + vec3 viewUp = normalize(vec3 (cameraData.viewMat[0][1], cameraData.viewMat[1][1], cameraData.viewMat[2][1])); + + particlePos = particle.position.xyz + (viewRight * particlePos.x * particleScaleData.x) + (viewUp * particlePos.y * particleScaleData.y); + OutFlat.textureIndex = particle.textureIndex; + OutFlat.color = particle.colorTint; + + gl_Position = cameraData.vpMat * vec4(particlePos, 1.0f); +} \ No newline at end of file diff --git a/Assets/Shaders/ParticleRounded_VS.shshaderb b/Assets/Shaders/ParticleRounded_VS.shshaderb new file mode 100644 index 00000000..0b2d07da Binary files /dev/null and b/Assets/Shaders/ParticleRounded_VS.shshaderb differ diff --git a/Assets/Shaders/ParticleRounded_VS.shshaderb.shmeta b/Assets/Shaders/ParticleRounded_VS.shshaderb.shmeta new file mode 100644 index 00000000..68577bd3 --- /dev/null +++ b/Assets/Shaders/ParticleRounded_VS.shshaderb.shmeta @@ -0,0 +1,3 @@ +Name: ParticleRounded_VS +ID: 44202416 +Type: 2 diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 2858b2af..7bb5c552 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -1004,6 +1004,88 @@ namespace SHADE } + SHEditorWidgets::InputText("Custom Vertex Shader", + [comp = component]() + { + auto customShader = comp->GetCustomVertexShader(); + + if (customShader) + return customShader->GetName(); + else + return std::string{}; + + }, + [comp = component](std::string const& text) + { + }, {}, ImGuiSliderFlags_ReadOnly); + + if (SHDragDrop::BeginTarget()) + { + if (AssetID* payload = SHDragDrop::AcceptPayload(SHDragDrop::DRAG_RESOURCE)) + { + Handle shaderModule = SHResourceManager::LoadOrGet(*payload); + + if (shaderModule) + { + component->SetCustomVertexShader(shaderModule); + component->SetCustomVertexShaderAssetID(*payload); + } + else + { + SHLOG_WARNING("[] Attempted to load invalid shader! Custom vertex shader for particles not set. "); + } + + SHDragDrop::EndTarget(); + } + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) + { + component->SetCustomVertexShader({}); + component->SetCustomVertexShaderAssetID(INVALID_ASSET_ID); + } + + + SHEditorWidgets::InputText("Custom Fragment Shader", + [comp = component]() + { + auto customShader = comp->GetCustomFragmentShader(); + + if (customShader) + return customShader->GetName(); + else + return std::string{}; + + }, + [comp = component](std::string const& text) + { + }, {}, ImGuiSliderFlags_ReadOnly); + + if (SHDragDrop::BeginTarget()) + { + if (AssetID* payload = SHDragDrop::AcceptPayload(SHDragDrop::DRAG_RESOURCE)) + { + Handle shaderModule = SHResourceManager::LoadOrGet(*payload); + + if (shaderModule) + { + component->SetCustomFragmentShader(shaderModule); + component->SetCustomFragmentShaderAssetID(*payload); + } + else + { + SHLOG_WARNING("[] Attempted to load invalid shader! Custom fragment shader for particles not set. "); + } + + SHDragDrop::EndTarget(); + } + } + ImGui::SameLine(); + if (ImGui::Button("Reset")) + { + component->SetCustomFragmentShader({}); + component->SetCustomFragmentShaderAssetID(INVALID_ASSET_ID); + } SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); }); diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp index f7ccc2ed..392e18a5 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.cpp @@ -124,6 +124,16 @@ namespace SHADE customUpdateShaderID = id; } + void SHParticleEmitterComponent::SetCustomVertexShaderAssetID(AssetID id) noexcept + { + customVertexShaderID = id; + } + + void SHParticleEmitterComponent::SetCustomFragmentShaderAssetID(AssetID id) noexcept + { + customFragmentShaderID = id; + } + void SHParticleEmitterComponent::SetMinSize(float size) noexcept { cpuEmitterData.lifeAndSizeRange.z = size; @@ -139,6 +149,16 @@ namespace SHADE cpuEmitterData.sizeDecayMult = decay; } + void SHParticleEmitterComponent::SetCustomVertexShader(Handle shaderModule) noexcept + { + customVertexShader = shaderModule; + } + + void SHParticleEmitterComponent::SetCustomFragmentShader(Handle shaderModule) noexcept + { + customFragmentShader = shaderModule; + } + void SHParticleEmitterComponent::SetCustomUpdateShader(Handle shaderModule) noexcept { customUpdateShader = shaderModule; @@ -276,6 +296,16 @@ namespace SHADE return customUpdateShaderID; } + AssetID SHParticleEmitterComponent::GetCustomVertexShaderAssetID(void) const noexcept + { + return customVertexShaderID; + } + + AssetID SHParticleEmitterComponent::GetCustomFragmentShaderAssetID(void) const noexcept + { + return customFragmentShaderID; + } + float SHParticleEmitterComponent::GetMinSize(void) const noexcept { return cpuEmitterData.lifeAndSizeRange.z; @@ -297,6 +327,16 @@ namespace SHADE return customUpdateShader; } + Handle SHParticleEmitterComponent::GetCustomVertexShader(void) const noexcept + { + return customVertexShader; + } + + Handle SHParticleEmitterComponent::GetCustomFragmentShader(void) const noexcept + { + return customFragmentShader; + } + SHVec4 const& SHParticleEmitterComponent::GetColorTint(void) const noexcept { return cpuEmitterData.colorTint; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h index f43ebefb..d32ac2fc 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleEmitterComponent.h @@ -115,7 +115,7 @@ namespace SHADE Handle particleData; //! Freelist data - Handle freelistData; + Handle freelistData; //! Indices data Handle indicesData; @@ -133,6 +133,16 @@ namespace SHADE //! Internally the system will bind this pipeline when it detects that this is not a null handle Handle customUpdatePipeline; + //! Custom vertex shader + Handle customVertexShader; + + //! Custom fragment shader + Handle customFragmentShader; + + //! Custom graphics pipeline for drawing particles (created + //! from the VS and FS above). + Handle customGraphicsPipeline; + //! Emitter's data on the CPU side. To be copied to GPU. GPUEmitterStruct cpuEmitterData; @@ -154,6 +164,12 @@ namespace SHADE //! Custom update shaders, similarly with textures, will be identified through their AssetID AssetID customUpdateShaderID; + //! Custom vertex shaders, similarly with textures, will be identified through their AssetID + AssetID customVertexShaderID; + + //! Custom fragment shaders, similarly with textures, will be identified through their AssetID + AssetID customFragmentShaderID; + public: void OnCreate(void) override final; void OnDestroy(void) override final; @@ -177,6 +193,8 @@ namespace SHADE void SetMinSize (float size) noexcept; void SetMaxSize (float size) noexcept; void SetSizeDecayMult (float decay) noexcept; + void SetCustomVertexShader (Handle shaderModule) noexcept; + void SetCustomFragmentShader (Handle shaderModule) noexcept; void SetCustomUpdateShader (Handle shaderModule) noexcept; void SetColorTint (SHVec4 tint) noexcept; void SetColorTintRGB (SHVec3 tint) noexcept; @@ -189,42 +207,49 @@ namespace SHADE void SetColorDecayRGB (SHVec3 const& decay) noexcept; void SetColorDecayAlpha (float alpha) noexcept; - uint32_t GetEmissionCount (void) const noexcept; - bool GetPassive (void) const noexcept; - float GetEmissionInterval (void) const noexcept; - float GetMinLife (void) const noexcept; - float GetMaxLife (void) const noexcept; - SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept; - SHVec2 GetAngularRanges (void) const noexcept; - SHVec2 GetAngularOffsets (void) const noexcept; - SHVec3 GetAcceleration (void) const noexcept; - float GetMinSpeed (void) const noexcept; - float GetMaxSpeed (void) const noexcept; - float GetRotationSpeed (void) const noexcept; - float GetRotationDecay (void) const noexcept; - uint32_t GetTextureIndex (void) const noexcept; - float GetMinSize (void) const noexcept; - float GetMaxSize (void) const noexcept; - float GetSizeDecayMult (void) const noexcept; - Handle GetCustomUpdateShader (void) const noexcept; - SHVec4 const& GetColorTint (void) const noexcept; - SHVec3 GetColorTintRGB (void) const noexcept; - float GetColorTintAlpha (void) const noexcept; - SHVec4 const& GetColorTintRange (void) const noexcept; - SHVec3 GetColorTintRangeRGB (void) const noexcept; - float GetColorTintRangeAlpha (void) const noexcept; - SHVec4 const& GetColorDecay (void) const noexcept; - SHVec3 GetColorDecayRGB (void) const noexcept; - float GetColorDecayAlpha (void) const noexcept; + uint32_t GetEmissionCount (void) const noexcept; + bool GetPassive (void) const noexcept; + float GetEmissionInterval (void) const noexcept; + float GetMinLife (void) const noexcept; + float GetMaxLife (void) const noexcept; + SHVec4 const& GetAngularRangesAndOffsets (void) const noexcept; + SHVec2 GetAngularRanges (void) const noexcept; + SHVec2 GetAngularOffsets (void) const noexcept; + SHVec3 GetAcceleration (void) const noexcept; + float GetMinSpeed (void) const noexcept; + float GetMaxSpeed (void) const noexcept; + float GetRotationSpeed (void) const noexcept; + float GetRotationDecay (void) const noexcept; + uint32_t GetTextureIndex (void) const noexcept; + float GetMinSize (void) const noexcept; + float GetMaxSize (void) const noexcept; + float GetSizeDecayMult (void) const noexcept; + Handle GetCustomUpdateShader (void) const noexcept; + Handle GetCustomVertexShader (void) const noexcept; + Handle GetCustomFragmentShader (void) const noexcept; + SHVec4 const& GetColorTint (void) const noexcept; + SHVec3 GetColorTintRGB (void) const noexcept; + float GetColorTintAlpha (void) const noexcept; + SHVec4 const& GetColorTintRange (void) const noexcept; + SHVec3 GetColorTintRangeRGB (void) const noexcept; + float GetColorTintRangeAlpha (void) const noexcept; + SHVec4 const& GetColorDecay (void) const noexcept; + SHVec3 GetColorDecayRGB (void) const noexcept; + float GetColorDecayAlpha (void) const noexcept; /*-----------------------------------------------------------------------*/ /* NON-INTERFACE FUNCTIONS */ /*-----------------------------------------------------------------------*/ void SetTextureAssetID(AssetID id) noexcept; void SetCustomUpdateShaderAssetID(AssetID id) noexcept; + void SetCustomVertexShaderAssetID(AssetID id) noexcept; + void SetCustomFragmentShaderAssetID (AssetID id) noexcept; AssetID GetTextureAssetID(void) const noexcept; AssetID GetCustomUpdateShaderAssetID(void) const noexcept; + AssetID GetCustomVertexShaderAssetID(void) const noexcept; + AssetID GetCustomFragmentShaderAssetID(void) const noexcept; + friend class SHParticleSubSystem; diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp index d99832a5..92405264 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.cpp @@ -268,10 +268,73 @@ namespace SHADE return customUpdatePipelineCache.at (customUpdateShader).customPipeline; } - void SHParticleSubSystem::Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept + Handle SHParticleSubSystem::GetCustomGraphicsPipeline(Handle customVS, Handle customFS) noexcept + { + if (!customVS || !customFS) + return {}; + + if (!customGraphicsPipelineCache.contains(std::make_pair(customVS, customFS))) + { + SHPipelineLayoutParams plParams + { + .shaderModules = {customVS, customFS}, + .predefinedDescSetLayouts = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING).descSetLayouts + }; + + auto pipelineLayout = logicalDevice->CreatePipelineLayout(plParams); + auto newPipeline = logicalDevice->CreateGraphicsPipeline(pipelineLayout, nullptr, renderpass, subpass); + + SHColorBlendState colorBlendState{}; + colorBlendState.logic_op_enable = VK_FALSE; + colorBlendState.logic_op = vk::LogicOp::eCopy; + + auto const& subpassColorReferences = subpass->GetColorAttachmentReferences(); + colorBlendState.attachments.reserve(subpassColorReferences.size()); + + + for (auto& att : subpassColorReferences) + { + colorBlendState.attachments.push_back(vk::PipelineColorBlendAttachmentState + { + .blendEnable = SHVkUtil::IsBlendCompatible(subpass->GetFormatFromAttachmentReference(att.attachment)), + .srcColorBlendFactor = vk::BlendFactor::eSrcAlpha, + .dstColorBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, + .colorBlendOp = vk::BlendOp::eAdd, + .srcAlphaBlendFactor = vk::BlendFactor::eSrcAlpha, + .dstAlphaBlendFactor = vk::BlendFactor::eOneMinusSrcAlpha, + .alphaBlendOp = vk::BlendOp::eAdd, + .colorWriteMask = vk::ColorComponentFlagBits::eR | vk::ColorComponentFlagBits::eG | vk::ColorComponentFlagBits::eB | vk::ColorComponentFlagBits::eA, + } + ); + } + + newPipeline->GetPipelineState().SetColorBlenState(colorBlendState); + + // Sets the input assembly state for rendering particles + SHInputAssemblyState inputAssemblyState{}; + inputAssemblyState.topology = vk::PrimitiveTopology::eTriangleFan; + newPipeline->GetPipelineState().SetInputAssemblyState(inputAssemblyState); + + newPipeline->ConstructPipeline(); + + if (!newPipeline) + return {}; + + auto customUpdateShaderData = CustomPipeline{ newPipeline, pipelineLayout }; + + customGraphicsPipelineCache.emplace(std::make_pair(customVS, customFS), customUpdateShaderData); + } + + return customGraphicsPipelineCache.at(std::make_pair(customVS, customFS)).customPipeline; + + } + + void SHParticleSubSystem::Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle compatibleSubpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept { descPool = inDescPool; logicalDevice = device; + renderpass = compatibleRenderpass; + subpass = compatibleSubpass; /*-----------------------------------------------------------------------*/ /* INITIALIZE ALL PIPELINES */ @@ -499,12 +562,22 @@ namespace SHADE auto& emitters = SHComponentManager::GetDense(); auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING); - // bind the pipeline for updating - cmdBuffer->BindPipeline(renderingPipelineData.pipeline); - // TODO: Issue barrier for output particle data. Semaphore should also be issued outside in SHGraphicsSystem for (auto& emitter : emitters) { + if (emitter.customVertexShader && emitter.customFragmentShader) + { + if (!emitter.customGraphicsPipeline) + emitter.customGraphicsPipeline = GetCustomGraphicsPipeline(emitter.customVertexShader, emitter.customFragmentShader); + + cmdBuffer->BindPipeline(emitter.customGraphicsPipeline); + } + else + { + // bind the pipeline for updating + cmdBuffer->BindPipeline(renderingPipelineData.pipeline); + } + if (emitter.isActive) { // bind the descriptor sets required for emitting particles diff --git a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h index a0675da6..2288a5bb 100644 --- a/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h +++ b/SHADE_Engine/src/Graphics/MiddleEnd/Particles/SHParticleSubSystem.h @@ -82,7 +82,14 @@ namespace SHADE //! Desc pool for particle component desc set allocation Handle descPool; + //! Renderpass the system draws its particles in + Handle renderpass; + + //! Subpass the system draws its particles in + Handle subpass; + std::unordered_map, CustomPipeline> customUpdatePipelineCache; + std::unordered_map, Handle>, CustomPipeline> customGraphicsPipelineCache; void InitializeComponent (SHParticleEmitterComponent& comp) noexcept; @@ -92,10 +99,11 @@ namespace SHADE void PreparePrePostUpdateBarriers (std::vector& preUpdateBarriers, std::vector& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept; - Handle GetCustomUpdatePipeline (Handle customUpdateShader) noexcept; + Handle GetCustomUpdatePipeline(Handle customUpdateShader) noexcept; + Handle GetCustomGraphicsPipeline(Handle customVS, Handle customFS) noexcept; public: - void Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle subpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept; + void Init(Handle device, Handle inDescPool, Handle compatibleRenderpass, Handle compatibleSubpass, Handle VS, Handle FS, Handle emitCS, Handle defaultUpdateCS) noexcept; void Run(Handle cmdBuffer, uint32_t frameIndex, Handle waitFence = {}) noexcept; void ResetInstanceCounts (Handle cmdBuffer, uint32_t frameIndex) noexcept; diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index a1c185aa..0df15b5b 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -518,6 +518,8 @@ namespace YAML static constexpr std::string_view ROTATION_SPEED_TAG = "Rotation Speed"; static constexpr std::string_view ROTATION_DECAY_TAG = "Rotation Decay"; static constexpr std::string_view TEXTURE_ASSET_ID_TAG = "Texture Asset ID"; + static constexpr std::string_view CUSTOM_VERTEX_SHADER_ASSET_ID_TAG = "Custom Vertex Shader Asset ID"; + static constexpr std::string_view CUSTOM_FRAGMENT_SHADER_ASSET_ID_TAG = "Custom Fragment Shader Asset ID"; static constexpr std::string_view CUSTOM_UPDATE_SHADER_ASSET_ID_TAG = "Custom Update Shader Asset ID"; static constexpr std::string_view COLOR_TINT_TAG = "Color Tint"; static constexpr std::string_view COLOR_TINT_RANGE_TAG = "Color Tint Range"; @@ -541,6 +543,8 @@ namespace YAML node[ROTATION_SPEED_TAG.data()] = rhs.GetRotationSpeed(); node[ROTATION_DECAY_TAG.data()] = rhs.GetRotationDecay(); node[TEXTURE_ASSET_ID_TAG.data()] = rhs.GetTextureAssetID(); + node[CUSTOM_VERTEX_SHADER_ASSET_ID_TAG.data()] = rhs.GetCustomVertexShaderAssetID(); + node[CUSTOM_FRAGMENT_SHADER_ASSET_ID_TAG.data()] = rhs.GetCustomFragmentShaderAssetID(); node[CUSTOM_UPDATE_SHADER_ASSET_ID_TAG.data()] = rhs.GetCustomUpdateShaderAssetID(); node[COLOR_TINT_TAG.data()] = rhs.GetColorTint(); node[COLOR_TINT_RANGE_TAG.data()] = rhs.GetColorTintRange(); @@ -634,6 +638,31 @@ namespace YAML rhs.SetCustomUpdateShader(shaderModule); rhs.SetCustomUpdateShaderAssetID(id); } + + if (node[CUSTOM_VERTEX_SHADER_ASSET_ID_TAG.data()].IsDefined()) + { + AssetID id = node[CUSTOM_VERTEX_SHADER_ASSET_ID_TAG.data()].as(); + + Handle shaderModule = SHResourceManager::LoadOrGet(id); + SHResourceManager::FinaliseChanges(); + //gfxSystem->BuildTextures(); + + rhs.SetCustomVertexShader(shaderModule); + rhs.SetCustomVertexShaderAssetID(id); + } + + if (node[CUSTOM_FRAGMENT_SHADER_ASSET_ID_TAG.data()].IsDefined()) + { + AssetID id = node[CUSTOM_FRAGMENT_SHADER_ASSET_ID_TAG.data()].as(); + + Handle shaderModule = SHResourceManager::LoadOrGet(id); + SHResourceManager::FinaliseChanges(); + //gfxSystem->BuildTextures(); + + rhs.SetCustomFragmentShader(shaderModule); + rhs.SetCustomFragmentShaderAssetID(id); + } + return true; }