<p>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.</p>
<p>The error is in the detection of intersection with the meshes.
When I put the lines of code responsible for writing a new ray.</p>
<p>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.</p>
<p>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.</p>
<pre><code>public void buildObjectList()
        {
            int indicesCount = 0;
            int verticesCount = 0;

            foreach (PathTracingObject pto in pathTracingObjects)
            {
                int[] triangles;
                Vector3[] vertices;

                triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
                vertices = pto.objectMesh.vertices;//Take vertex list

                pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
                pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.

                foreach (Vector3 vertice in vertices)
                    this.vertices.Add(vertice);

                for (int i = 0; i &lt; triangles.Length; i++)
                {
                    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

                    /*Example:
                    If the previous object has 270 vertices.
                    The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
                    +1 because vertex 270 belongs to a different object.*/
                }

                indicesCount += triangles.Length;//update index
                verticesCount += vertices.Length;//update index
            }
        }
</code></pre>
<p>In compute shader:</p>
<pre><code>/*
http://www.graphics.cornell.edu/pubs/1997/MT97.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
*/
bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
{
    float3 edge1 = vert1 - vert0;
    float3 edge2 = vert2 - vert0;
    float3 pvec = cross(ray.rayDirection, edge2);
    float det = dot(edge1, pvec);
    if (det &lt; EPSILON)
        return false;
    float inv_det = 1.0f / det;
    float3 tvec = ray.raySource - vert0;
    u = dot(tvec, pvec) * inv_det;
    if (u &lt; 0.0 || u &gt; 1.0f)
        return false;
    float3 qvec = cross(tvec, edge1);
    v = dot(ray.rayDirection, qvec) * inv_det;
    if (v &lt; 0.0 || u + v &gt; 1.0f)
        return false;
    t = dot(edge2, qvec) * inv_det;
    return true;
}


void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
{
    for (int i = 0; i &lt; pto.indicesCount; i += 3) {
        float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
        float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
        float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;

        float t, u, v;
        if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
        {
            if (t &gt; 0 &amp;&amp; t &lt; bestHit.hitDistance)
            {
                /*           
                bestHit.hitDistance = t; // makes unity crash
                bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
                bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash

                bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
                */
            }
        }
</code></pre>
<p><a href="https://i.sstatic.net/OYL2N.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/OYL2N.png" alt="enter image description here" /></a></p>
<p>Message information: We detected driver timeout on your system. A bug report was generated. this report can help AMD resolve the issue.</p>
<p>Full code:</p>
<pre><code>// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

#define PI 3.14159265359
#define EPSILON 0.0000001

RWTexture2D&lt;float4&gt; Result;

struct pathTracingObject
{
    float4 Position;

    int indicesCount;
    int indicesOffset;

    float4x4 localToWorldMatrix;
};

StructuredBuffer&lt;pathTracingObject&gt; _pathTracingObject;
StructuredBuffer&lt;float3&gt; _Vertices;
StructuredBuffer&lt;int&gt; _Indices;

int _pathTracingObjectCount;

float4x4 _CameraToWorld;
float4x4 _CameraInverseProjection;
 
struct Ray {
    float3 raySource;
    float3 rayDirection;
    float3 rayColor;
};

Ray CreateRay(float3 source, float3 direction)
{
    Ray ray;
    ray.raySource = source;
    ray.rayDirection = direction;

    return ray;
}

Ray CreateCameraRay(float2 uv)
{
    float3 source = mul(_CameraToWorld, float4(0.0f, 0.0f, 0.0f, 1.0f)).xyz;

    float3 direction = mul(_CameraInverseProjection, float4(uv, 0.0f, 1.0f)).xyz;
    direction = mul(_CameraToWorld, float4(direction, 0.0f)).xyz;
    direction = normalize(direction);
    return CreateRay(source, direction);
}

struct RayHit
{
    float3 hitPosition;
    float hitDistance;
    float3 hitNormal;

    float3 hitAlbedo;
};

RayHit CreateRayHit()
{
    RayHit hit;

    hit.hitPosition = float3(0.0f, 0.0f, 0.0f);
    hit.hitDistance = 1.#INF;
    hit.hitNormal = float3(0.0f, 0.0f, 0.0f);

    hit.hitAlbedo = float3(0.0f, 0.0f, 0.0f);

    return hit;
}

/*
http://www.graphics.cornell.edu/pubs/1997/MT97.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
*/
bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
{
    float3 edge1 = vert1 - vert0;
    float3 edge2 = vert2 - vert0;
    float3 pvec = cross(ray.rayDirection, edge2);
    float det = dot(edge1, pvec);
    if (det &lt; EPSILON)
        return false;
    float inv_det = 1.0f / det;
    float3 tvec = ray.raySource - vert0;
    u = dot(tvec, pvec) * inv_det;
    if (u &lt; 0.0 || u &gt; 1.0f)
        return false;
    float3 qvec = cross(tvec, edge1);
    v = dot(ray.rayDirection, qvec) * inv_det;
    if (v &lt; 0.0 || u + v &gt; 1.0f)
        return false;
    t = dot(edge2, qvec) * inv_det;
    return true;
}


void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
{
    for (int i = 0; i &lt; pto.indicesCount; i += 3) {
        float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
        float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
        float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;

        float t, u, v;
        if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
        {
            if (t &gt; 0 &amp;&amp; t &lt; bestHit.hitDistance)
            {
                           
                bestHit.hitDistance = t; // makes unity crash
                bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
                bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash

                bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
             
            }
        }

    }
}

RayHit Trace(Ray ray)
{
    RayHit bestHit = CreateRayHit();

    for (int i = 0; i &lt; _pathTracingObjectCount; i++) {
        pathTracingObject pto = _pathTracingObject[i];
        IntersectMeshObject(pto, ray, bestHit);
    }

    return bestHit;
}

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!
    float3 result = float3(0, 0, 0);

    int width, height;
    Result.GetDimensions(width, height);
    float2 uv = float2((id.xy + float2(0.5f, 0.5f)) / float2(width, height) * 2.0f - 1.0f);

    for(int i = 0; i &lt; 1;i++) {
        Ray ray = CreateCameraRay(id.xy);
        RayHit hit = Trace(ray);
        result += hit.hitAlbedo;
    }
    result /= float3(5,5,5);

    Result[id.xy] = float4(result, 1);
}
</code></pre>
<p>C#</p>
<pre><code>using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

[System.Serializable]
class PathTracing
{
 
    [SerializeField]
    ComputeShader computeShader;
    [SerializeField]
    GameObject[] pathTracingObjects;
  
    class PathTracingComputeShader
    {
        PathTracingObject[] pathTracingObjects;

        public List&lt;Vector3&gt; vertices = new List&lt;Vector3&gt;();
        public List&lt;int&gt; indices = new List&lt;int&gt;();

        RenderTexture RT;
        public void loadRenderTexture()
        {
            RT = new RenderTexture(Mathf.CeilToInt(Screen.width / 4), Mathf.CeilToInt(Screen.height / 4), 0, RenderTextureFormat.DefaultHDR);
            RT.enableRandomWrite = true;
            RT.Create();
        }
        public RenderTexture OnRenderComputeShader(ComputeShader computeShader)
        {
            loadRenderTexture();

            #region Mesh Forwarding

            computeShader.SetInt(&quot;_pathTracingObjectCount&quot;, pathTracingObjects.Length);

            foreach (PathTracingObject pto in pathTracingObjects)
               pto.OnExecutePathTracing();

            buildObjectList();

            ComputeBuffer objectsBuffer = new ComputeBuffer(pathTracingObjects.Length, 88) { name = &quot;Scenes Objects Buffer&quot; };
            ComputeBuffer vertexBuffer = new ComputeBuffer(vertices.Count, 12) { name = &quot;Vertices Buffer&quot; };
            ComputeBuffer indexBuffer = new ComputeBuffer(indices.Count, 4) { name = &quot;Indices Buffer&quot; };

            PathTracingObject.pathTracingObject[] sceneObjects = new PathTracingObject.pathTracingObject[pathTracingObjects.Length];
            for (int i = 0; i &lt; pathTracingObjects.Length; i++)
            {
                sceneObjects[i] = pathTracingObjects[i]._pathTracingObject;
            }

            objectsBuffer.SetData(sceneObjects);
            vertexBuffer.SetData(vertices);
            indexBuffer.SetData(indices);

            computeShader.SetBuffer(0, &quot;_pathTracingObject&quot;, objectsBuffer);
            computeShader.SetBuffer(0, &quot;_Vertices&quot;, vertexBuffer);
            computeShader.SetBuffer(0, &quot;_Indices&quot;, indexBuffer);
            #endregion

            computeShader.SetMatrix(&quot;_CameraToWorld&quot;, Camera.main.cameraToWorldMatrix);
            computeShader.SetMatrix(&quot;_CameraInverseProjection&quot;, Camera.main.projectionMatrix.inverse);

            computeShader.SetTexture(0, &quot;Result&quot;, RT);
            computeShader.Dispatch(0, RT.width, RT.height, 24);

            return RT;
        }
        public void buildObjectList()
        {
            int indicesCount = 0;
            int verticesCount = 0;

            foreach (PathTracingObject pto in pathTracingObjects)
            {
                int[] triangles;
                Vector3[] vertices;

                triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
                vertices = pto.objectMesh.vertices;//Take vertex list

                pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
                pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.

                foreach (Vector3 vertice in vertices)
                    this.vertices.Add(vertice);

                for (int i = 0; i &lt; triangles.Length; i++)
                {
                    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

                    /*Example:
                    If the previous object has 270 vertices.
                    The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
                    +1 because vertex 270 belongs to a different object.*/
                }

                indicesCount += triangles.Length;//update index
                verticesCount += vertices.Length;//update index
            }
        }
        public void setPathTracingObjects(PathTracingObject[] pto) { pathTracingObjects = pto; }
    }
    public RenderTexture preProcessing()
    {
        PathTracingComputeShader pathTracingCompute = new PathTracingComputeShader();

        PathTracingObject[] objs = new PathTracingObject[pathTracingObjects.Length];
        for (int i = 0; i &lt; pathTracingObjects.Length; i++)
            objs[i] = pathTracingObjects[i].GetComponent&lt;PathTracingObject&gt;();

        pathTracingCompute.setPathTracingObjects(objs);
        return pathTracingCompute.OnRenderComputeShader(computeShader);
    }
}
</code></pre>
<p>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?)</p>
<p>But I'm not sure, since it just crashes without an error message or something.</p>

CC BY-SA 4.0
2021-07-01T11:17:47.890Z
GPU drivers have a timeout built into them, if a shader takes to long to execute then the driver automatically stops the shader which results in an error thrown to the program.  Just going from the text of the error message this could be your problem.
pmw1234
CC BY-SA 4.0
2021-07-01T13:49:47.453Z
Thanks for the answer! I was thinking it could be that, but is it a Shader error?
I believe that my video card is really the problem since I am using an R7 240 4Gb.
Matheus Markies
CC BY-SA 4.0
2021-07-01T14:10:28.147Z
The timeout isn't a shader error so much as it is the shader take to long to complete. The timeouts for a given shader execution are pretty short since the intent behind them is to run in parallel.  If it is timing out then either one of the loops is buggy and stuck, or are just plain doing to much work for you video card to handle for a single shader.  A faster/different video card might hide the issue for a time, but it will probably come up again if the underlying issue isn't resolved.
pmw1234
<pathtracing><compute-shader><unity>
Unity crashes when running path tracing
Matheus Markies
# Unity crashes when running path tracing

(Asked by: username_0 on 2021-06-28)

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.

```
public void buildObjectList()
        {
            int indicesCount = 0;
            int verticesCount = 0;

            foreach (PathTracingObject pto in pathTracingObjects)
            {
                int[] triangles;
                Vector3[] vertices;

                triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
                vertices = pto.objectMesh.vertices;//Take vertex list

                pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
                pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.

                foreach (Vector3 vertice in vertices)
                    this.vertices.Add(vertice);

                for (int i = 0; i < triangles.Length; i++)
                {
                    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

                    /*Example:
                    If the previous object has 270 vertices.
                    The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
                    +1 because vertex 270 belongs to a different object.*/
                }

                indicesCount += triangles.Length;//update index
                verticesCount += vertices.Length;//update index
            }
        }

```

In compute shader:

```
/*
http://www.graphics.cornell.edu/pubs/1997/MT97.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
*/
bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
{
    float3 edge1 = vert1 - vert0;
    float3 edge2 = vert2 - vert0;
    float3 pvec = cross(ray.rayDirection, edge2);
    float det = dot(edge1, pvec);
    if (det < EPSILON)
        return false;
    float inv_det = 1.0f / det;
    float3 tvec = ray.raySource - vert0;
    u = dot(tvec, pvec) * inv_det;
    if (u < 0.0 || u > 1.0f)
        return false;
    float3 qvec = cross(tvec, edge1);
    v = dot(ray.rayDirection, qvec) * inv_det;
    if (v < 0.0 || u + v > 1.0f)
        return false;
    t = dot(edge2, qvec) * inv_det;
    return true;
}

void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
{
    for (int i = 0; i < pto.indicesCount; i += 3) {
        float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
        float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
        float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;

        float t, u, v;
        if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
        {
            if (t > 0 && t < bestHit.hitDistance)
            {
                /*           
                bestHit.hitDistance = t; // makes unity crash
                bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
                bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash

                bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
                */
            }
        }

```

[![enter image description here](https://i.sstatic.net/OYL2N.png)](https://i.sstatic.net/OYL2N.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:

```
// Each #kernel tells which function to compile; you can have many kernels
#pragma kernel CSMain

#define PI 3.14159265359
#define EPSILON 0.0000001

RWTexture2D<float4> Result;

struct pathTracingObject
{
    float4 Position;

    int indicesCount;
    int indicesOffset;

    float4x4 localToWorldMatrix;
};

StructuredBuffer<pathTracingObject> _pathTracingObject;
StructuredBuffer<float3> _Vertices;
StructuredBuffer<int> _Indices;

int _pathTracingObjectCount;

float4x4 _CameraToWorld;
float4x4 _CameraInverseProjection;
 
struct Ray {
    float3 raySource;
    float3 rayDirection;
    float3 rayColor;
};

Ray CreateRay(float3 source, float3 direction)
{
    Ray ray;
    ray.raySource = source;
    ray.rayDirection = direction;

    return ray;
}

Ray CreateCameraRay(float2 uv)
{
    float3 source = mul(_CameraToWorld, float4(0.0f, 0.0f, 0.0f, 1.0f)).xyz;

    float3 direction = mul(_CameraInverseProjection, float4(uv, 0.0f, 1.0f)).xyz;
    direction = mul(_CameraToWorld, float4(direction, 0.0f)).xyz;
    direction = normalize(direction);
    return CreateRay(source, direction);
}

struct RayHit
{
    float3 hitPosition;
    float hitDistance;
    float3 hitNormal;

    float3 hitAlbedo;
};

RayHit CreateRayHit()
{
    RayHit hit;

    hit.hitPosition = float3(0.0f, 0.0f, 0.0f);
    hit.hitDistance = 1.#INF;
    hit.hitNormal = float3(0.0f, 0.0f, 0.0f);

    hit.hitAlbedo = float3(0.0f, 0.0f, 0.0f);

    return hit;
}

/*
http://www.graphics.cornell.edu/pubs/1997/MT97.html
https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/barycentric-coordinates
*/
bool IntersectTriangle(Ray ray, float3 vert0, float3 vert1, float3 vert2, inout float t, inout float u, inout float v)
{
    float3 edge1 = vert1 - vert0;
    float3 edge2 = vert2 - vert0;
    float3 pvec = cross(ray.rayDirection, edge2);
    float det = dot(edge1, pvec);
    if (det < EPSILON)
        return false;
    float inv_det = 1.0f / det;
    float3 tvec = ray.raySource - vert0;
    u = dot(tvec, pvec) * inv_det;
    if (u < 0.0 || u > 1.0f)
        return false;
    float3 qvec = cross(tvec, edge1);
    v = dot(ray.rayDirection, qvec) * inv_det;
    if (v < 0.0 || u + v > 1.0f)
        return false;
    t = dot(edge2, qvec) * inv_det;
    return true;
}

void IntersectMeshObject(pathTracingObject pto, Ray ray, inout RayHit bestHit)
{
    for (int i = 0; i < pto.indicesCount; i += 3) {
        float3 v0 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i]], 1))).xyz;
        float3 v1 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 1]], 1))).xyz;
        float3 v2 = (mul(pto.localToWorldMatrix, float4(_Vertices[_Indices[pto.indicesOffset + i + 2]], 1))).xyz;

        float t, u, v;
        if (IntersectTriangle(ray, v0, v1, v2, t, u, v))
        {
            if (t > 0 && t < bestHit.hitDistance)
            {
                           
                bestHit.hitDistance = t; // makes unity crash
                bestHit.hitPosition = ray.raySource + t * ray.rayDirection; // makes unity crash
                bestHit.hitNormal = normalize(bestHit.hitPosition); // makes unity crash

                bestHit.hitAlbedo = float3(1,1,1); // makes unity crash
             
            }
        }

    }
}

RayHit Trace(Ray ray)
{
    RayHit bestHit = CreateRayHit();

    for (int i = 0; i < _pathTracingObjectCount; i++) {
        pathTracingObject pto = _pathTracingObject[i];
        IntersectMeshObject(pto, ray, bestHit);
    }

    return bestHit;
}

[numthreads(8,8,1)]
void CSMain (uint3 id : SV_DispatchThreadID)
{
    // TODO: insert actual code here!
    float3 result = float3(0, 0, 0);

    int width, height;
    Result.GetDimensions(width, height);
    float2 uv = float2((id.xy + float2(0.5f, 0.5f)) / float2(width, height) * 2.0f - 1.0f);

    for(int i = 0; i < 1;i++) {
        Ray ray = CreateCameraRay(id.xy);
        RayHit hit = Trace(ray);
        result += hit.hitAlbedo;
    }
    result /= float3(5,5,5);

    Result[id.xy] = float4(result, 1);
}

```

C#

```
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;

[System.Serializable]
class PathTracing
{
 
    [SerializeField]
    ComputeShader computeShader;
    [SerializeField]
    GameObject[] pathTracingObjects;
  
    class PathTracingComputeShader
    {
        PathTracingObject[] pathTracingObjects;

        public List<Vector3> vertices = new List<Vector3>();
        public List<int> indices = new List<int>();

        RenderTexture RT;
        public void loadRenderTexture()
        {
            RT = new RenderTexture(Mathf.CeilToInt(Screen.width / 4), Mathf.CeilToInt(Screen.height / 4), 0, RenderTextureFormat.DefaultHDR);
            RT.enableRandomWrite = true;
            RT.Create();
        }
        public RenderTexture OnRenderComputeShader(ComputeShader computeShader)
        {
            loadRenderTexture();

            #region Mesh Forwarding

            computeShader.SetInt("_pathTracingObjectCount", pathTracingObjects.Length);

            foreach (PathTracingObject pto in pathTracingObjects)
               pto.OnExecutePathTracing();

            buildObjectList();

            ComputeBuffer objectsBuffer = new ComputeBuffer(pathTracingObjects.Length, 88) { name = "Scenes Objects Buffer" };
            ComputeBuffer vertexBuffer = new ComputeBuffer(vertices.Count, 12) { name = "Vertices Buffer" };
            ComputeBuffer indexBuffer = new ComputeBuffer(indices.Count, 4) { name = "Indices Buffer" };

            PathTracingObject.pathTracingObject[] sceneObjects = new PathTracingObject.pathTracingObject[pathTracingObjects.Length];
            for (int i = 0; i < pathTracingObjects.Length; i++)
            {
                sceneObjects[i] = pathTracingObjects[i]._pathTracingObject;
            }

            objectsBuffer.SetData(sceneObjects);
            vertexBuffer.SetData(vertices);
            indexBuffer.SetData(indices);

            computeShader.SetBuffer(0, "_pathTracingObject", objectsBuffer);
            computeShader.SetBuffer(0, "_Vertices", vertexBuffer);
            computeShader.SetBuffer(0, "_Indices", indexBuffer);
            #endregion

            computeShader.SetMatrix("_CameraToWorld", Camera.main.cameraToWorldMatrix);
            computeShader.SetMatrix("_CameraInverseProjection", Camera.main.projectionMatrix.inverse);

            computeShader.SetTexture(0, "Result", RT);
            computeShader.Dispatch(0, RT.width, RT.height, 24);

            return RT;
        }
        public void buildObjectList()
        {
            int indicesCount = 0;
            int verticesCount = 0;

            foreach (PathTracingObject pto in pathTracingObjects)
            {
                int[] triangles;
                Vector3[] vertices;

                triangles = pto.objectMesh.triangles;//Take a sequence of vertices that form a triangle.
                vertices = pto.objectMesh.vertices;//Take vertex list

                pto._pathTracingObject.indicesOffset = indicesCount;//Offset: Where the list of indices belonging to the object starts. | indicesCount: How many indices were added before these.
                pto._pathTracingObject.indicesCount = triangles.Length;//How many indexes does this object have.

                foreach (Vector3 vertice in vertices)
                    this.vertices.Add(vertice);

                for (int i = 0; i < triangles.Length; i++)
                {
                    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

                    /*Example:
                    If the previous object has 270 vertices.
                    The first triangle of the next objects will be connected to the vertices(271, 272, 273) instead of(0,1,2).
                    +1 because vertex 270 belongs to a different object.*/
                }

                indicesCount += triangles.Length;//update index
                verticesCount += vertices.Length;//update index
            }
        }
        public void setPathTracingObjects(PathTracingObject[] pto) { pathTracingObjects = pto; }
    }
    public RenderTexture preProcessing()
    {
        PathTracingComputeShader pathTracingCompute = new PathTracingComputeShader();

        PathTracingObject[] objs = new PathTracingObject[pathTracingObjects.Length];
        for (int i = 0; i < pathTracingObjects.Length; i++)
            objs[i] = pathTracingObjects[i].GetComponent<PathTracingObject>();

        pathTracingCompute.setPathTracingObjects(objs);
        return pathTracingCompute.OnRenderComputeShader(computeShader);
    }
}

```

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.

**Tags:** pathtracing, compute-shader, unity

> **Comments:**
> **username_1**: GPU drivers have a timeout built into them, if a shader takes to long to execute then the driver automatically stops the shader which results in an error thrown to the program.  Just going from the text of the error message this could be your problem.  
> **username_0**: Thanks for the answer! I was thinking it could be that, but is it a Shader error? I believe that my video card is really the problem since I am using an R7 240 4Gb.  
> **username_1**: The timeout isn't a shader error so much as it is the shader take to long to complete. The timeouts for a given shader execution are pretty short since the intent behind them is to run in parallel.  If it is timing out then either one of the loops is buggy and stuck, or are just plain doing to much work for you video card to handle for a single shader.  A faster/different video card might hide the issue for a time, but it will probably come up again if the underlying issue isn't resolved.  

---

## 0 answers

