public TerrainDrawStreaming(int maximumLength, int meshSize, ComputeShader transformShader) { current = this; if (meshSize % 2 != 0) { Debug.LogError("Terrain panel's size should be even number!"); meshSize++; } this.meshSize = meshSize; //Initialize Mesh and triangles int vertexCount = meshSize + 1; vertSize = vertexCount; heightMapSize = vertSize * vertSize; NativeArray <float2> terrainVertexArray = new NativeArray <float2>(vertexCount * vertexCount, Allocator.Temp, NativeArrayOptions.UninitializedMemory); float2 *arrPtr = terrainVertexArray.Ptr(); for (int x = 0; x < vertexCount; ++x) { for (int y = 0; y < vertexCount; ++y) { arrPtr[y * vertexCount + x] = new float2(x, y) / meshSize - new float2(0.5f, 0.5f); } } verticesBuffer = new ComputeBuffer(terrainVertexArray.Length, sizeof(float2)); verticesBuffer.SetData(terrainVertexArray); heightMapBuffer = new ComputeBuffer(maximumLength * (vertexCount * vertexCount), sizeof(float)); NativeArray <int> triangles = new NativeArray <int>(6 * meshSize * meshSize, Allocator.Temp, NativeArrayOptions.UninitializedMemory); int *trianglePtr = triangles.Ptr(); for (int x = 0, count = 0; x < meshSize; ++x) { for (int y = 0; y < meshSize; ++y) { int4 indices = new int4(vertexCount * y + x, vertexCount * (y + 1) + x, vertexCount * y + (x + 1), vertexCount * (y + 1) + (x + 1)); trianglePtr[count] = indices.x; trianglePtr[count + 1] = indices.y; trianglePtr[count + 2] = indices.z; trianglePtr[count + 3] = indices.y; trianglePtr[count + 4] = indices.w; trianglePtr[count + 5] = indices.z; count += 6; } } triangleBuffer = new ComputeBuffer(triangles.Length, sizeof(int)); triangleBuffer.SetData(triangles); triangles.Dispose(); terrainVertexArray.Dispose(); removebuffer = new ComputeBuffer(100, sizeof(int2)); //Initialize indirect clusterBuffer = new ComputeBuffer(maximumLength, sizeof(TerrainPanel)); referenceBuffer = new NativeList <ulong>(maximumLength, Allocator.Persistent); this.transformShader = transformShader; resultBuffer = new ComputeBuffer(maximumLength, sizeof(int)); instanceCountBuffer = new ComputeBuffer(5, sizeof(int), ComputeBufferType.IndirectArguments); NativeArray <int> indirect = new NativeArray <int>(5, Allocator.Temp, NativeArrayOptions.ClearMemory); indirect[0] = triangleBuffer.count; instanceCountBuffer.SetData(indirect); indirect.Dispose(); notUsedHeightmapIndices = new NativeList <int>(maximumLength, Allocator.Persistent); for (int i = 0; i < maximumLength; ++i) { notUsedHeightmapIndices.Add(i); } }
public void RemoveQuadTrees(NativeList <ulong> removeList) { void ErasePoint(TerrainQuadTree.QuadTreeNode *node) { node->listPosition = -1; notUsedHeightmapIndices.Add(node->panel.heightMapIndex); } int length = removeList.Length; TerrainQuadTree.QuadTreeNode **tree = (TerrainQuadTree.QuadTreeNode * *)removeList.unsafePtr; int targetLength = referenceBuffer.Length - length; int len = 0; if (targetLength <= 0) { for (int i = 0; i < length; ++i) { ErasePoint(tree[i]); } referenceBuffer.Clear(); return; } for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *currentNode = tree[i]; if (currentNode->listPosition >= targetLength) { referenceBuffer[currentNode->listPosition] = 0; ErasePoint(currentNode); } } NativeArray <int2> transformList = new NativeArray <int2>(length, Allocator.Temp, NativeArrayOptions.UninitializedMemory); int2 *transformPtr = transformList.Ptr(); len = 0; int currentIndex = referenceBuffer.Length - 1; for (int i = 0; i < length; ++i) { TerrainQuadTree.QuadTreeNode *treeNode = tree[i]; if (treeNode->listPosition < 0) { continue; } while (referenceBuffer[currentIndex] == 0) { currentIndex--; if (currentIndex < 0) { goto FINALIZE; } } TerrainQuadTree.QuadTreeNode *lastNode = (TerrainQuadTree.QuadTreeNode *)referenceBuffer[currentIndex]; currentIndex--; transformPtr[len] = new int2(treeNode->listPosition, lastNode->listPosition); len++; lastNode->listPosition = treeNode->listPosition; referenceBuffer[lastNode->listPosition] = (ulong)lastNode; ErasePoint(treeNode); } FINALIZE: referenceBuffer.RemoveLast(length); if (len <= 0) { return; } if (len > removebuffer.count) { removebuffer.Dispose(); removebuffer = new ComputeBuffer(len, sizeof(int2)); } removebuffer.SetData(transformList, 0, 0, len); transformShader.SetBuffer(0, ShaderIDs._IndexBuffer, removebuffer); transformShader.SetBuffer(0, ShaderIDs.clusterBuffer, clusterBuffer); ComputeShaderUtility.Dispatch(transformShader, 0, len); transformList.Dispose(); }
public void GenerateAsync(bool listCommand = true) { clusterBuffer = new NativeArray <CullBox>(property.clusterCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); pointsBuffer = new NativeArray <Point>(property.clusterCount * PipelineBaseBuffer.CLUSTERCLIPCOUNT, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); indicesBuffer = new NativeArray <int>(property.clusterCount, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); NativeList <ulong> pointerContainer = SceneController.pointerContainer; pointerContainer.AddCapacityTo(pointerContainer.Length + indicesBuffer.Length); CullBox * clusterData = clusterBuffer.Ptr(); Point * verticesData = pointsBuffer.Ptr(); const string infosPath = "Assets/BinaryData/MapInfos/"; const string pointsPath = "Assets/BinaryData/MapPoints/"; MStringBuilder sb = new MStringBuilder(pointsPath.Length + property.name.Length + ".mpipe".Length); allStrings[0] = infosPath; allStrings[1] = property.name; allStrings[2] = ".mpipe"; sb.Combine(allStrings); // FileStream fileStream = new FileStream(sb.str, FileMode.Open, FileAccess.Read); using (FileStream reader = new FileStream(sb.str, FileMode.Open, FileAccess.Read)) { int length = (int)reader.Length; byte[] bytes = GetByteArray(length); reader.Read(bytes, 0, length); fixed(byte *b = bytes) { UnsafeUtility.MemCpy(clusterData, b, length); } } allStrings[0] = pointsPath; sb.Combine(allStrings); using (FileStream reader = new FileStream(sb.str, FileMode.Open, FileAccess.Read)) { int length = (int)reader.Length; byte[] bytes = GetByteArray(length); reader.Read(bytes, 0, length); fixed(byte *b = bytes) { UnsafeUtility.MemCpy(verticesData, b, length); } } int *indicesPtr = indicesBuffer.Ptr(); LoadingCommandQueue commandQueue = SceneController.commandQueue; for (int i = 0; i < indicesBuffer.Length; ++i) { indicesPtr[i] = pointerContainer.Length; pointerContainer.Add((ulong)(indicesPtr + i)); } LoadTextures(); propertiesPool = SceneController.commonData.GetPropertyIndex(property.properties.Length); uint *poolPtr = propertiesPool.Ptr(); lightmapIndices = new NativeArray <int>(allLightmapDatas.Count, Allocator.Persistent, NativeArrayOptions.UninitializedMemory); int *ptr = lightmapIndices.Ptr(); for (int i = 0; i < lightmapIndices.Length; ++i) { ptr[i] = allLightmapDatas[i].index; } if (listCommand) { lock (commandQueue) { commandQueue.Queue(GenerateRun()); } } }
public static void ReleaseRTAfterFrame(int targetRT) { waitReleaseRT.Add(targetRT); }
public void Awake(MonoBehaviour behavior) { current = this; addList = new NativeList <ulong>(10, Allocator.Persistent); this.behavior = behavior; baseBuffer = new PipelineBaseBuffer(); clusterResources = Resources.Load <ClusterMatResources>("MapMat/" + mapResources); int clusterCount = 0; allScenes = new List <SceneStreaming>(clusterResources.clusterProperties.Count); foreach (var i in clusterResources.clusterProperties) { clusterCount += i.clusterCount; allScenes.Add(new SceneStreaming(i)); } PipelineFunctions.InitBaseBuffer(baseBuffer, clusterResources, mapResources, clusterCount); pointerContainer = new NativeList <ulong>(clusterCount, Allocator.Persistent); commandQueue = new LoadingCommandQueue(); RenderTextureDescriptor desc = new RenderTextureDescriptor { autoGenerateMips = false, bindMS = false, colorFormat = RenderTextureFormat.ARGB32, depthBufferBits = 0, dimension = TextureDimension.Tex2DArray, enableRandomWrite = false, height = resolution, width = resolution, memoryless = RenderTextureMemoryless.None, msaaSamples = 1, vrUsage = VRTextureUsage.None, volumeDepth = texArrayCapacity, shadowSamplingMode = ShadowSamplingMode.None, sRGB = false, useMipMap = false }; commonData = new SceneCommonData { texDict = new Dictionary <string, SceneCommonData.TextureIdentifier>(), avaiableProperties = new NativeList <int>(propertyCapacity, Allocator.Persistent), avaiableTexs = new NativeList <int>(texArrayCapacity, Allocator.Persistent), texCopyBuffer = new ComputeBuffer(resolution * resolution, sizeof(int)), propertyBuffer = new ComputeBuffer(propertyCapacity, sizeof(PropertyValue)), copyTextureMat = new Material(RenderPipeline.current.resources.copyShader), texArray = new RenderTexture(desc), clusterMaterial = new Material(RenderPipeline.current.resources.clusterRenderShader), terrainMaterial = new Material(RenderPipeline.current.resources.terrainShader), terrainDrawStreaming = new TerrainDrawStreaming(100, 16, RenderPipeline.current.resources.terrainCompute) }; commonData.clusterMaterial.SetBuffer(ShaderIDs._PropertiesBuffer, commonData.propertyBuffer); commonData.clusterMaterial.SetTexture(ShaderIDs._MainTex, commonData.texArray); commonData.copyTextureMat.SetVector("_TextureSize", new Vector4(resolution, resolution)); commonData.copyTextureMat.SetBuffer("_TextureBuffer", commonData.texCopyBuffer); for (int i = 0; i < propertyCapacity; ++i) { commonData.avaiableProperties.Add(i); } for (int i = 0; i < texArrayCapacity; ++i) { commonData.avaiableTexs.Add(i); } testNodeArray = new NativeList <ulong>(terrainTransforms.Length, Allocator.Persistent); foreach (var i in terrainTransforms) { TerrainQuadTree.QuadTreeNode *testNode = (TerrainQuadTree.QuadTreeNode *)UnsafeUtility.Malloc(sizeof(TerrainQuadTree.QuadTreeNode), 16, Allocator.Persistent); testNode->listPosition = -1; ref TerrainPanel panel = ref testNode->panel; if (i.localScale.x > 1.1f) { panel.edgeFlag = 0; } else { panel.edgeFlag = 15; } panel.extent = i.localScale * 0.5f; panel.position = i.position; panel.textureIndex = 0; panel.heightMapIndex = 0; testNodeArray.Add((ulong)testNode); }