Implemented color decay, color range emission and custom VS and FS for particles #447

Merged
Xenosas1337 merged 4 commits from SP3-1-Rendering into main 2023-03-30 19:37:33 +08:00
13 changed files with 436 additions and 37 deletions
Showing only changes of commit 4d145bbc43 - Show all commits

View File

@ -172,10 +172,12 @@
Rotation Speed: 0.0309999995 Rotation Speed: 0.0309999995
Rotation Decay: 0.0199999996 Rotation Decay: 0.0199999996
Texture Asset ID: 0 Texture Asset ID: 0
Custom Vertex Shader Asset ID: 44202416
Custom Fragment Shader Asset ID: 42315398
Custom Update Shader Asset ID: 0 Custom Update Shader Asset ID: 0
Color Tint: {x: 0, y: 1, z: 0.56387639, w: 1} Color Tint: {x: 0.46696043, y: 1, z: 0, w: 1}
Color Tint Range: {x: 0.5, y: 0.5, z: 0.5, w: 0} Color Tint Range: {x: 1, y: 0, z: 0, w: 0}
Color Decay: {x: 0, y: 0, z: 0, w: 0} Color Decay: {x: -1, y: -1, z: -1, w: 0}
Acceleration: {x: 0, y: 0, z: 0} Acceleration: {x: 0, y: 0, z: 0}
IsActive: true IsActive: true
Scripts: ~ Scripts: ~

View File

@ -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;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ParticleRounded_FS
ID: 42315398
Type: 2

View File

@ -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);
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: ParticleRounded_VS
ID: 44202416
Type: 2

View File

@ -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<AssetID>(SHDragDrop::DRAG_RESOURCE))
{
Handle<SHVkShaderModule> shaderModule = SHResourceManager::LoadOrGet<SHVkShaderModule>(*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<AssetID>(SHDragDrop::DRAG_RESOURCE))
{
Handle<SHVkShaderModule> shaderModule = SHResourceManager::LoadOrGet<SHVkShaderModule>(*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); }); SHEditorWidgets::CheckBox("Is Passive", [comp = component]() {return comp->GetPassive(); }, [comp = component](bool flag) {comp->SetPassive(flag); });

View File

@ -124,6 +124,16 @@ namespace SHADE
customUpdateShaderID = id; customUpdateShaderID = id;
} }
void SHParticleEmitterComponent::SetCustomVertexShaderAssetID(AssetID id) noexcept
{
customVertexShaderID = id;
}
void SHParticleEmitterComponent::SetCustomFragmentShaderAssetID(AssetID id) noexcept
{
customFragmentShaderID = id;
}
void SHParticleEmitterComponent::SetMinSize(float size) noexcept void SHParticleEmitterComponent::SetMinSize(float size) noexcept
{ {
cpuEmitterData.lifeAndSizeRange.z = size; cpuEmitterData.lifeAndSizeRange.z = size;
@ -139,6 +149,16 @@ namespace SHADE
cpuEmitterData.sizeDecayMult = decay; cpuEmitterData.sizeDecayMult = decay;
} }
void SHParticleEmitterComponent::SetCustomVertexShader(Handle<SHVkShaderModule> shaderModule) noexcept
{
customVertexShader = shaderModule;
}
void SHParticleEmitterComponent::SetCustomFragmentShader(Handle<SHVkShaderModule> shaderModule) noexcept
{
customFragmentShader = shaderModule;
}
void SHParticleEmitterComponent::SetCustomUpdateShader(Handle<SHVkShaderModule> shaderModule) noexcept void SHParticleEmitterComponent::SetCustomUpdateShader(Handle<SHVkShaderModule> shaderModule) noexcept
{ {
customUpdateShader = shaderModule; customUpdateShader = shaderModule;
@ -276,6 +296,16 @@ namespace SHADE
return customUpdateShaderID; return customUpdateShaderID;
} }
AssetID SHParticleEmitterComponent::GetCustomVertexShaderAssetID(void) const noexcept
{
return customVertexShaderID;
}
AssetID SHParticleEmitterComponent::GetCustomFragmentShaderAssetID(void) const noexcept
{
return customFragmentShaderID;
}
float SHParticleEmitterComponent::GetMinSize(void) const noexcept float SHParticleEmitterComponent::GetMinSize(void) const noexcept
{ {
return cpuEmitterData.lifeAndSizeRange.z; return cpuEmitterData.lifeAndSizeRange.z;
@ -297,6 +327,16 @@ namespace SHADE
return customUpdateShader; return customUpdateShader;
} }
Handle<SHVkShaderModule> SHParticleEmitterComponent::GetCustomVertexShader(void) const noexcept
{
return customVertexShader;
}
Handle<SHVkShaderModule> SHParticleEmitterComponent::GetCustomFragmentShader(void) const noexcept
{
return customFragmentShader;
}
SHVec4 const& SHParticleEmitterComponent::GetColorTint(void) const noexcept SHVec4 const& SHParticleEmitterComponent::GetColorTint(void) const noexcept
{ {
return cpuEmitterData.colorTint; return cpuEmitterData.colorTint;

View File

@ -133,6 +133,16 @@ namespace SHADE
//! Internally the system will bind this pipeline when it detects that this is not a null handle //! Internally the system will bind this pipeline when it detects that this is not a null handle
Handle<SHVkPipeline> customUpdatePipeline; Handle<SHVkPipeline> customUpdatePipeline;
//! Custom vertex shader
Handle<SHVkShaderModule> customVertexShader;
//! Custom fragment shader
Handle<SHVkShaderModule> customFragmentShader;
//! Custom graphics pipeline for drawing particles (created
//! from the VS and FS above).
Handle<SHVkPipeline> customGraphicsPipeline;
//! Emitter's data on the CPU side. To be copied to GPU. //! Emitter's data on the CPU side. To be copied to GPU.
GPUEmitterStruct cpuEmitterData; GPUEmitterStruct cpuEmitterData;
@ -154,6 +164,12 @@ namespace SHADE
//! Custom update shaders, similarly with textures, will be identified through their AssetID //! Custom update shaders, similarly with textures, will be identified through their AssetID
AssetID customUpdateShaderID; 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: public:
void OnCreate(void) override final; void OnCreate(void) override final;
void OnDestroy(void) override final; void OnDestroy(void) override final;
@ -177,6 +193,8 @@ namespace SHADE
void SetMinSize (float size) noexcept; void SetMinSize (float size) noexcept;
void SetMaxSize (float size) noexcept; void SetMaxSize (float size) noexcept;
void SetSizeDecayMult (float decay) noexcept; void SetSizeDecayMult (float decay) noexcept;
void SetCustomVertexShader (Handle<SHVkShaderModule> shaderModule) noexcept;
void SetCustomFragmentShader (Handle<SHVkShaderModule> shaderModule) noexcept;
void SetCustomUpdateShader (Handle<SHVkShaderModule> shaderModule) noexcept; void SetCustomUpdateShader (Handle<SHVkShaderModule> shaderModule) noexcept;
void SetColorTint (SHVec4 tint) noexcept; void SetColorTint (SHVec4 tint) noexcept;
void SetColorTintRGB (SHVec3 tint) noexcept; void SetColorTintRGB (SHVec3 tint) noexcept;
@ -207,6 +225,8 @@ namespace SHADE
float GetMaxSize (void) const noexcept; float GetMaxSize (void) const noexcept;
float GetSizeDecayMult (void) const noexcept; float GetSizeDecayMult (void) const noexcept;
Handle<SHVkShaderModule> GetCustomUpdateShader (void) const noexcept; Handle<SHVkShaderModule> GetCustomUpdateShader (void) const noexcept;
Handle<SHVkShaderModule> GetCustomVertexShader (void) const noexcept;
Handle<SHVkShaderModule> GetCustomFragmentShader (void) const noexcept;
SHVec4 const& GetColorTint (void) const noexcept; SHVec4 const& GetColorTint (void) const noexcept;
SHVec3 GetColorTintRGB (void) const noexcept; SHVec3 GetColorTintRGB (void) const noexcept;
float GetColorTintAlpha (void) const noexcept; float GetColorTintAlpha (void) const noexcept;
@ -222,9 +242,14 @@ namespace SHADE
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
void SetTextureAssetID(AssetID id) noexcept; void SetTextureAssetID(AssetID id) noexcept;
void SetCustomUpdateShaderAssetID(AssetID id) noexcept; void SetCustomUpdateShaderAssetID(AssetID id) noexcept;
void SetCustomVertexShaderAssetID(AssetID id) noexcept;
void SetCustomFragmentShaderAssetID (AssetID id) noexcept;
AssetID GetTextureAssetID(void) const noexcept; AssetID GetTextureAssetID(void) const noexcept;
AssetID GetCustomUpdateShaderAssetID(void) const noexcept; AssetID GetCustomUpdateShaderAssetID(void) const noexcept;
AssetID GetCustomVertexShaderAssetID(void) const noexcept;
AssetID GetCustomFragmentShaderAssetID(void) const noexcept;
friend class SHParticleSubSystem; friend class SHParticleSubSystem;

View File

@ -268,10 +268,73 @@ namespace SHADE
return customUpdatePipelineCache.at (customUpdateShader).customPipeline; return customUpdatePipelineCache.at (customUpdateShader).customPipeline;
} }
void SHParticleSubSystem::Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept Handle<SHVkPipeline> SHParticleSubSystem::GetCustomGraphicsPipeline(Handle<SHVkShaderModule> customVS, Handle<SHVkShaderModule> 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<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> compatibleSubpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept
{ {
descPool = inDescPool; descPool = inDescPool;
logicalDevice = device; logicalDevice = device;
renderpass = compatibleRenderpass;
subpass = compatibleSubpass;
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* INITIALIZE ALL PIPELINES */ /* INITIALIZE ALL PIPELINES */
@ -499,12 +562,22 @@ namespace SHADE
auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>(); auto& emitters = SHComponentManager::GetDense<SHParticleEmitterComponent>();
auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::PARTICLE_RENEDERING); 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 // TODO: Issue barrier for output particle data. Semaphore should also be issued outside in SHGraphicsSystem
for (auto& emitter : emitters) 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) if (emitter.isActive)
{ {
// bind the descriptor sets required for emitting particles // bind the descriptor sets required for emitting particles

View File

@ -82,7 +82,14 @@ namespace SHADE
//! Desc pool for particle component desc set allocation //! Desc pool for particle component desc set allocation
Handle<SHVkDescriptorPool> descPool; Handle<SHVkDescriptorPool> descPool;
//! Renderpass the system draws its particles in
Handle<SHVkRenderpass> renderpass;
//! Subpass the system draws its particles in
Handle<SHSubpass> subpass;
std::unordered_map<Handle<SHVkShaderModule>, CustomPipeline> customUpdatePipelineCache; std::unordered_map<Handle<SHVkShaderModule>, CustomPipeline> customUpdatePipelineCache;
std::unordered_map<std::pair<Handle<SHVkShaderModule>, Handle<SHVkShaderModule>>, CustomPipeline> customGraphicsPipelineCache;
void InitializeComponent (SHParticleEmitterComponent& comp) noexcept; void InitializeComponent (SHParticleEmitterComponent& comp) noexcept;
@ -92,10 +99,11 @@ namespace SHADE
void PreparePrePostUpdateBarriers (std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept; void PreparePrePostUpdateBarriers (std::vector<vk::BufferMemoryBarrier>& preUpdateBarriers, std::vector<vk::BufferMemoryBarrier>& postUpdateBarriers, SHParticleEmitterComponent const& emitter, uint32_t const EMITTER_INDEX, uint32_t const FRAME_INDEX) noexcept;
Handle<SHVkPipeline> GetCustomUpdatePipeline (Handle<SHVkShaderModule> customUpdateShader) noexcept; Handle<SHVkPipeline> GetCustomUpdatePipeline(Handle<SHVkShaderModule> customUpdateShader) noexcept;
Handle<SHVkPipeline> GetCustomGraphicsPipeline(Handle<SHVkShaderModule> customVS, Handle<SHVkShaderModule> customFS) noexcept;
public: public:
void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> subpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept; void Init(Handle<SHVkLogicalDevice> device, Handle<SHVkDescriptorPool> inDescPool, Handle<SHVkRenderpass> compatibleRenderpass, Handle<SHSubpass> compatibleSubpass, Handle<SHVkShaderModule> VS, Handle<SHVkShaderModule> FS, Handle<SHVkShaderModule> emitCS, Handle<SHVkShaderModule> defaultUpdateCS) noexcept;
void Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, Handle<SHVkFence> waitFence = {}) noexcept; void Run(Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex, Handle<SHVkFence> waitFence = {}) noexcept;
void ResetInstanceCounts (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept; void ResetInstanceCounts (Handle<SHVkCommandBuffer> cmdBuffer, uint32_t frameIndex) noexcept;

View File

@ -518,6 +518,8 @@ namespace YAML
static constexpr std::string_view ROTATION_SPEED_TAG = "Rotation Speed"; 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 ROTATION_DECAY_TAG = "Rotation Decay";
static constexpr std::string_view TEXTURE_ASSET_ID_TAG = "Texture Asset ID"; 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 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_TAG = "Color Tint";
static constexpr std::string_view COLOR_TINT_RANGE_TAG = "Color Tint Range"; 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_SPEED_TAG.data()] = rhs.GetRotationSpeed();
node[ROTATION_DECAY_TAG.data()] = rhs.GetRotationDecay(); node[ROTATION_DECAY_TAG.data()] = rhs.GetRotationDecay();
node[TEXTURE_ASSET_ID_TAG.data()] = rhs.GetTextureAssetID(); 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[CUSTOM_UPDATE_SHADER_ASSET_ID_TAG.data()] = rhs.GetCustomUpdateShaderAssetID();
node[COLOR_TINT_TAG.data()] = rhs.GetColorTint(); node[COLOR_TINT_TAG.data()] = rhs.GetColorTint();
node[COLOR_TINT_RANGE_TAG.data()] = rhs.GetColorTintRange(); node[COLOR_TINT_RANGE_TAG.data()] = rhs.GetColorTintRange();
@ -635,6 +639,31 @@ namespace YAML
rhs.SetCustomUpdateShaderAssetID(id); rhs.SetCustomUpdateShaderAssetID(id);
} }
if (node[CUSTOM_VERTEX_SHADER_ASSET_ID_TAG.data()].IsDefined())
{
AssetID id = node[CUSTOM_VERTEX_SHADER_ASSET_ID_TAG.data()].as<AssetID>();
Handle<SHVkShaderModule> shaderModule = SHResourceManager::LoadOrGet<SHVkShaderModule>(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<AssetID>();
Handle<SHVkShaderModule> shaderModule = SHResourceManager::LoadOrGet<SHVkShaderModule>(id);
SHResourceManager::FinaliseChanges();
//gfxSystem->BuildTextures();
rhs.SetCustomFragmentShader(shaderModule);
rhs.SetCustomFragmentShaderAssetID(id);
}
return true; return true;
} }
}; };