Пример #1
0
    void Start()
    {
        Stopwatch sw = new Stopwatch();

        sw.Start();
        Scene scene = new Scene(true);

        bvhScene = new BVHScene(scene.triangles, scene.vertices);
        Debug.Log("bvhScene.triangles.Count = " + bvhScene.triangles.Count);

        Debug.Log(" ================================ ");

        var bvhData = new CPU_BVHData(bvhScene);

        CPU_SBVHBuilder.Build(bvhData);

        Debug.Log("bvhData.triangles.Count = " + bvhData.triIndices.Count);
        Debug.Log(" ================================ ");
        // debug gpu bvh
        GPU_BVHData gpuData = new GPU_BVHData().Generate(bvhData);

        Debug.Log("gpuData.nodes.Count = " + gpuData.nodes.Count);
        Debug.Log("gpuData.woopTris.Count = " + gpuData.woopTris.Count);
        Debug.Log("gpuData.triIndices.Count = " + gpuData.triIndices.Count);


        root = bvhData.root;
        sw.Stop();
        string log = "Build successfully, time: " + sw.ElapsedMilliseconds + " ms";

        Debug.Log(log);
    }
Пример #2
0
    public override void OnInspectorGUI()
    {
        var tracer = target as TracerBehaviour;

        bool pressGenerateBVH = GUILayout.Button("Rebuild BVH", GUILayout.ExpandWidth(true));

        if (pressGenerateBVH)
        {
            var scene    = new Scene(true);
            var bvhScene = new BVHScene(scene.triangles, scene.vertices);
            var cpuBVH   = new CPU_BVHData(bvhScene);
            CPU_SBVHBuilder.Build(cpuBVH);

            SaveBVH(tracer, cpuBVH);
        }

        //bool pressTest = GUILayout.Button("Log Test", GUILayout.ExpandWidth(true));
        //if (pressTest)
        //{
        //    Debug.Log(tracer.gpuBVH.nodes.Count);
        //    Debug.Log(tracer.gpuBVH.nodes[1]);
        //}

        DrawProperty("useCachedBVH");
        DrawProperty("spps");
        DrawProperty("tracingShader");
        DrawProperty("skyboxTex");
        DrawProperty("sun");

        serializedObject.ApplyModifiedProperties();
    }
Пример #3
0
    private void woopifyTri(CPU_BVHData bvh, int triIdx)
    {
        // fetch the 3 vertex indices of this triangle
        Vector3Int vtxInds = bvh.scene.triangles[bvh.triIndices[triIdx]];
        Vector3    v0      = bvh.scene.vertices[vtxInds.x];
        Vector3    v1      = bvh.scene.vertices[vtxInds.y];
        Vector3    v2      = bvh.scene.vertices[vtxInds.z];

        // regular triangles (for debugging only)
        _debug[0] = new Vector4(v0.x, v0.y, v0.z, 0.0f);
        _debug[1] = new Vector4(v1.x, v1.y, v1.z, 0.0f);
        _debug[2] = new Vector4(v2.x, v2.y, v2.z, 0.0f);

        Matrix4x4 mtx = new Matrix4x4();

        // compute edges and transform them with a matrix
        mtx.SetColumn(0, MathUtils.Swizzle(v0 - v2)); // sets matrix column 0 equal to a Vec4f(Vec3f, 0.0f )
        mtx.SetColumn(1, MathUtils.Swizzle(v1 - v2, 0.0f));
        mtx.SetColumn(2, MathUtils.Swizzle(Vector3.Cross(v0 - v2, v1 - v2), 0.0f));
        mtx.SetColumn(3, MathUtils.Swizzle(v2, 1.0f));
        mtx = Matrix4x4.Inverse(mtx);

        /// m_woop[3] stores 3 transformed triangle edges
        _woop[0] = new Vector4(mtx[2, 0], mtx[2, 1], mtx[2, 2], -mtx[2, 3]); // elements of 3rd row of inverted matrix
        _woop[1] = mtx.GetRow(0);
        _woop[2] = mtx.GetRow(1);
    }
Пример #4
0
    private CPU_SBVHBuilder(CPU_BVHData bvhData)
    {
        _bvhData     = bvhData;
        _refStack    = new List <PrimitiveRef>();
        _rightBounds = new List <AABB>();

        int rightBoundsCount = Mathf.Max(_bvhData.scene.triangles.Count, N_SPATIAL_BINS) - 1;

        for (int i = 0; i < rightBoundsCount; i++)
        {
            _rightBounds.Add(AABB.New());
        }
    }
Пример #5
0
    // Start is called before the first frame update
    void Start()
    {
        if (gpuBVH == null)
        {
            Debug.Log("No cached BVH data found, building BVH now.");
            _theScene = new Scene(true);
            var bvhScene = new BVHScene(_theScene.triangles, _theScene.vertices);
            var cpuBVH   = new CPU_BVHData(bvhScene);
            CPU_SBVHBuilder.Build(cpuBVH);
            gpuBVH = new GPU_BVHData().Generate(cpuBVH);
        }
        else
        {
            _theScene = new Scene(true);
            Debug.Log("Using cached BVH data.");
        }

        // bind texture2darray
        var diffuseTexLen = _theScene.diffuseTextures.Count;

        if (_theScene.diffuseTextures.Count > 0)
        {
            var tex = _theScene.diffuseTextures[0];
            _diffuseTextures = new Texture2DArray(tex.width, tex.height, diffuseTexLen, tex.format, true);

            for (int i = 0; i < diffuseTexLen; i++)
            {
                Graphics.CopyTexture(_theScene.diffuseTextures[i], 0, _diffuseTextures, i);
            }
        }

        // bvh
        CreateComputeBuffer(ref _nodesBuffer, gpuBVH.nodes, 16);
        CreateComputeBuffer(ref _woopTrisBuffer, gpuBVH.woopTris, 16);
        CreateComputeBuffer(ref _triIndicesBuffer, gpuBVH.triIndices, 4);

        // per vertex
        CreateComputeBuffer(ref _verticesBuffer, _theScene.vertices, 12);
        CreateComputeBuffer(ref _normalsBuffer, _theScene.normals, 12);
        CreateComputeBuffer(ref _uv0sBuffer, _theScene.uv0s, 8);

        // per triangle
        CreateComputeBuffer(ref _trianglesBuffer, _theScene.triangles, 12);
        CreateComputeBuffer(ref _materialsBuffer, _theScene.materials, 144);
        CreateComputeBuffer(ref _matIdxBuffer, _theScene.matIndices, 4);
    }
Пример #6
0
    private static void SaveBVH(TracerBehaviour tracer, CPU_BVHData cpuBVH)
    {
        var cacheDir = "Assets/Cache/BVH/";

        if (!System.IO.Directory.Exists(cacheDir))
        {
            System.IO.Directory.CreateDirectory(cacheDir);
        }

        var path      = cacheDir + EditorSceneManager.GetActiveScene().name + "_BVH.prefab";
        var dataObj   = new GameObject("__BVHData__");
        var cachedBVH = dataObj.AddComponent <GPU_BVHData>();

        cachedBVH.Generate(cpuBVH);
        var prefabRoot = PrefabUtility.SaveAsPrefabAsset(dataObj, path);

        DestroyImmediate(dataObj);
        tracer.gpuBVH = prefabRoot.GetComponent <GPU_BVHData>();
    }
Пример #7
0
    public static void Build(CPU_BVHData bvhData)
    {
        var builder = new CPU_SBVHBuilder(bvhData);

        builder.Build();
    }
Пример #8
0
    public GPU_BVHData Generate(CPU_BVHData cpuData)
    {
        nodes      = new List <Vector4>();
        woopTris   = new List <Vector4>();
        triIndices = new List <int>();

        Stack <StackEntry> stack = new Stack <StackEntry>();

        stack.Push(new StackEntry(cpuData.root, 0));

        AABB[] cbox = new AABB[2];
        int[]  cidx = new int[2];

        Vector4[] zero4 = new Vector4[4] {
            new Vector4(), new Vector4(), new Vector4(), new Vector4()
        };
        nodes.AddRange(zero4);

        while (stack.Count > 0)
        {
            var cur = stack.Pop();

            for (int i = 0; i < 2; i++)
            {
                var child = cur.node.GetChildNode(i);
                cbox[i] = child.bounds;

                if (!child.IsLeaf())
                {
                    cidx[i] = nodes.Count /* / nodeOffsetSizeDiv */;

                    stack.Push(new StackEntry(child, nodes.Count));
                    nodes.AddRange(zero4);
                    continue;
                }

                LeafNode leaf = child as LeafNode;
                cidx[i] = ~woopTris.Count;

                for (int j = leaf.triangleStart; j < leaf.triangleEnd; j++)
                {
                    woopifyTri(cpuData, j);

                    woopTris.Add(_woop[0]);
                    woopTris.Add(_woop[1]);
                    woopTris.Add(_woop[2]);

                    triIndices.Add(cpuData.triIndices[j]);
                    triIndices.Add(0); // 对齐索引,好查找
                    triIndices.Add(0);
                }

                // 用来标记属于该叶节点的三角形末端
                woopTris.Add(new Vector4(1e20f, 0, 0, 0));
                triIndices.Add(0);
            }

            int dstIdx = cur.idx;
            nodes[dstIdx]     = new Vector4(cbox[0].min.x, cbox[0].max.x, cbox[0].min.y, cbox[0].max.y);
            nodes[dstIdx + 1] = new Vector4(cbox[1].min.x, cbox[1].max.x, cbox[1].min.y, cbox[1].max.y);
            nodes[dstIdx + 2] = new Vector4(cbox[0].min.z, cbox[0].max.z, cbox[1].min.z, cbox[1].max.z);
            nodes[dstIdx + 3] = new Vector4(cidx[0], cidx[1], 0, 0);
        }

        return(this);
    }