private void InitializeBuffers() { // InitializeBuffers if (terrainGenomeCBuffer != null) { terrainGenomeCBuffer.Release(); } terrainGenomeCBuffer = new ComputeBuffer(numNoiseOctaves, sizeof(float) * 5); GenomeNoiseOctaveData[] genomeNoiseOctaveDataArray = new GenomeNoiseOctaveData[numNoiseOctaves]; for (int i = 0; i < genomeNoiseOctaveDataArray.Length; i++) { GenomeNoiseOctaveData genomeNoiseOctaveData; genomeNoiseOctaveData.amplitude = baseAmplitude / Mathf.Pow(2, i); genomeNoiseOctaveData.frequency = baseFrequency * Mathf.Pow(2, i); genomeNoiseOctaveData.offset = new Vector3(0f, 0f, 0f) + baseOffset; genomeNoiseOctaveDataArray[i] = genomeNoiseOctaveData; } terrainGenomeCBuffer.SetData(genomeNoiseOctaveDataArray); if (terrainVertexDataCBuffer != null) { terrainVertexDataCBuffer.Release(); } terrainVertexDataCBuffer = new ComputeBuffer(meshResolutionX * meshResolutionZ, sizeof(float) * 11); if (terrainTriangleIndexDataCBuffer != null) { terrainTriangleIndexDataCBuffer.Release(); } terrainTriangleIndexDataCBuffer = new ComputeBuffer((meshResolutionX - 1) * (meshResolutionZ - 1) * 2, sizeof(int) * 3); if (weightMatrix5CBuffer != null) { weightMatrix5CBuffer.Release(); } weightMatrix5CBuffer = new ComputeBuffer(5, sizeof(float) * 3); // center + 4 cardinal direction neighbors if (weightMatrix9CBuffer != null) { weightMatrix9CBuffer.Release(); } weightMatrix9CBuffer = new ComputeBuffer(9, sizeof(float) * 3); // center + all direction neighbors if (weightMatrix13CBuffer != null) { weightMatrix13CBuffer.Release(); } weightMatrix13CBuffer = new ComputeBuffer(13, sizeof(float) * 3); // center + all direction neighbors 1 away + cardinal dir neighbors 2 away SetWeightMatricesToNextRandom(); }
private GenomeNoiseOctaveData[] SetNoiseSamplerSettings(int numOctaves, Vector3 baseAmplitude, Vector3 baseFrequency, Vector3 baseOffset, float baseRotation, float ridgeNoise) { GenomeNoiseOctaveData[] sampleParamsArray = new GenomeNoiseOctaveData[numOctaves]; for (int i = 0; i < sampleParamsArray.Length; i++) { GenomeNoiseOctaveData genomeNoiseOctaveData; genomeNoiseOctaveData.amplitude = baseAmplitude / Mathf.Pow(2, i); genomeNoiseOctaveData.frequency = baseFrequency * Mathf.Pow(2, i); genomeNoiseOctaveData.offset = new Vector3(0f, 0f, 0f) + baseOffset; genomeNoiseOctaveData.rotation = baseRotation * i; genomeNoiseOctaveData.ridgeNoise = ridgeNoise; sampleParamsArray[i] = genomeNoiseOctaveData; } return(sampleParamsArray); }
// Use this for initialization void Start() { // InitializeBuffers if (terrainGenomeCBuffer != null) { terrainGenomeCBuffer.Release(); } terrainGenomeCBuffer = new ComputeBuffer(numNoiseOctaves, sizeof(float) * 5); GenomeNoiseOctaveData[] genomeNoiseOctaveDataArray = new GenomeNoiseOctaveData[numNoiseOctaves]; for (int i = 0; i < genomeNoiseOctaveDataArray.Length; i++) { GenomeNoiseOctaveData genomeNoiseOctaveData; genomeNoiseOctaveData.amplitude = baseAmplitude / Mathf.Pow(2, i); genomeNoiseOctaveData.frequency = baseFrequency * Mathf.Pow(2, i); genomeNoiseOctaveData.offset = new Vector3(0f, 0f, 0f) + baseOffset; genomeNoiseOctaveDataArray[i] = genomeNoiseOctaveData; } terrainGenomeCBuffer.SetData(genomeNoiseOctaveDataArray); // TEXTURES: //heightMapTextureA = new RenderTexture(resolutionX + 1, resolutionZ + 1, 1, RenderTextureFormat.Default); // heightMapTextureB = new RenderTexture(resolutionX + 1, resolutionZ + 1, 1, RenderTextureFormat.Default); if (terrainVertexDataCBuffer != null) { terrainVertexDataCBuffer.Release(); } terrainVertexDataCBuffer = new ComputeBuffer((resolutionX + 1) * (resolutionZ + 1), sizeof(float) * 11); if (terrainVertexDataSwapCBuffer != null) { terrainVertexDataSwapCBuffer.Release(); } terrainVertexDataSwapCBuffer = new ComputeBuffer((resolutionX + 1) * (resolutionZ + 1), sizeof(float) * 11); if (terrainTriangleIndexDataCBuffer != null) { terrainTriangleIndexDataCBuffer.Release(); } terrainTriangleIndexDataCBuffer = new ComputeBuffer(resolutionX * resolutionZ * 2, sizeof(int) * 3); // Upload TerrainGenome to GPU terrainComputeShader.SetInt("resolutionX", resolutionX); terrainComputeShader.SetInt("resolutionZ", resolutionZ); terrainComputeShader.SetFloat("xStart", xStart); terrainComputeShader.SetFloat("xEnd", xEnd); terrainComputeShader.SetFloat("zStart", zStart); terrainComputeShader.SetFloat("zEnd", zEnd); int vertexDataKernelID = terrainComputeShader.FindKernel("CSGenerateVertexData"); terrainComputeShader.SetBuffer(vertexDataKernelID, "terrainGenomeCBuffer", terrainGenomeCBuffer); terrainComputeShader.SetBuffer(vertexDataKernelID, "terrainVertexDataCBuffer", terrainVertexDataCBuffer); terrainComputeShader.SetBuffer(vertexDataKernelID, "terrainVertexDataSwapCBuffer", terrainVertexDataSwapCBuffer); //terrainComputeShader.SetTexture(vertexDataKernelID, "heightMapTextureA", heightMapTextureA); //terrainComputeShader.SetTexture(vertexDataKernelID, "heightMapTextureB", heightMapTextureB); int simulateCAKernelID = terrainComputeShader.FindKernel("CSSimulateCA"); terrainComputeShader.SetBuffer(simulateCAKernelID, "terrainGenomeCBuffer", terrainGenomeCBuffer); terrainComputeShader.SetBuffer(simulateCAKernelID, "terrainVertexDataCBuffer", terrainVertexDataCBuffer); terrainComputeShader.SetBuffer(simulateCAKernelID, "terrainVertexDataSwapCBuffer", terrainVertexDataSwapCBuffer); //terrainComputeShader.SetTexture(simulateCAKernelID, "heightMapTextureA", heightMapTextureA); //terrainComputeShader.SetTexture(simulateCAKernelID, "heightMapTextureB", heightMapTextureB); int baseToSwapKernelID = terrainComputeShader.FindKernel("CSCopyFromBaseToSwap"); terrainComputeShader.SetBuffer(baseToSwapKernelID, "terrainVertexDataCBuffer", terrainVertexDataCBuffer); terrainComputeShader.SetBuffer(baseToSwapKernelID, "terrainVertexDataSwapCBuffer", terrainVertexDataSwapCBuffer); //terrainComputeShader.SetTexture(baseToSwapKernelID, "heightMapTextureA", heightMapTextureA); //terrainComputeShader.SetTexture(baseToSwapKernelID, "heightMapTextureB", heightMapTextureB); int swapToBaseKernelID = terrainComputeShader.FindKernel("CSCopyFromSwapToBase"); terrainComputeShader.SetBuffer(swapToBaseKernelID, "terrainVertexDataCBuffer", terrainVertexDataCBuffer); terrainComputeShader.SetBuffer(swapToBaseKernelID, "terrainVertexDataSwapCBuffer", terrainVertexDataSwapCBuffer); //terrainComputeShader.SetTexture(swapToBaseKernelID, "heightMapTextureA", heightMapTextureA); //terrainComputeShader.SetTexture(swapToBaseKernelID, "heightMapTextureB", heightMapTextureB); // Or should I just do this on the CPU??? probably faster?? .... optimize/profile later on... int triangleIndicesKernelID = terrainComputeShader.FindKernel("CSGenerateTriangleIndices"); terrainComputeShader.SetBuffer(triangleIndicesKernelID, "terrainGenomeCBuffer", terrainGenomeCBuffer); terrainComputeShader.SetBuffer(triangleIndicesKernelID, "terrainTriangleIndexDataCBuffer", terrainTriangleIndexDataCBuffer); // Calculate Terrain Mesh, Dispatch terrainComputeShader.Dispatch(vertexDataKernelID, resolutionX + 1, 1, resolutionZ + 1); for (int i = 0; i < numFilterIterations; i++) { terrainComputeShader.Dispatch(baseToSwapKernelID, resolutionX + 1, 1, resolutionZ + 1); // initialize swap buffer as copy of original terrainComputeShader.Dispatch(simulateCAKernelID, resolutionX + 1, 1, resolutionZ + 1); // read from original buffer, write modified values to swap buffer terrainComputeShader.Dispatch(swapToBaseKernelID, resolutionX + 1, 1, resolutionZ + 1); // copy new values in swap buffer back to original to be read } terrainComputeShader.Dispatch(triangleIndicesKernelID, resolutionX, 1, resolutionZ); // Download Mesh from GPU VertexData[] vertexDataArray = new VertexData[terrainVertexDataCBuffer.count]; terrainVertexDataCBuffer.GetData(vertexDataArray); TriangleIndexData[] triangleIndexDataArray = new TriangleIndexData[terrainTriangleIndexDataCBuffer.count]; terrainTriangleIndexDataCBuffer.GetData(triangleIndexDataArray); // Process Mesh on CPU //for (int x = 0; x < resolutionX; x++) { // for(int z = 0; z < resolutionZ; z++) { // int index = x * resolutionZ + z; // Debug.Log(index.ToString() + " [" + x.ToString() + "," + z.ToString() + "] pos: " + vertexDataArray[index].worldPos.ToString()); // } //} //for(int i = 0; i < vertexDataArray.Length; i++) { // Debug.Log(i.ToString() + " pos: " + vertexDataArray[i].worldPos.ToString()); //} //for (int i = 0; i < triangleIndexDataArray.Length; i++) { // Debug.Log(i.ToString() + " index0: " + triangleIndexDataArray[i].v1.ToString() + ", " + triangleIndexDataArray[i].v2.ToString() + ", " + triangleIndexDataArray[i].v3.ToString() + ", "); //} terrainMesh = new Mesh(); Vector3[] vertices = new Vector3[vertexDataArray.Length]; int[] tris = new int[triangleIndexDataArray.Length * 3]; Vector2[] uvs = new Vector2[vertexDataArray.Length]; Vector3[] normals = new Vector3[vertexDataArray.Length]; Color[] colors = new Color[vertexDataArray.Length]; for (int i = 0; i < vertexDataArray.Length; i++) { vertices[i] = vertexDataArray[i].worldPos; normals[i] = vertexDataArray[i].normal; uvs[i] = vertexDataArray[i].uv; colors[i] = new Color(vertexDataArray[i].color.x, vertexDataArray[i].color.y, vertexDataArray[i].color.z); //Debug.Log(i.ToString() + " pos: " + vertexDataArray[i].worldPos.ToString()); } for (int i = 0; i < triangleIndexDataArray.Length; i++) { tris[i * 3] = triangleIndexDataArray[i].v1; tris[i * 3 + 1] = triangleIndexDataArray[i].v2; tris[i * 3 + 2] = triangleIndexDataArray[i].v3; //Debug.Log(i.ToString() + " index0: " + triangleIndexDataArray[i].v1.ToString() + ", " + triangleIndexDataArray[i].v2.ToString() + ", " + triangleIndexDataArray[i].v3.ToString() + ", "); } terrainMesh.vertices = vertices; terrainMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); terrainMesh.triangles = tris; terrainMesh.normals = normals; //NewMesh.RecalculateNormals(); terrainMesh.colors = colors; terrainMesh.RecalculateNormals(); // Display Mesh (set as MeshFilter's Mesh) this.GetComponent <MeshFilter>().sharedMesh = terrainMesh; }