Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question Unity crashes when running effect

Discussion in 'General Graphics' started by MatheusMarkies, Jun 28, 2021.

  1. MatheusMarkies

    MatheusMarkies

    Joined:
    Apr 16, 2017
    Posts:
    67
    I'm studying path tracing, at the moment I created a compute shader that aims to calculate the intersection of rays with meshes.
    However, when I run the code the unity crashes, displaying a graphics card error.

    The error is in the detection of intersection with the meshes.
    When I put the lines of code responsible for writing a new ray.

    But I'm not managing to fix it. I also don't understand if it could be a problem with my video card or my code.
    I tested it with only 1 mesh triangle and got a lot of lag.

    To send the vertices to the video card I did the following. I got the stitches from the scene. Then I took the indices and vertices arrays and merged them with the other meshes.

    Code (CSharp):
    1.  
    2. public void buildObjectList()
    3.         {
    4.             int indicesCount = 0;
    5.             int verticesCount = 0;
    6.  
    7.             foreach (PathTracingObject pto in pathTracingObjects)
    8.             {
    9.                 int[] triangles;
    10.                 Vector3[] vertices;
    11.  
    12.                 triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
    13.                 vertices = pto.objectMesh.vertices;//Take vertex list
    14.  
    15.                 pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
    16.                 pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.
    17.  
    18.                 foreach (Vector3 vertice in vertices)
    19.                     this.vertices.Add(vertice);
    20.  
    21.                 for (int i = 0; i < triangles.Length; i++)
    22.                 {
    23.                     this.indices.Add(triangles[i] + verticesCount + 1);//Variable containing all indices of all objects in the scene. | triangles[i] (take an index) +verticesCount(Add to the amount of vetices already added) + 1
    24.  
    25.                     /*Example:
    26.                     If the previous object has 270 vertices.
    27.                     The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
    28.                     +1 because vertex 270 belongs to a different object.*/
    29.                 }
    30.  
    31.                 indicesCount += triangles.Length;//update index
    32.                 verticesCount += vertices.Length;//update index
    33.             }
    34.         }
    35.  
    In compute shader:

    Code (CSharp):
    1.  
    2. /*
    3. http://www.graphics.cornell.edu/pubs/1997/MT97.html
    4. https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
    5. */
    6. bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
    7. {
    8.     float3 edge1 = vert1 - vert0;
    9.     float3 edge2 = vert2 - vert0;
    10.     float3 pvec = cross(ray.rayDirection, edge2);
    11.     float det = dot(edge1, pvec);
    12.     if (det < EPSILON)
    13.         return false;
    14.     float inv_det = 1.0f / det;
    15.     float3 tvec = ray.raySource - vert0;
    16.     u = dot(tvec, pvec) * inv_det;
    17.     if (u < 0.0 || u > 1.0f)
    18.         return false;
    19.     float3 qvec = cross(tvec, edge1);
    20.     v = dot(ray.rayDirection, qvec) * inv_det;
    21.     if (v < 0.0 || u + v > 1.0f)
    22.         return false;
    23.     t = dot(edge2, qvec) * inv_det;
    24.     return true;
    25. }
    26.  
    Code (CSharp):
    1.  
    2. void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
    3. {
    4.     for (int i = 0; i < pto.indicesCount; i += 3) {
    5.         float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
    6.         float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
    7.         float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;
    8.  
    9.         float t, u, v;
    10.         if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
    11.         {
    12.             if (t > 0 && t < bestHit.hitDistance)
    13.             {
    14.                 /*            
    15.                 bestHit.hitDistance = t; // makes unity crash
    16.                 bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
    17.                 bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash
    18.  
    19.                 bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
    20.                 */
    21.             }
    22.         }
    23.    
    Crash.PNG

    Message information: We detected driver timeout on your system. A bug report was generated. this report can help AMD resolve the issue.

    Full code:
    Code (CSharp):
    1.  
    2. // Each #kernel tells which function to compile; you can have many kernels
    3. #pragma kernel CSMain
    4.  
    5. #define PI 3.14159265359
    6. #define EPSILON 0.0000001
    7.  
    8. RWTexture2D<float4> Result;
    9.  
    10. struct pathTracingObject
    11. {
    12.     float4 Position;
    13.  
    14.     int indicesCount;
    15.     int indicesOffset;
    16.  
    17.     float4x4 localToWorldMatrix;
    18. };
    19.  
    20. StructuredBuffer<pathTracingObject> _pathTracingObject;
    21. StructuredBuffer<float3> _Vertices;
    22. StructuredBuffer<int> _Indices;
    23.  
    24. int _pathTracingObjectCount;
    25.  
    26. float4x4 _CameraToWorld;
    27. float4x4 _CameraInverseProjection;
    28.  
    29. struct Ray {
    30.     float3 raySource;
    31.     float3 rayDirection;
    32.     float3 rayColor;
    33. };
    34.  
    35. Ray CreateRay(float3 source, float3 direction)
    36. {
    37.     Ray ray;
    38.     ray.raySource = source;
    39.     ray.rayDirection = direction;
    40.  
    41.     return ray;
    42. }
    43.  
    44. Ray CreateCameraRay(float2 uv)
    45. {
    46.     float3 source = mul(_CameraToWorld, float4(0.0f, 0.0f, 0.0f, 1.0f)).xyz;
    47.  
    48.     float3 direction = mul(_CameraInverseProjection, float4(uv, 0.0f, 1.0f)).xyz;
    49.     direction = mul(_CameraToWorld, float4(direction, 0.0f)).xyz;
    50.     direction = normalize(direction);
    51.     return CreateRay(source, direction);
    52. }
    53.  
    54. struct RayHit
    55. {
    56.     float3 hitPosition;
    57.     float hitDistance;
    58.     float3 hitNormal;
    59.  
    60.     float3 hitAlbedo;
    61. };
    62.  
    63. RayHit CreateRayHit()
    64. {
    65.     RayHit hit;
    66.  
    67.     hit.hitPosition = float3(0.0f, 0.0f, 0.0f);
    68.     hit.hitDistance = 1.#INF;
    69.     hit.hitNormal = float3(0.0f, 0.0f, 0.0f);
    70.  
    71.     hit.hitAlbedo = float3(0.0f, 0.0f, 0.0f);
    72.  
    73.     return hit;
    74. }
    75.  
    76. /*
    77. http://www.graphics.cornell.edu/pubs/1997/MT97.html
    78. https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
    79. */
    80. bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
    81. {
    82.     float3 edge1 = vert1 - vert0;
    83.     float3 edge2 = vert2 - vert0;
    84.     float3 pvec = cross(ray.rayDirection, edge2);
    85.     float det = dot(edge1, pvec);
    86.     if (det < EPSILON)
    87.         return false;
    88.     float inv_det = 1.0f / det;
    89.     float3 tvec = ray.raySource - vert0;
    90.     u = dot(tvec, pvec) * inv_det;
    91.     if (u < 0.0 || u > 1.0f)
    92.         return false;
    93.     float3 qvec = cross(tvec, edge1);
    94.     v = dot(ray.rayDirection, qvec) * inv_det;
    95.     if (v < 0.0 || u + v > 1.0f)
    96.         return false;
    97.     t = dot(edge2, qvec) * inv_det;
    98.     return true;
    99. }
    100.  
    101.  
    102. void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
    103. {
    104.     for (int i = 0; i < pto.indicesCount; i += 3) {
    105.         float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
    106.         float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
    107.         float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;
    108.  
    109.         float t, u, v;
    110.         if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
    111.         {
    112.             if (t > 0 && t < bestHit.hitDistance)
    113.             {
    114.                            
    115.                 bestHit.hitDistance = t; // makes unity crash
    116.                 bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
    117.                 bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash
    118.  
    119.                 bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
    120.              
    121.             }
    122.         }
    123.  
    124.     }
    125. }
    126.  
    127. RayHit Trace(Ray ray)
    128. {
    129.     RayHit bestHit = CreateRayHit();
    130.  
    131.     for (int i = 0; i < _pathTracingObjectCount; i++) {
    132.         pathTracingObject pto = _pathTracingObject[i];
    133.         IntersectMeshObject(pto, ray, bestHit);
    134.     }
    135.  
    136.     return bestHit;
    137. }
    138.  
    139. [numthreads(8,8,1)]
    140. void CSMain (uint3 id : SV_DispatchThreadID)
    141. {
    142.     // TODO: insert actual code here!
    143.     float3 result = float3(0, 0, 0);
    144.  
    145.     int width, height;
    146.     Result.GetDimensions(width, height);
    147.     float2 uv = float2((id.xy + float2(0.5f, 0.5f)) / float2(width, height) * 2.0f - 1.0f);
    148.  
    149.     for(int i = 0; i < 1;i++) {
    150.         Ray ray = CreateCameraRay(id.xy);
    151.         RayHit hit = Trace(ray);
    152.         result += hit.hitAlbedo;
    153.     }
    154.     result /= float3(5,5,5);
    155.  
    156.     Result[id.xy] = float4(result, 1);
    157. }
    158.  
    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.Rendering;
    6.  
    7. [System.Serializable]
    8. class PathTracing
    9. {
    10.  
    11.     [SerializeField]
    12.     ComputeShader computeShader;
    13.     [SerializeField]
    14.     GameObject[] pathTracingObjects;
    15.    
    16.     class PathTracingComputeShader
    17.     {
    18.         PathTracingObject[] pathTracingObjects;
    19.  
    20.         public List<Vector3> vertices = new List<Vector3>();
    21.         public List<int> indices = new List<int>();
    22.  
    23.         RenderTexture RT;
    24.         public void loadRenderTexture()
    25.         {
    26.             RT = new RenderTexture(Mathf.CeilToInt(Screen.width / 4), Mathf.CeilToInt(Screen.height / 4), 0, RenderTextureFormat.DefaultHDR);
    27.             RT.enableRandomWrite = true;
    28.             RT.Create();
    29.         }
    30.         public RenderTexture OnRenderComputeShader(ComputeShader computeShader)
    31.         {
    32.             loadRenderTexture();
    33.  
    34.             #region Mesh Forwarding
    35.  
    36.             computeShader.SetInt("_pathTracingObjectCount", pathTracingObjects.Length);
    37.  
    38.             foreach (PathTracingObject pto in pathTracingObjects)
    39.                pto.OnExecutePathTracing();
    40.  
    41.             buildObjectList();
    42.  
    43.             ComputeBuffer objectsBuffer = new ComputeBuffer(pathTracingObjects.Length, 88) { name = "Scenes Objects Buffer" };
    44.             ComputeBuffer vertexBuffer = new ComputeBuffer(vertices.Count, 12) { name = "Vertices Buffer" };
    45.             ComputeBuffer indexBuffer = new ComputeBuffer(indices.Count, 4) { name = "Indices Buffer" };
    46.  
    47.             PathTracingObject.pathTracingObject[] sceneObjects = new PathTracingObject.pathTracingObject[pathTracingObjects.Length];
    48.             for (int i = 0; i < pathTracingObjects.Length; i++)
    49.             {
    50.                 sceneObjects[i] = pathTracingObjects[i]._pathTracingObject;
    51.             }
    52.  
    53.             objectsBuffer.SetData(sceneObjects);
    54.             vertexBuffer.SetData(vertices);
    55.             indexBuffer.SetData(indices);
    56.  
    57.             computeShader.SetBuffer(0, "_pathTracingObject", objectsBuffer);
    58.             computeShader.SetBuffer(0, "_Vertices", vertexBuffer);
    59.             computeShader.SetBuffer(0, "_Indices", indexBuffer);
    60.             #endregion
    61.  
    62.             computeShader.SetMatrix("_CameraToWorld", Camera.main.cameraToWorldMatrix);
    63.             computeShader.SetMatrix("_CameraInverseProjection", Camera.main.projectionMatrix.inverse);
    64.  
    65.             computeShader.SetTexture(0, "Result", RT);
    66.             computeShader.Dispatch(0, RT.width, RT.height, 24);
    67.  
    68.             return RT;
    69.         }
    70.         public void buildObjectList()
    71.         {
    72.             int indicesCount = 0;
    73.             int verticesCount = 0;
    74.  
    75.             foreach (PathTracingObject pto in pathTracingObjects)
    76.             {
    77.                 int[] triangles;
    78.                 Vector3[] vertices;
    79.  
    80.                 triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
    81.                 vertices = pto.objectMesh.vertices;//Take vertex list
    82.  
    83.                 pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
    84.                 pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.
    85.  
    86.                 foreach (Vector3 vertice in vertices)
    87.                     this.vertices.Add(vertice);
    88.  
    89.                 for (int i = 0; i < triangles.Length; i++)
    90.                 {
    91.                     this.indices.Add(triangles[i] + verticesCount + 1);//Variable containing all indices of all objects in the scene. | triangles[i] (take an index) +verticesCount(Add to the amount of vetices already added) + 1
    92.  
    93.                     /*Example:
    94.                     If the previous object has 270 vertices.
    95.                     The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
    96.                     +1 because vertex 270 belongs to a different object.*/
    97.                 }
    98.  
    99.                 indicesCount += triangles.Length;//update index
    100.                 verticesCount += vertices.Length;//update index
    101.             }
    102.         }
    103.         public void setPathTracingObjects(PathTracingObject[] pto) { pathTracingObjects = pto; }
    104.     }
    105.     public RenderTexture preProcessing()
    106.     {
    107.         PathTracingComputeShader pathTracingCompute = new PathTracingComputeShader();
    108.  
    109.         PathTracingObject[] objs = new PathTracingObject[pathTracingObjects.Length];
    110.         for (int i = 0; i < pathTracingObjects.Length; i++)
    111.             objs[i] = pathTracingObjects[i].GetComponent<PathTracingObject>();
    112.  
    113.         pathTracingCompute.setPathTracingObjects(objs);
    114.         return pathTracingCompute.OnRenderComputeShader(computeShader);
    115.     }
    116. }
    117.  
    I believe it could be 2 things.
    Or my video card doesn't count for work.
    Or there is a problem with the vertex array.
    (index out of range maybe?)

    But I'm not sure, since it just crashes without an error message or something.