Implemented scanline and silhouette effect #363

Merged
Xenosas1337 merged 12 commits from SP3-1-Rendering into main 2023-02-24 17:20:46 +08:00
17 changed files with 219 additions and 15 deletions
Showing only changes of commit 7eac238226 - Show all commits

View File

@ -0,0 +1,8 @@
- VertexShader: 38847805
FragmentShader: 42962441
SubPass: Object VFX Subpass No Depth
Properties:
data.color: {x: 1, y: 1, z: 1, w: 1}
data.textureIndex: 0
data.alpha: 0
data.beta: {x: 1, y: 1, z: 1}

View File

@ -0,0 +1,3 @@
Name: Silhouette
ID: 126391182
Type: 7

View File

@ -0,0 +1,67 @@
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require
struct MatPropData
{
vec4 color;
};
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;
};
layout(location = 0) in struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
vec4 worldPos; // location = 3
} In;
// material stuff
layout(location = 4) flat in struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} In2;
layout (set = 0, binding = 1) uniform sampler2D textures[]; // for textures (global)
layout (std430, set = 2, binding = 0) buffer MaterialProperties // For materials
{
MatPropData data[];
} MatProp;
layout (set = 0, binding = 0) uniform GenericDataBuffer
{
GenericData data;
} genericDataBuffer;
layout(location = 0) out vec4 objectVFX;
layout(input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput depthBuffer;
void main()
{
// Sample depth buffer using UV and save it
float currentDepth = subpassLoad (depthBuffer).r;
// Use depth buffer to check against current fragment's depth. If fragment is behind depth buffer, render fragment.
if (currentDepth > gl_FragCoord.z)
discard;
objectVFX = MatProp.data[In2.materialIndex].color;
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Silhouette_FS
ID: 42962441
Type: 2

View File

@ -0,0 +1,68 @@
#version 450
#extension GL_KHR_vulkan_glsl : enable
//#include "ShaderDescriptorDefinitions.glsl"
layout(location = 0) in vec3 aVertexPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec3 aNormal;
layout(location = 3) in vec3 aTangent;
layout(location = 4) in mat4 worldTransform;
layout(location = 8) in uvec2 integerData;
layout(location = 9) in uvec4 aBoneIndices;
layout(location = 10) in vec4 aBoneWeights;
layout(location = 11) in uint firstBoneIndex;
layout(location = 0) out struct
{
vec4 vertPos; // location 0
vec2 uv; // location = 1
vec4 normal; // location = 2
vec4 worldPos; // location = 3
} Out;
// material stuff
layout(location = 4) out struct
{
int materialIndex;
uint eid;
uint lightLayerIndex;
} Out2;
layout(set = 1, binding = 0) uniform CameraData
{
vec4 position;
mat4 vpMat;
mat4 viewMat;
mat4 projMat;
} cameraData;
void main()
{
Out2.materialIndex = gl_InstanceIndex;
Out2.eid = integerData[0];
Out2.lightLayerIndex = integerData[1];
// for transforming gBuffer position and normal data
mat4 modelViewMat = cameraData.viewMat * worldTransform;
// gBuffer position will be in view space
Out.vertPos = modelViewMat * vec4(aVertexPos, 1.0f);
Out.worldPos = worldTransform * vec4 (aVertexPos, 1.0f);
// uvs for texturing in fragment shader
Out.uv = aUV;
mat3 transposeInv = mat3 (transpose(inverse(modelViewMat)));
// normals are also in view space
Out.normal.rgb = transposeInv * aNormal.rgb;
Out.normal.rgb = normalize (Out.normal.rgb);
// clip space for rendering
gl_Position = cameraData.vpMat * worldTransform * vec4 (aVertexPos, 1.0f);
}

Binary file not shown.

View File

@ -0,0 +1,3 @@
Name: Silhouette_VS
ID: 38847805
Type: 2

View File

@ -3,7 +3,7 @@
#extension GL_ARB_shading_language_420pack : enable #extension GL_ARB_shading_language_420pack : enable
#extension GL_EXT_nonuniform_qualifier : require #extension GL_EXT_nonuniform_qualifier : require
layout (input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput sceneTexture; layout (input_attachment_index = 0, set = 3, binding = 0) uniform subpassInput sceneTexture;
layout(location = 0) out vec4 fragColor; layout(location = 0) out vec4 fragColor;

View File

@ -25,9 +25,10 @@ namespace SHADE
{ {
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING)].descMappings.AddMappings
({ ({
{SHPredefinedDescriptorTypes::STATIC_DATA, 0}, {SHPredefinedDescriptorTypes::STATIC_DATA, 0},
{SHPredefinedDescriptorTypes::CAMERA, 1}, {SHPredefinedDescriptorTypes::CAMERA, 1},
{SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2}, {SHPredefinedDescriptorTypes::PER_INSTANCE_BATCH, 2},
{SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE, 3},
}); });
perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings perSystemData[SHUtilities::ConvertEnum(SystemType::BATCHING_ANIM)].descMappings.AddMappings

View File

@ -129,11 +129,13 @@ namespace SHADE
static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write"; static constexpr std::string_view GBUFFER_WRITE_SUBPASS = "G-Buffer Write";
static constexpr std::string_view UI_SUBPASS = "UI"; static constexpr std::string_view UI_SUBPASS = "UI";
static constexpr std::string_view VFX_SUBPASS = "VFX"; static constexpr std::string_view VFX_SUBPASS = "VFX";
static constexpr std::string_view OBJ_VFX_SUBPASS = "Object VFX Subpass No Depth";
static constexpr std::array USABLE_SUBPASSES = static constexpr std::array USABLE_SUBPASSES =
{ {
GBUFFER_WRITE_SUBPASS, GBUFFER_WRITE_SUBPASS,
UI_SUBPASS UI_SUBPASS,
OBJ_VFX_SUBPASS
}; };
}; };

View File

@ -215,7 +215,7 @@ namespace SHADE
renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); renderGraph->AddResource("Normals", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
//worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat); //worldRenderGraph->AddResource("Tangents", { SH_ATT_DESC_TYPE_FLAGS::COLOR, SH_ATT_DESC_TYPE_FLAGS::INPUT, SH_ATT_DESC_TYPE_FLAGS::STORAGE }, windowDims.first, windowDims.second, vk::Format::eR32G32B32A32Sfloat);
renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second); renderGraph->AddResource("Albedo", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second);
renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint); renderGraph->AddResource("Depth Buffer", { SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT }, true, windowDims.first, windowDims.second, vk::Format::eD32SfloatS8Uint);
renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Entity ID", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc); renderGraph->AddResource("Light Layer Indices", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE }, true, windowDims.first, windowDims.second, vk::Format::eR32Uint, 1, vk::ImageUsageFlagBits::eTransferSrc);
renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second); renderGraph->AddResource("Scene", { SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR, SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT, SH_RENDER_GRAPH_RESOURCE_FLAGS::STORAGE, SH_RENDER_GRAPH_RESOURCE_FLAGS::SHARED }, true, windowDims.first, windowDims.second);
@ -255,7 +255,13 @@ namespace SHADE
gBufferSubpass->AddColorOutput("Object VFX"); gBufferSubpass->AddColorOutput("Object VFX");
gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL); gBufferSubpass->AddDepthOutput("Depth Buffer", SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL);
usableSubpassesMapping.emplace (std::string (SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass); // We add the object VFX render target and depth buffer as input just in case we want to make comparisons
auto objectVfxSubpassNoDepth = gBufferNode->AddSubpass(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data(), worldViewport, worldRenderer);
objectVfxSubpassNoDepth->AddColorOutput("Object VFX");
objectVfxSubpassNoDepth->AddInput ("Depth Buffer");
usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::GBUFFER_WRITE_SUBPASS.data()), gBufferSubpass);
usableSubpassesMapping.emplace(std::string(SHGraphicsConstants::RenderGraphEntityNames::OBJ_VFX_SUBPASS.data()), objectVfxSubpassNoDepth);
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/
/* SSAO PASS AND DATA INIT */ /* SSAO PASS AND DATA INIT */

View File

@ -512,8 +512,9 @@ namespace SHADE
uint32_t h = static_cast<uint32_t>(resource->GetHeight()); uint32_t h = static_cast<uint32_t>(resource->GetHeight());
cmdBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h); cmdBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0; //static constexpr uint32_t INPUT_IMAGE_SET_INDEX = 0;
newSubpass->BindInputDescriptorSets (cmdBuffer, INPUT_IMAGE_SET_INDEX, frameIndex); auto const& mappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
newSubpass->BindInputDescriptorSets (cmdBuffer, mappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex);
// draw a quad. // draw a quad.
cmdBuffer->DrawArrays(4, 1, 0, 0); cmdBuffer->DrawArrays(4, 1, 0, 0);
@ -570,7 +571,8 @@ namespace SHADE
auto cmdBuffer = commandBuffers[frameIndex]; auto cmdBuffer = commandBuffers[frameIndex];
cmdBuffer->BeginLabeledSegment(name); cmdBuffer->BeginLabeledSegment(name);
auto batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING); auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
// Force bind pipeline layout // Force bind pipeline layout
cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS); cmdBuffer->ForceSetPipelineLayout(batchingSystemData.dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS);

View File

@ -184,12 +184,13 @@ namespace SHADE
for (auto& inputAtt : subpass->inputReferences) for (auto& inputAtt : subpass->inputReferences)
{ {
auto resource = attResources[inputAtt.attachment]; auto resource = attResources[inputAtt.attachment];
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT)) auto typeFlags = resource->resourceTypeFlags;
if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::INPUT))
{ {
if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) || if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR) ||
resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT)) typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::COLOR_PRESENT))
colorRead |= (1 << i); colorRead |= (1 << i);
else if (resource->resourceTypeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL)) else if (typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH_STENCIL) || typeFlags & static_cast<uint32_t>(SH_RENDER_GRAPH_RESOURCE_FLAGS::DEPTH))
depthRead |= (1 << i); depthRead |= (1 << i);
} }
else else
@ -265,6 +266,7 @@ namespace SHADE
// initialize input descriptors // initialize input descriptors
subpasses[i]->CreateInputDescriptors(); subpasses[i]->CreateInputDescriptors();
subpasses[i]->GenerateDummyPipielineLayout();
++i; ++i;
} }

View File

@ -226,11 +226,15 @@ namespace SHADE
commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h); commandBuffer->SetViewportScissor(static_cast<float>(w), static_cast<float>(h), w, h);
} }
commandBuffer->ForceSetPipelineLayout(dummyPipelineLayout, SH_PIPELINE_TYPE::GRAPHICS);
auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING); auto const& descMappings = SHGraphicsPredefinedData::GetMappings(SHGraphicsPredefinedData::SystemType::BATCHING);
if (renderer) if (renderer)
renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex); renderer->BindDescriptorSet(commandBuffer, SH_PIPELINE_TYPE::GRAPHICS, descMappings.at(SHPredefinedDescriptorTypes::CAMERA), frameIndex);
BindInputDescriptorSets (commandBuffer, descMappings.at(SHPredefinedDescriptorTypes::RENDER_GRAPH_RESOURCE), frameIndex);
// If companion subpass is not a valid handle, render super batch normally // If companion subpass is not a valid handle, render super batch normally
if (!companionSubpass.companion) if (!companionSubpass.companion)
{ {
@ -439,6 +443,33 @@ namespace SHADE
} }
} }
/***************************************************************************/
/*!
\brief
Generates the dummy pipeline layout for subpass; specifically add the
input descriptor set layout if it exists.
\return
*/
/***************************************************************************/
void SHSubpass::GenerateDummyPipielineLayout(void) noexcept
{
auto const& batchingSystemData = SHGraphicsPredefinedData::GetSystemData(SHGraphicsPredefinedData::SystemType::BATCHING);
std::vector newLayouts = batchingSystemData.descSetLayouts;
if (inputDescriptorLayout)
{
newLayouts.push_back(inputDescriptorLayout);
}
dummyPipelineLayout = graphStorage->logicalDevice->CreatePipelineLayoutDummy
(
SHPipelineLayoutParamsDummy{ newLayouts }
);
}
/***************************************************************************/ /***************************************************************************/
/*! /*!

View File

@ -22,6 +22,7 @@ namespace SHADE
class SHRenderer; class SHRenderer;
class SHViewport; class SHViewport;
class SHVkPipeline; class SHVkPipeline;
class SHVkPipelineLayout;
class SH_API SHSubpass : public ISelfHandle<SHSubpass> class SH_API SHSubpass : public ISelfHandle<SHSubpass>
{ {
@ -87,6 +88,12 @@ namespace SHADE
std::vector<Handle<SHVkSampler>> inputSamplers; std::vector<Handle<SHVkSampler>> inputSamplers;
//! Dummy pipeline layout for subpass to bind before draw.
//! // IMPORTANT NOTE: After implementing input descriptors, every subpass differs in number input descriptors.
//! Before binding the input descriptors, a pipeline layout containing the desc set layouts
//! for the input descriptors is required, making this umbrella initial dummy bind invalid.
Handle<SHVkPipelineLayout> dummyPipelineLayout;
////! subpass compute image barriers. We do this because every frame has a different ////! subpass compute image barriers. We do this because every frame has a different
////! swapchain image. If the resource we want to transition is not a swapchain image, ////! swapchain image. If the resource we want to transition is not a swapchain image,
@ -146,6 +153,7 @@ namespace SHADE
//void InitComputeBarriers (void) noexcept; //void InitComputeBarriers (void) noexcept;
void CreateInputDescriptors (void) noexcept; void CreateInputDescriptors (void) noexcept;
void UpdateWriteDescriptors (void) noexcept; void UpdateWriteDescriptors (void) noexcept;
void GenerateDummyPipielineLayout (void) noexcept;
private: private:
/*-----------------------------------------------------------------------*/ /*-----------------------------------------------------------------------*/