0

I loaded a model using tinyobjloader in a Vulkan application. The color of each vertex simply equals its 3d position. Using RenderDoc I verified that the depth buffer is working correctly:

enter image description here

But the color output shows some weird artifacts where you see vertices that are occluded:

enter image description here

This is how the artifacts look when using phong lighting:

enter image description here

  • Face orientation and culling is correct
  • I've tried both SRGB and SFLOAT image formats, both yield the same results
  • I don't explicitly transition the layouts (and thus don't change the access masks using VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT) but let the subpasses take care of it

Since Vulkan code is commonly very long, I've created a gist so you can look at the main application code. Let me know if you need to see more.

6
  • What happens if you try VK_CULL_MODE_NONE? Commented Apr 26, 2020 at 15:48
  • Crossposted at reddit.com/r/vulkan/comments/g8eamw/… Commented Apr 26, 2020 at 15:58
  • @krOoze same artifacts when using no culling Commented Apr 26, 2020 at 16:02
  • Also try disabling blending. Commented Apr 26, 2020 at 16:02
  • @krOoze Disabling blending works! Thank you! Why am I not supposed to use color blending here? (eSrcColor and eOneMinusSrcColor for the source and destination color respectively. And one and zero for the alpha values.) Commented Apr 26, 2020 at 16:11

1 Answer 1

1

Color blending is order dependent operation, and so tricky when used with depth buffering.

Your code is:

vk::PipelineColorBlendAttachmentState colorBlendAttachment(true,
vk::BlendFactor::eSrcColor, vk::BlendFactor::eOneMinusSrcColor,
vk::BlendOp::eAdd,
vk::BlendFactor::eOne, vk::BlendFactor::eZero,
vk::BlendOp::eAdd,

Primitives (triangles) are processed in primitime order. Here notably, the triangle that is first in your index buffer will be processed first.

Now, as depth testing works is that a fragment proceeds if it passes the depth test. That means one fragment could suceed. Then other fragment with even better depth value could overwrite it.

This affects your Dst blend value. In your case it will either be the clear color, or the previous fragment color, depending on whichever happens first, per the primitive order.

Your blend op is srcColor * srcColor + dstColor * (1-srcColor). If your previous color is 0, then it results in 2*srcColor, which is probably non-sense, but not noticable. But if dstColor is something, then your output becomes some bright artifact color with more of a Dst's tint.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.