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); }
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(); }
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); }
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()); } }
// 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); }
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>(); }
public static void Build(CPU_BVHData bvhData) { var builder = new CPU_SBVHBuilder(bvhData); builder.Build(); }
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); }