Basic light culling but without the culling

This commit is contained in:
Dynamitos
2021-06-12 18:51:29 +02:00
parent 22adb08bfc
commit 7f019a28b4
17 changed files with 122 additions and 63 deletions
+5 -5
View File
@@ -8,9 +8,9 @@ import MATERIAL_IMPORT;
import PrimitiveSceneData;
import MaterialParameter;
layout(set = INDEX_LIGHT_ENV, binding = 1)
layout(set = INDEX_LIGHT_ENV, binding = 4)
StructuredBuffer<uint> lightIndexList;
layout(set = INDEX_LIGHT_ENV, binding = 2)
layout(set = INDEX_LIGHT_ENV, binding = 5)
RWTexture2D<uint2> lightGrid;
@@ -56,9 +56,9 @@ float4 fragmentMain(
float3 result = float3(0, 0, 0);
for (int i = 0; i < gLightEnv.numDirectionalLights; i++)
for (int i = 0; i < numDirectionalLights; i++)
{
result += gLightEnv.directionalLights[i].illuminate(materialParams, brdf, viewDir);
result += directionalLights[i].illuminate(materialParams, brdf, viewDir);
}
uint2 tileIndex = uint2(floor(position.xy / BLOCK_SIZE));
@@ -69,7 +69,7 @@ float4 fragmentMain(
for (int j = 0; j < lightCount; ++j)
{
uint lightIndex = lightIndexList[startOffset + j];
PointLight pointLight = gLightEnv.pointLights[lightIndex];
PointLight pointLight = pointLights[lightIndex];
result += pointLight.illuminate(materialParams, brdf, viewDir);
}
return float4(result, 1);
+7 -6
View File
@@ -102,15 +102,16 @@ void cullLights(ComputeShaderInput in)
Plane minPlane = {float3(0, 0, -1), -minDepthVS};
for ( uint i = in.groupIndex; i < gLightEnv.numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
{
PointLight light = gLightEnv.pointLights[i];
//if(gLightEnv.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
PointLight light = pointLights[i];
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
{
tAppendLight(i);
//if(!light.insidePlane(minPlane))
//{
oAppendLight(i);
//}
{
oAppendLight(i);
}
}
}
+7 -11
View File
@@ -58,15 +58,11 @@ struct PointLight : ILightEnv
}
};
#define MAX_DIRECTIONAL_LIGHTS 4
#define MAX_POINT_LIGHTS 256
struct Lights
{
DirectionalLight directionalLights[MAX_DIRECTIONAL_LIGHTS];
PointLight pointLights[MAX_POINT_LIGHTS];
uint numDirectionalLights;
uint numPointLights;
};
layout(set = INDEX_LIGHT_ENV, binding = 0, std430)
ConstantBuffer<Lights> gLightEnv;
StructuredBuffer<DirectionalLight> directionalLights;
layout(set = INDEX_LIGHT_ENV, binding = 1, std430)
ConstantBuffer<uint> numDirectionalLights;
layout(set = INDEX_LIGHT_ENV, binding = 2, std430)
StructuredBuffer<PointLight> pointLights;
layout(set = INDEX_LIGHT_ENV, binding = 3, std430)
ConstantBuffer<uint> numPointLights;
+1 -1
View File
@@ -35,7 +35,7 @@ void AssetRegistry::importFile(const std::string &filePath)
{
get().importTexture(fsPath);
}
if (extension.compare(".semat") == 0)
if (extension.compare(".asset") == 0)
{
get().importMaterial(fsPath);
}
+2 -1
View File
@@ -16,9 +16,10 @@ public:
virtual void load() override;
void addMesh(PMesh mesh);
const Array<PMesh> getMeshes();
//Workaround while no editor
Array<PMaterialAsset> referencedMaterials;
private:
Array<PMesh> meshes;
Array<PMaterialAsset> referencedMaterials;
};
DEFINE_REF(MeshAsset)
} // namespace Seele
+1
View File
@@ -323,6 +323,7 @@ namespace Seele
_data[index] = std::move(_data[arraySize - 1]);
}
arraySize--;
markIteratorDirty();
}
void clear()
{
+23 -8
View File
@@ -92,9 +92,17 @@ BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics
basePassLayout = graphics->createPipelineLayout();
lightLayout = graphics->createDescriptorLayout("LightLayout");
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
// Directional Lights
lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
// Point Lights
lightLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
// Light Index List
lightLayout->addDescriptorBinding(4, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
// Light Grid
lightLayout->addDescriptorBinding(5, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE);
lightLayout->create();
basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout);
descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocateDescriptorSet();
@@ -155,9 +163,12 @@ void BasePass::render()
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, scene->getLightBuffer());
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, oLightIndexList);
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(2, oLightGrid);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, directLightBuffer);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(1, numDirLightBuffer);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(2, pointLightBuffer);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(3, numPointLightBuffer);
descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(4, oLightIndexList);
descriptorSets[INDEX_LIGHT_ENV]->updateTexture(5, oLightGrid);
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : scene->getStaticMeshes())
@@ -174,12 +185,16 @@ void BasePass::endFrame()
void BasePass::publishOutputs()
{
colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner());
colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner());
renderGraph->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment);
}
void BasePass::createRenderPass()
{
{
directLightBuffer = renderGraph->requestBuffer("DIRECTIONAL_LIGHTS");
pointLightBuffer = renderGraph->requestBuffer("POINT_LIGHTS");
numDirLightBuffer = renderGraph->requestUniform("NUM_DIRECTIONAL_LIGHTS");
numPointLightBuffer = renderGraph->requestUniform("NUM_POINT_LIGHTS");
Gfx::PRenderTargetAttachment depthAttachment = renderGraph->requestRenderTarget("DEPTHPREPASS_DEPTH");
depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD;
Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment);
@@ -54,6 +54,10 @@ private:
Gfx::PPipelineLayout basePassLayout;
// Set 0: Light environment
static constexpr uint32 INDEX_LIGHT_ENV = 0;
Gfx::PStructuredBuffer directLightBuffer;
Gfx::PUniformBuffer numDirLightBuffer;
Gfx::PStructuredBuffer pointLightBuffer;
Gfx::PUniformBuffer numPointLightBuffer;
Gfx::PStructuredBuffer oLightIndexList;
Gfx::PTexture oLightGrid;
Gfx::PDescriptorLayout lightLayout;
@@ -42,7 +42,6 @@ void LightCullingPass::beginFrame()
counterReset.size = sizeof(uint32);
oLightIndexCounter->updateContents(counterReset);
tLightIndexCounter->updateContents(counterReset);
cullingDescriptorLayout->reset();
lightEnvDescriptorLayout->reset();
@@ -58,6 +57,12 @@ void LightCullingPass::beginFrame()
cullingDescriptorSet->updateBuffer(7, tLightIndexList);
cullingDescriptorSet->updateTexture(8, oLightGrid);
cullingDescriptorSet->updateTexture(9, tLightGrid);
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
lightEnvDescriptorSet->updateBuffer(3, numPointLightBuffer);
lightEnvDescriptorSet->writeChanges();
}
void LightCullingPass::render()
@@ -75,8 +80,6 @@ void LightCullingPass::render()
depthAttachment->transferOwnership(Gfx::QueueType::COMPUTE);
cullingDescriptorSet->updateTexture(2, depthAttachment);
cullingDescriptorSet->writeChanges();
lightEnvDescriptorSet->updateBuffer(0, scene->getLightBuffer());
lightEnvDescriptorSet->writeChanges();
Gfx::PComputeCommand computeCommand = graphics->createComputeCommand("CullingCommand");
computeCommand->bindPipeline(cullingPipeline);
Array<Gfx::PDescriptorSet> descriptorSets = {cullingDescriptorSet, lightEnvDescriptorSet};
@@ -103,26 +106,50 @@ void LightCullingPass::publishOutputs()
dispatchParams.numThreads = numThreadGroups * glm::uvec3(BLOCK_SIZE, BLOCK_SIZE, 1);
BulkResourceData resourceData;
StructuredBufferCreateInfo createInfo;
StructuredBufferCreateInfo structInfo;
uint32 counterReset = 0;
resourceData.size = sizeof(uint32);
resourceData.data = (uint8*)&counterReset;
resourceData.owner = Gfx::QueueType::COMPUTE;
createInfo.bDynamic = true;
createInfo.resourceData = resourceData;
oLightIndexCounter = graphics->createStructuredBuffer(createInfo);
tLightIndexCounter = graphics->createStructuredBuffer(createInfo);
structInfo.bDynamic = true;
structInfo.resourceData = resourceData;
oLightIndexCounter = graphics->createStructuredBuffer(structInfo);
tLightIndexCounter = graphics->createStructuredBuffer(structInfo);
resourceData.data = nullptr;
resourceData.size = sizeof(uint32_t)
* dispatchParams.numThreadGroups.x
* dispatchParams.numThreadGroups.y
* dispatchParams.numThreadGroups.z * 200;
createInfo.resourceData = resourceData;
createInfo.bDynamic = false;
oLightIndexList = graphics->createStructuredBuffer(createInfo);
tLightIndexList = graphics->createStructuredBuffer(createInfo);
structInfo.resourceData = resourceData;
structInfo.bDynamic = false;
oLightIndexList = graphics->createStructuredBuffer(structInfo);
tLightIndexList = graphics->createStructuredBuffer(structInfo);
renderGraph->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
renderGraph->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
const LightEnv& lightEnv = scene->getLightBuffer();
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
resourceData.data = (uint8*)&lightEnv.directionalLights;
structInfo.resourceData = resourceData;
structInfo.bDynamic = true;
directLightBuffer = graphics->createStructuredBuffer(structInfo);
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
resourceData.data = (uint8*)&lightEnv.pointLights;
structInfo.resourceData = resourceData;
pointLightBuffer = graphics->createStructuredBuffer(structInfo);
UniformBufferCreateInfo uniformInfo;
resourceData.size = sizeof(uint32);
resourceData.data = (uint8*)&lightEnv.numDirectionalLights;
uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true;
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
resourceData.data = (uint8*)&lightEnv.numPointLights;
uniformInfo.resourceData = resourceData;
uniformInfo.bDynamic = true;
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
renderGraph->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
renderGraph->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
renderGraph->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
renderGraph->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
TextureCreateInfo textureInfo;
textureInfo.width = dispatchParams.numThreadGroups.x;
textureInfo.height = dispatchParams.numThreadGroups.y;
@@ -132,6 +159,7 @@ void LightCullingPass::publishOutputs()
tLightGrid = graphics->createTexture2D(textureInfo);
renderGraph->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
renderGraph->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
}
@@ -162,8 +190,12 @@ void LightCullingPass::createRenderPass()
lightEnvDescriptorLayout = graphics->createDescriptorLayout("LightEnv");
//LightEnv
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
// Directional Lights
lightEnvDescriptorLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightEnvDescriptorLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
// Point Lights
lightEnvDescriptorLayout->addDescriptorBinding(2, Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER);
lightEnvDescriptorLayout->addDescriptorBinding(3, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
cullingLayout = graphics->createPipelineLayout();
cullingLayout->addDescriptorLayout(0, cullingDescriptorLayout);
@@ -64,6 +64,10 @@ private:
Gfx::PStructuredBuffer tLightIndexList;
Gfx::PTexture2D oLightGrid;
Gfx::PTexture2D tLightGrid;
Gfx::PStructuredBuffer directLightBuffer;
Gfx::PUniformBuffer numDirLightBuffer;
Gfx::PStructuredBuffer pointLightBuffer;
Gfx::PUniformBuffer numPointLightBuffer;
Gfx::PDescriptorSet lightEnvDescriptorSet;
Gfx::PDescriptorSet cullingDescriptorSet;
Gfx::PDescriptorLayout lightEnvDescriptorLayout;
+14 -1
View File
@@ -48,7 +48,6 @@ Gfx::PTexture RenderGraph::requestTexture(const std::string& outputName)
return registeredTextures[outputName];
}
Gfx::PStructuredBuffer RenderGraph::requestBuffer(const std::string& outputName)
{
if(registeredBuffers.find(outputName) == registeredBuffers.end())
@@ -59,6 +58,16 @@ Gfx::PStructuredBuffer RenderGraph::requestBuffer(const std::string& outputName)
return registeredBuffers[outputName];
}
Gfx::PUniformBuffer RenderGraph::requestUniform(const std::string& outputName)
{
if(registeredUniforms.find(outputName) == registeredUniforms.end())
{
std::cout << "Attachment " << outputName << " not found" << std::endl;
return nullptr;
}
return registeredUniforms[outputName];
}
void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment)
{
registeredAttachments[outputName] = attachment;
@@ -72,4 +81,8 @@ void RenderGraph::registerTextureOutput(const std::string& outputName, Gfx::PTex
void RenderGraph::registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer)
{
registeredBuffers[outputName] = buffer;
}
void RenderGraph::registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer)
{
registeredUniforms[outputName] = buffer;
}
@@ -15,13 +15,16 @@ public:
Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName);
Gfx::PTexture requestTexture(const std::string& outputName);
Gfx::PStructuredBuffer requestBuffer(const std::string& outputName);
Gfx::PUniformBuffer requestUniform(const std::string& outputName);
void registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment);
void registerTextureOutput(const std::string& outputName, Gfx::PTexture buffer);
void registerBufferOutput(const std::string& outputName, Gfx::PStructuredBuffer buffer);
void registerUniformOutput(const std::string& outputName, Gfx::PUniformBuffer buffer);
private:
Map<std::string, Gfx::PRenderTargetAttachment> registeredAttachments;
Map<std::string, Gfx::PTexture> registeredTextures;
Map<std::string, Gfx::PStructuredBuffer> registeredBuffers;
Map<std::string, Gfx::PUniformBuffer> registeredUniforms;
List<PRenderPass> renderPasses;
};
DEFINE_REF(RenderGraph)
@@ -296,7 +296,7 @@ void StagingManager::clearPending()
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
{
std::unique_lock l(lock);
std::scoped_lock l(lock);
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
{
auto freeBuffer = *it;
@@ -344,7 +344,7 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
{
std::unique_lock l(lock);
std::scoped_lock l(lock);
freeBuffers.add(buffer);
activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
}
@@ -18,7 +18,7 @@ PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
for (uint32 i = 0; i < assetMeshes.size(); i++)
{
auto& batch = staticMeshes[i];
batch.material = assetMeshes[i]->referencedMaterial;
batch.material = asset->referencedMaterials[i];
batch.isBackfaceCullingDisabled = false;
batch.isCastingShadow = true;
batch.primitiveComponent = this;
+1 -10
View File
@@ -19,23 +19,14 @@ Scene::Scene(Gfx::PGraphics graphics)
lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1);
lightEnv.directionalLights[0].direction = Vector4(1, 1, 0, 1);
lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1);
lightEnv.numDirectionalLights = 0;
lightEnv.numDirectionalLights = 1;
srand((unsigned int)time(NULL));
for(uint32 i = 0; i < MAX_POINT_LIGHTS/2; ++i)
{
lightEnv.pointLights[i].colorRange = Vector4(frand(), frand(), frand(), frand() * 30);
lightEnv.pointLights[i].positionWS = Vector4(frand() * 100-50, frand(), frand() * 100-50, 1);
lightEnv.pointLights[i].positionVS = Vector4(frand() * 100-50, frand(), frand() * 100-50, 1);
}
lightEnv.numPointLights = MAX_POINT_LIGHTS/2;
BulkResourceData lightInit;
UniformBufferCreateInfo structuredInfo;
lightInit.size = sizeof(LightEnv);
lightInit.data = (uint8*)&lightEnv;
structuredInfo.resourceData = lightInit;
structuredInfo.bDynamic = false;
lightBuffer = graphics->createUniformBuffer(structuredInfo);
}
Scene::~Scene()
+1 -2
View File
@@ -46,14 +46,13 @@ public:
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; }
const Gfx::PUniformBuffer& getLightBuffer() const { return lightBuffer; }
const LightEnv& getLightBuffer() const { return lightEnv; }
UPSceneUpdater& getSceneUpdater() { return updater; }
private:
Array<MeshBatch> staticMeshes;
Array<PActor> rootActors;
Array<PPrimitiveComponent> primitives;
LightEnv lightEnv;
Gfx::PUniformBuffer lightBuffer;
Gfx::PGraphics graphics;
UPSceneUpdater updater;
};
-1
View File
@@ -32,7 +32,6 @@ int main()
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.obj");
PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane"));
plane->setWorldScale(Vector(100, 100, 100));
plane->addWorldTranslation(Vector(0, -10, 0));
PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely"));
arissa->addWorldTranslation(Vector(0, 0, 100));
arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f));