GithubHelp home page GithubHelp logo

Comments (5)

mklefrancois avatar mklefrancois commented on August 25, 2024

Hi @richardeakin,

Make sure the hitGroupId uses the proper Hit Group Shaders for the implicit objects. In createTopLevelAS() you are setting the value to 0, which in incorrect in this case. Check that all BLAS containing implicit objects are using the Hit Group 1 or the one associated with the Group (Hit, Intersection, AnyHit) you create in the SBT, which I haven't see it done.

from vk_raytracing_tutorial_khr.

richardeakin avatar richardeakin commented on August 25, 2024

Thanks for taking a look at this! I believe I am adding the implicit objects to the TLAS with hit group = 1 here, this is what you're referring to right?

The link is a convenient place to ask you though, the line before seems like it could be the problem - does it make sense that the blasId for the implicit BLAS is m_gltfScene.m_primMeshes.size()? I haven't been able to reconcile in my mind how to deal with glTF scenes that have more nodes than meshes. For example taking cornellBox.gltf as used in the tutorial code, there are 9 primMeshes and thus 9 BLAS added in createBottomLevelAS(), and then in createTopLevelAS() there are 10 nvvk::RaytracingBuilderKHR::Instances added to the TLAS corresponding to the 10 scene nodes (the two spheres reuse the same mesh).

I thought this was the issue as Suzanne.gltf has only one node and one mesh and it worked, but then this was squashed when I tried Box.gltf which as is 1:1 nodes:meshes and it has the same problems as cornellBox.gltf. Thanks again for any tips on solving this, it is driving me a bit nuts!

For convenience I've pasted my updated version of these functions here:

void HelloVulkan::createBottomLevelAS()
{
    // BLAS - Storing each primitive in a geometry
    std::vector<nvvk::RaytracingBuilderKHR::BlasInput> allBlas;
    allBlas.reserve(m_gltfScene.m_primMeshes.size());
    for(auto& primMesh : m_gltfScene.m_primMeshes)
    {
        auto geo = primitiveToGeometry(primMesh);
        allBlas.push_back({geo});
    }

    // Implicits
    {
        auto blas = sphereToVkGeometryKHR();
        allBlas.emplace_back(blas);
    }

    m_rtBuilder.buildBlas(allBlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
}

void HelloVulkan::createTopLevelAS()
{
    std::vector<nvvk::RaytracingBuilderKHR::Instance> tlas;
    tlas.reserve(m_gltfScene.m_nodes.size());
    uint32_t instID = 0;
    for(auto& node : m_gltfScene.m_nodes)
    {
        nvvk::RaytracingBuilderKHR::Instance rayInst;
        rayInst.transform        = node.worldMatrix;
        rayInst.instanceCustomId = node.primMesh;  // gl_InstanceCustomIndexEXT: to find which primitive
        rayInst.blasId           = node.primMesh;
        rayInst.flags            = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
        rayInst.hitGroupId       = 0;  // We will use the same hit group for all objects
        tlas.emplace_back(rayInst);
    }

    // Add the blas containing all implicits
    {
        nvvk::RaytracingBuilderKHR::Instance rayInst;
        rayInst.transform  = m_gltfScene.m_nodes[0].worldMatrix;          // Position of the instance
        rayInst.instanceCustomId = static_cast<uint32_t>(tlas.size());  // gl_InstanceID
        //rayInst.blasId     = static_cast<uint32_t>(m_gltfScene.m_nodes.size());
        rayInst.blasId     = static_cast<uint32_t>(m_gltfScene.m_primMeshes.size()); // TODO: this is hacky, assign blasId from createBottomLevelAS()
        rayInst.hitGroupId = 1;  // We will use the same hit group for all objects
        rayInst.flags      = VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR;
        tlas.emplace_back(rayInst);
    }

    m_rtBuilder.buildTlas(tlas, vk::BuildAccelerationStructureFlagBitsKHR::ePreferFastTrace);
}

from vk_raytracing_tutorial_khr.

mklefrancois avatar mklefrancois commented on August 25, 2024

I think you are not setting the right instance matrix for the implicit surface

Can you try replacing:

rayInst.transform = m_gltfScene.m_nodes[0].worldMatrix;  // Position of the instance

with

rayInst.transform = nvmath::mat4(1);                     // Position of the instance

from vk_raytracing_tutorial_khr.

mklefrancois avatar mklefrancois commented on August 25, 2024

Hi, I took a bit of time looking into the issue. I was not able to re-use your example, but I have made a similar example starting with the glTF sample and adding the intersection code. I was able to see a similar artifacts when the matrix for the implicit surfaces was not identity. This makes sense, because the hitT is incorrectly calculated in the intersection shader.

Regarding the number of BLAS, it is m_gltfScene.m_primMeshes.size(). If the implicit surfaces are added after all glTF primitives, the blasId will be static_cast<uint32_t>(m_gltfScene.m_primMeshes.size()).

Here is a modified version of the glTF. Sorry, it uses share code that is not yet on GitHub, but it should be easy to adapt.
ray_tracing_gltf.zip

Note that this glTF example uses a very simple shading model. For a more complete PBR shading, I have wrote a separated example: https://github.com/nvpro-samples/vk_raytrace

from vk_raytracing_tutorial_khr.

richardeakin avatar richardeakin commented on August 25, 2024

Ah, of course! That's what I get for blindly copying the sample code. I imagine then this line should also be nvmath::mat4(1), though it doesn't matter with the objs since their transform was always identity.

After I read your diagnose of the bug, I've been having a go at enabling those TLAS-level transforms since that seems useful for building up larger scenes based on the "Ray Intersection with Transformed Objects" chapter in Suffern's "Ray Tracing from the Ground Up", working well! No transform:

image

rayInst.transform = nvmath::translation_mat4( nvmath::vec3f( 0, 2, 0 ) ) * nvmath::scale_mat4( nvmath::vec3f( 2 ) );

image

I'm working toward your vk_raytrace, looking forward to it! But also being able to raytrace some things procedurally was very important to me, so I'm happy that I finally have a solution for this bug I was stuck on. Thanks so much!

from vk_raytracing_tutorial_khr.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.