From f2fd8a57c8cc2ecd0c572e726dd8dd403ba8d38a Mon Sep 17 00:00:00 2001 From: Powei Feng Date: Wed, 9 Oct 2024 16:29:01 -0700 Subject: [PATCH] Testing stencilling 3 --- filament/backend/src/vulkan/VulkanDriver.cpp | 17 +-- filament/backend/src/vulkan/VulkanHandles.cpp | 16 +-- filament/backend/src/vulkan/VulkanHandles.h | 4 +- samples/hellotriangle.cpp | 108 +++++++++++++++--- 4 files changed, 103 insertions(+), 42 deletions(-) diff --git a/filament/backend/src/vulkan/VulkanDriver.cpp b/filament/backend/src/vulkan/VulkanDriver.cpp index 4602067663..0982173876 100644 --- a/filament/backend/src/vulkan/VulkanDriver.cpp +++ b/filament/backend/src/vulkan/VulkanDriver.cpp @@ -606,7 +606,7 @@ void VulkanDriver::createRenderTargetR(Handle rth, } } - VulkanAttachment depthStencil[2] = {}; + VulkanAttachment depthStencil; if (depth.handle) { depthStencil[0] = { .texture = mResourceAllocator.handle_cast(depth.handle), @@ -621,19 +621,8 @@ void VulkanDriver::createRenderTargetR(Handle rth, attachmentCount++; } - if (stencil.handle) { - depthStencil[1] = { - .texture = mResourceAllocator.handle_cast(stencil.handle), - .level = stencil.level, - .baseViewIndex = stencil.baseViewIndex, - .layerCount = layerCount, - .layer = stencil.layer, - }; - UTILS_UNUSED_IN_RELEASE VkExtent2D extent = depthStencil[1].getExtent2D(); - tmin = { std::min(tmin.x, extent.width), std::min(tmin.y, extent.height) }; - tmax = { std::max(tmax.x, extent.width), std::max(tmax.y, extent.height) }; - attachmentCount++; - } + // The stencil buffer is always assumed to be part of the depth-stencil buffer. + assert_invariant(!stencil.handle || stencil.handle == depth.handle); // All attachments must have the same dimensions, which must be greater than or equal to the // render target dimensions. diff --git a/filament/backend/src/vulkan/VulkanHandles.cpp b/filament/backend/src/vulkan/VulkanHandles.cpp index 4222f361a6..f6e3700d11 100644 --- a/filament/backend/src/vulkan/VulkanHandles.cpp +++ b/filament/backend/src/vulkan/VulkanHandles.cpp @@ -314,7 +314,7 @@ void VulkanRenderTarget::bindToSwapChain(VulkanSwapChain& swapChain) { assert_invariant(!mOffscreen); VkExtent2D const extent = swapChain.getExtent(); mColor[0] = { .texture = swapChain.getCurrentColor() }; - mDepth = { .texture = swapChain.getDepth() }; + mDepthStencil = { .texture = swapChain.getDepth() }; width = extent.width; height = extent.height; } @@ -323,7 +323,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica VulkanContext const& context, VmaAllocator allocator, VulkanCommands* commands, uint32_t width, uint32_t height, uint8_t samples, VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT], - VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount) + VulkanAttachment depthStencil, VulkanStagePool& stagePool, uint8_t layerCount) : HwRenderTarget(width, height), VulkanResource(VulkanResourceType::RENDER_TARGET), mOffscreen(true), @@ -332,8 +332,8 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica for (int index = 0; index < MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT; index++) { mColor[index] = color[index]; } - mDepth = depthStencil[0]; - VulkanTexture* depthTexture = (VulkanTexture*) mDepth.texture; + mDepthStencil = depthStencil[0]; + VulkanTexture* depthTexture = (VulkanTexture*) mDepthStencil.texture; if (samples == 1) { return; @@ -372,7 +372,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica // There is no need for sidecar depth if the depth texture is already MSAA. if (depthTexture->samples > 1) { - mMsaaDepthAttachment = mDepth; + mMsaaDepthAttachment = mDepthStencil; return; } @@ -392,7 +392,7 @@ VulkanRenderTarget::VulkanRenderTarget(VkDevice device, VkPhysicalDevice physica mMsaaDepthAttachment = { .texture = msTexture, .level = msLevel, - .layer = mDepth.layer, + .layer = mDepthStencil.layer, }; } @@ -418,8 +418,8 @@ VulkanAttachment& VulkanRenderTarget::getMsaaColor(int target) { return mMsaaAttachments[target]; } -VulkanAttachment& VulkanRenderTarget::getDepth() { - return mDepth; +VulkanAttachment& VulkanRenderTarget::getDepthStencil() { + return mDepthStencil; } VulkanAttachment& VulkanRenderTarget::getMsaaDepth() { diff --git a/filament/backend/src/vulkan/VulkanHandles.h b/filament/backend/src/vulkan/VulkanHandles.h index ee6ffed346..d03e0ba914 100644 --- a/filament/backend/src/vulkan/VulkanHandles.h +++ b/filament/backend/src/vulkan/VulkanHandles.h @@ -304,7 +304,7 @@ struct VulkanRenderTarget : private HwRenderTarget, VulkanResource { VulkanContext const& context, VmaAllocator allocator, VulkanCommands* commands, uint32_t width, uint32_t height, uint8_t samples, VulkanAttachment color[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT], - VulkanAttachment depthStencil[2], VulkanStagePool& stagePool, uint8_t layerCount); + VulkanAttachment depthStencil, VulkanStagePool& stagePool, uint8_t layerCount); // Creates a special "default" render target (i.e. associated with the swap chain) explicit VulkanRenderTarget(); @@ -326,7 +326,7 @@ struct VulkanRenderTarget : private HwRenderTarget, VulkanResource { private: VulkanAttachment mColor[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = {}; - VulkanAttachment mDepth = {}; + VulkanAttachment mDepthStencil = {}; VulkanAttachment mMsaaAttachments[MRT::MAX_SUPPORTED_RENDER_TARGET_COUNT] = {}; VulkanAttachment mMsaaDepthAttachment = {}; const bool mOffscreen : 1; diff --git a/samples/hellotriangle.cpp b/samples/hellotriangle.cpp index 4477429dd6..c777a0796c 100644 --- a/samples/hellotriangle.cpp +++ b/samples/hellotriangle.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -46,23 +47,33 @@ using utils::EntityManager; struct App { Config config; VertexBuffer* vb; + VertexBuffer* vb2; IndexBuffer* ib; Material* mat; Camera* cam; Entity camera; Skybox* skybox; Entity renderable; + Entity r2; }; struct Vertex { - filament::math::float2 position; + filament::math::float3 position; uint32_t color; }; +float const z = 5; + static const Vertex TRIANGLE_VERTICES[3] = { - {{1, 0}, 0xffff0000u}, - {{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3)}, 0xff00ff00u}, - {{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3)}, 0xff0000ffu}, + {{1, 0, z}, 0xffff0000u}, + {{cos(M_PI * 2 / 3), sin(M_PI * 2 / 3), z}, 0xff00ff00u}, + {{cos(M_PI * 4 / 3), sin(M_PI * 4 / 3), z}, 0xff0000ffu}, +}; + +static Vertex T2[3] = { + TRIANGLE_VERTICES[0], + TRIANGLE_VERTICES[1], + TRIANGLE_VERTICES[2], }; static constexpr uint16_t TRIANGLE_INDICES[3] = { 0, 1, 2 }; @@ -120,25 +131,36 @@ static int handleCommandLineArguments(int argc, char* argv[], App* app) { } int main(int argc, char** argv) { + T2[0].position.z = z - 10; + T2[1].position.z = z - 10; + T2[2].position.z = z - 10; + + T2[0].color = 0xFF0000FF; + T2[1].color = 0xFF0000FF; + T2[2].color = 0xFF0000FF; + App app{}; app.config.title = "hellotriangle"; app.config.featureLevel = backend::FeatureLevel::FEATURE_LEVEL_0; handleCommandLineArguments(argc, argv, &app); auto setup = [&app](Engine* engine, View* view, Scene* scene) { - app.skybox = Skybox::Builder().color({0.1, 0.125, 0.25, 1.0}).build(*engine); - scene->setSkybox(app.skybox); view->setPostProcessingEnabled(false); - static_assert(sizeof(Vertex) == 12, "Strange vertex size."); - app.vb = VertexBuffer::Builder() + view->setStencilBufferEnabled(true); + + static_assert(sizeof(Vertex) == 16, "Strange vertex size."); + auto builder = VertexBuffer::Builder() .vertexCount(3) .bufferCount(1) - .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT2, 0, 12) - .attribute(VertexAttribute::COLOR, 0, VertexBuffer::AttributeType::UBYTE4, 8, 12) - .normalized(VertexAttribute::COLOR) - .build(*engine); + .attribute(VertexAttribute::POSITION, 0, VertexBuffer::AttributeType::FLOAT3, 0, 16) + .attribute(VertexAttribute::COLOR, 0, VertexBuffer::AttributeType::UBYTE4, 12, 16) + .normalized(VertexAttribute::COLOR); + app.vb = builder.build(*engine); + app.vb2 = builder.build(*engine); app.vb->setBufferAt(*engine, 0, - VertexBuffer::BufferDescriptor(TRIANGLE_VERTICES, 36, nullptr)); + VertexBuffer::BufferDescriptor(TRIANGLE_VERTICES, 48, nullptr)); + app.vb2->setBufferAt(*engine, 0, + VertexBuffer::BufferDescriptor(T2, 48, nullptr)); app.ib = IndexBuffer::Builder() .indexCount(3) .bufferType(IndexBuffer::IndexType::USHORT) @@ -149,22 +171,67 @@ int main(int argc, char** argv) { .package(RESOURCES_BAKEDCOLOR_DATA, RESOURCES_BAKEDCOLOR_SIZE) .build(*engine); app.renderable = EntityManager::get().create(); + app.r2 = EntityManager::get().create(); + + auto inst1 = app.mat->createInstance(); + inst1->setDepthWrite(false); + inst1->setDepthFunc(MaterialInstance::DepthFunc::A); + inst1->setDepthCulling(false); + + inst1->setStencilWrite(true); + inst1->setStencilCompareFunction(MaterialInstance::StencilCompareFunc::E); + inst1->setStencilOpDepthStencilPass(MaterialInstance::StencilOperation::REPLACE); + inst1->setStencilReferenceValue(6); + + auto inst2 = app.mat->createInstance(); + inst2->setDepthWrite(false); + inst2->setDepthFunc(MaterialInstance::DepthFunc::A); + inst2->setDepthCulling(false); + + inst2->setStencilWrite(true); + inst2->setStencilCompareFunction(MaterialInstance::StencilCompareFunc::L); + inst2->setStencilOpDepthStencilPass(MaterialInstance::StencilOperation::REPLACE); + inst2->setStencilReferenceValue(6); + + + auto& renderableMan = engine->getRenderableManager(); + RenderableManager::Builder(1) .boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }}) - .material(0, app.mat->getDefaultInstance()) + .material(0, inst1) .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.vb, app.ib, 0, 3) .culling(false) .receiveShadows(false) .castShadows(false) .build(*engine, app.renderable); + + + RenderableManager::Builder(1) + .boundingBox({{ -1, -1, -1 }, { 1, 1, 1 }}) + .material(0, inst2) + .geometry(0, RenderableManager::PrimitiveType::TRIANGLES, app.vb2, app.ib, 0, 3) + .culling(false) + .receiveShadows(false) + .castShadows(false) + .build(*engine, app.r2); + scene->addEntity(app.renderable); + + + auto r1inst = renderableMan.getInstance(app.renderable); + renderableMan.setPriority(r1inst, 7); + + scene->addEntity(app.r2); + auto r2inst = renderableMan.getInstance(app.r2); + renderableMan.setPriority(r2inst, 6); + app.camera = utils::EntityManager::get().create(); app.cam = engine->createCamera(app.camera); view->setCamera(app.cam); }; auto cleanup = [&app](Engine* engine, View*, Scene*) { - engine->destroy(app.skybox); +// engine->destroy(app.skybox); engine->destroy(app.renderable); engine->destroy(app.mat); engine->destroy(app.vb); @@ -174,19 +241,24 @@ int main(int argc, char** argv) { }; FilamentApp::get().animate([&app](Engine* engine, View* view, double now) { - constexpr float ZOOM = 1.5f; + constexpr float ZOOM = 1.5; const uint32_t w = view->getViewport().width; const uint32_t h = view->getViewport().height; const float aspect = (float) w / h; app.cam->setProjection(Camera::Projection::ORTHO, -aspect * ZOOM, aspect * ZOOM, - -ZOOM, ZOOM, 0, 1); + -ZOOM, ZOOM, -100, 100); auto& tcm = engine->getTransformManager(); tcm.setTransform(tcm.getInstance(app.renderable), filament::math::mat4f::rotation(now, filament::math::float3{ 0, 0, 1 })); }); - FilamentApp::get().run(app.config, setup, cleanup); + + auto preRender = [](Engine*, View* view, Scene*, Renderer* renderer) { + renderer->setClearOptions({ .clearStencil = 0u, .clear = true }); + }; + + FilamentApp::get().run(app.config, setup, cleanup, {}, preRender); return 0; }