Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Question Lidar Ray Tracing Problem

Discussion in 'HDRP Ray Tracing' started by Fishing602, Oct 19, 2023.

  1. Fishing602

    Fishing602

    Joined:
    Sep 5, 2023
    Posts:
    1
    Hi forum,

    I am doing a Lidar Simulation on Unity currently and I'm facing a problem, which made me feel really confused.
    In Lidar simulation, the Lidar rotates and dispatches rays, my goal is to generate a point cloud after scanning, here I use red balls to represent points.

    The Problem is why the rays I visualized do not stop at hit points but go through objects?
    Do I need to add a shader to every scanned object to achieve the goal?


    I used Debug.DrawRay to show ray directions (blue) in scene, and I also checked the colliders of surrounding objects, but it did not help. In C# script I added all objects in scene to RayTracingAccelerationStructure and set pool for balls, which represents the hit points in order to visualize the point cloud.

    Here are the screenshots of my project, it shows that rays go through objects:
    upload_2023-10-19_17-19-54.png
    upload_2023-10-19_17-26-13.png

    Also I upload the c# scripts and shader here in attachment.

    The .raytrace file can't be uploaded so I post it here in text (hlsl code, not csharp):

    Code (CSharp):
    1. // LiDARRayTracingShader.raytrace
    2.  
    3. #pragma raytracing
    4.  
    5.  
    6.  
    7. // Accelerated structure declaration
    8. RaytracingAccelerationStructure _AccelerationStructure : register(t0);
    9.  
    10. // Input and output structure
    11. struct RayGenInput
    12. {
    13.     float3 RayOrigin : ORIGIN;
    14.     float3 RayDirection : DIRECTION;
    15. };
    16.  
    17. struct RayGenOutput
    18. {
    19.     float3 HitPoint : SV_Position;
    20. };
    21.  
    22. struct Attributes
    23. {
    24.     float2 barycentrics;
    25. };
    26.  
    27. struct RayPayload
    28. {
    29.     float HitDistance;
    30.     float3 HitColor;
    31.     float3 color;
    32.     float t;
    33. };
    34.  
    35. // global variable
    36. float _MaxDistance;
    37. int _NumberOfRays;
    38. float3 _RayOrigin;
    39. float3 _BackgroundColor = float3(0.5, 0.5, 0.5);
    40. RWStructuredBuffer<float3> _HitPoints;
    41.  
    42.  
    43. // Ray generation shader
    44. [shader("raygeneration")]
    45. void RaygenLiDAR()
    46. {
    47.     uint2 launchIndex = DispatchRaysIndex().xy;
    48.  
    49.     // Calculate ray direction
    50.     float angle = 2.0f * 3.14159265359f * (launchIndex.x / (float)_NumberOfRays);
    51.     float3 direction = float3(cos(angle), 0, sin(angle));
    52.  
    53.     // Initialising the light payload
    54.     RayPayload payload;
    55.     payload.HitDistance = -1; // An initial value of -1 indicates a miss
    56.     payload.HitColor = _BackgroundColor; // Initial colour is the background colour
    57.  
    58.     // send out rays
    59.     RayDesc ray = { _RayOrigin, 0, direction, _MaxDistance }; // Use the default ray starting point
    60.     TraceRay(_AccelerationStructure, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, 0xFF, 0, 1, 0, ray, payload);
    61.  
    62.     // Processing results based on payload
    63.     if (payload.HitDistance > 0)
    64.     {
    65.         float3 hitPoint = float3(0,0,0) + direction * payload.HitDistance;
    66.         _HitPoints[launchIndex.x] = hitPoint;
    67.     }
    68.     else
    69.     {
    70.         _HitPoints[launchIndex.x] = float3(0, -1000, 0); // Use an invalid value to indicate no hit
    71.     }
    72. }
    73.  
    74. // Miss shader
    75. [shader("miss")]
    76. void MissShader(inout RayPayload payload)
    77. {
    78.     // when the ray does not hit any object(
    79.     payload.HitDistance = -1;
    80.     payload.HitColor = _BackgroundColor;
    81.    
    82. }
    83.  
    84.  
    85. // Closest hit shader
    86. [shader("closesthit")]
    87. void ClosestHit(inout RayPayload payload, Attributes attrib)
    88. {
    89.     payload.color = float3(1, 0, 0); // red
    90.     payload.HitDistance = payload.t; // Store the intersection distance
    91.    
    92. }

    Thank you for reading this and any advice would be useful for me!
     

    Attached Files:

  2. INedelcu

    INedelcu

    Unity Technologies

    Joined:
    Jul 14, 2015
    Posts:
    173
    Hi!

    The .raytrace file is the right place to write the raygeneration shader. This file doesn't deal with intersection shading code, only with generating primary rays and also miss shaders executed when a ray doesn't hit anything, thus it doesn't support hit shaders.

    The .shader file is where hit shaders code must be placed because that shader is attached to geometries that rays intersect but it doesn't make sense to write raygeneration or miss shaders there.

    You don't have to declare the register when declaring RaytracingAccelerationStructures in shader code. The registers are assigned automatically by the shader compiler.

    In your .cs file you don't actually do any ray tracing. You need to call RayTracingShader.Dispatch somewhere after setting all the input (_AccelerationStructure) and output (_HitPoints) and other shader variables that you use.

    // Dispatch the rays for each rotation step
    Graphics.Blit(null, lidarMaterial, 0);

    This doesn't dispatch any rays!

    Make sure to select the correct Shader Pass to execute when rays intersect geometries. This is done using RayTracingShader.SetShaderPass or CommandBuffer.SetRayTracingShaderPass if you use command buffers. You need to call this before the dispatch rays call.

    Shader "Custom/LiDARRayTracing"
    {
    SubShader
    {
    Pass
    {
    Name "RayTracing"

    In your case the shader pass is called RayTracing.

    Here's a simple example of dispatching rays into a scene. The example just retrieves the geometry world normal at the intersection point and outputs that to the screen https://github.com/INedelcu/RayTracingShader_VertexAttributeInterpolation There's a .raytrace shader and a classic .shader file with a closest hit shader inside. This is used by all the geometries in the scene.
     
    chap-unity likes this.