static public int Dispose(IntPtr l) { try { #if DEBUG var method = System.Reflection.MethodBase.GetCurrentMethod(); string methodName = GetMethodName(method); #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.BeginSample(methodName); #else Profiler.BeginSample(methodName); #endif #endif UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Dispose(); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } #if DEBUG finally { #if UNITY_5_5_OR_NEWER UnityEngine.Profiling.Profiler.EndSample(); #else Profiler.EndSample(); #endif } #endif }
public static Tensor InvokeFunctionKernel(string name, Tensor input) { var compute = Pix2PixResources.Compute; var kernel = compute.FindKernel(name); uint tgn_x, tgn_y, tgn_z; compute.GetKernelThreadGroupSizes(kernel, out tgn_x, out tgn_y, out tgn_z); Debug.Assert(tgn_y == 1 && tgn_z == 1); var length = input.Data.Length; Debug.Assert(length % tgn_x == 0); var buffer_input = new UnityEngine.ComputeBuffer(length, sizeof(float)); var buffer_output = new UnityEngine.ComputeBuffer(length, sizeof(float)); buffer_input.SetData(input.Data); compute.SetBuffer(kernel, "Input", buffer_input); compute.SetBuffer(kernel, "Output", buffer_output); compute.Dispatch(kernel, length / (int)tgn_x, 1, 1); var output = new Tensor(input.Shape); buffer_output.GetData(output.Data); buffer_input.Dispose(); buffer_output.Dispose(); return(output); }
// Use this for initialization void Start() { Debug.Log("Population size: " + populationSize); int width = (int)Mathf.Round(Mathf.Sqrt(populationSize)); int height = (int)Mathf.Round(Mathf.Sqrt(populationSize)); testing = new ComputeBuffer(10, Marshal.SizeOf(typeof(Individual))); Debug.Log("Seed " + DateTime.Now.Millisecond); // Fill with random genome, and run first fitness test. int kernel = shader.FindKernel("InitializePopulation"); DebugAux.Assert(kernel >= 0, "Couldn't find kernel: " + "InitializePopulation " + kernel); shader.SetBuffer(kernel, "Population", testing); shader.SetFloat("seed", DateTime.Now.Millisecond); shader.Dispatch(kernel, 32, 32, 1); Individual[] tes = new Individual[10]; testing.GetData(tes); for (int i = 0; i < tes.Length; i++) Debug.Log(tes[i].genome + " " + tes[i].fitness); // Selection.. /*kernel = shader.FindKernel("AllOnesFitness"); DebugAux.Assert(kernel >= 0, "Couldn't find kernel: " + "AllOnesFitness " + kernel); shader.SetBuffer(kernel, "Population", testing); shader.Dispatch(kernel, 32, 32, 1);*/ testing.Dispose(); }
public static Tensor InvokeConvolutionKernel( ConvolutionMode mode, string name, Tensor input, Tensor filter, Tensor bias ) { var compute = Pix2PixResources.Compute; var kernel = compute.FindKernel(name); uint tgn_x, tgn_y, tgn_z; compute.GetKernelThreadGroupSizes(kernel, out tgn_x, out tgn_y, out tgn_z); var deconv = (mode == ConvolutionMode.Backward); var outHeight = deconv ? input.Shape[0] * 2 : input.Shape[0] / 2; var outWidth = deconv ? input.Shape[1] * 2 : input.Shape[1] / 2; var outChannels = filter.Shape[deconv ? 2 : 3]; Debug.Assert(outHeight % tgn_z == 0); Debug.Assert(outWidth % tgn_y == 0); Debug.Assert(outChannels % tgn_x == 0); var output = new Tensor(new [] { outHeight, outWidth, outChannels }); var buffer_input = new UnityEngine.ComputeBuffer(input.Data.Length, sizeof(float)); var buffer_filter = new UnityEngine.ComputeBuffer(filter.Data.Length, sizeof(float)); var buffer_bias = new UnityEngine.ComputeBuffer(bias.Data.Length, sizeof(float)); var buffer_output = new UnityEngine.ComputeBuffer(output.Data.Length, sizeof(float)); buffer_input.SetData(input.Data); buffer_filter.SetData(filter.Data); buffer_bias.SetData(bias.Data); compute.SetInts("InputShape", input.Shape); compute.SetInts("FilterShape", filter.Shape); compute.SetInts("OutputShape", output.Shape); compute.SetBuffer(kernel, "Input", buffer_input); compute.SetBuffer(kernel, "Filter", buffer_filter); compute.SetBuffer(kernel, "Bias", buffer_bias); compute.SetBuffer(kernel, "Output", buffer_output); compute.Dispatch(kernel, outChannels / (int)tgn_x, outWidth / (int)tgn_y, outHeight / (int)tgn_z ); buffer_output.GetData(output.Data); buffer_input.Dispose(); buffer_filter.Dispose(); buffer_bias.Dispose(); buffer_output.Dispose(); return(output); }
static public int Dispose(IntPtr l) { try { UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Dispose(); pushValue(l, true); return(1); } catch (Exception e) { return(error(l, e)); } }
static public int Dispose(IntPtr l) { try { UnityEngine.ComputeBuffer self = (UnityEngine.ComputeBuffer)checkSelf(l); self.Dispose(); return(0); } catch (Exception e) { LuaDLL.luaL_error(l, e.ToString()); return(0); } }
public static Tensor InvokeNormalizationKernel( string name, Tensor input, Tensor scale, Tensor offset ) { var compute = Pix2PixResources.Compute; var kernel = compute.FindKernel(name); uint tgn_x, tgn_y, tgn_z; compute.GetKernelThreadGroupSizes(kernel, out tgn_x, out tgn_y, out tgn_z); var length = input.Data.Length; var channels = input.Shape[2]; Debug.Assert(channels % tgn_x == 0); Debug.Assert(channels == scale.Data.Length); Debug.Assert(channels == offset.Data.Length); var buffer_input = new UnityEngine.ComputeBuffer(length, sizeof(float)); var buffer_scale = new UnityEngine.ComputeBuffer(channels, sizeof(float)); var buffer_offset = new UnityEngine.ComputeBuffer(channels, sizeof(float)); var buffer_output = new UnityEngine.ComputeBuffer(length, sizeof(float)); buffer_input.SetData(input.Data); buffer_scale.SetData(scale.Data); buffer_offset.SetData(offset.Data); compute.SetInts("InputShape", input.Shape); compute.SetInts("OutputShape", input.Shape); compute.SetBuffer(kernel, "Input", buffer_input); compute.SetBuffer(kernel, "Filter", buffer_scale); compute.SetBuffer(kernel, "Bias", buffer_offset); compute.SetBuffer(kernel, "Output", buffer_output); compute.Dispatch(kernel, channels / (int)tgn_x, 1, 1); var output = new Tensor(input.Shape); buffer_output.GetData(output.Data); buffer_input.Dispose(); buffer_scale.Dispose(); buffer_offset.Dispose(); buffer_output.Dispose(); return(output); }
public void RunMultiplyShader() { VecMatPair[] data = new VecMatPair[5]; VecMatPair[] output = new VecMatPair[5]; // Init Data here!!! for (int i = 0; i < data.Length; i++) { data[i].point = UnityEngine.Random.onUnitSphere; data[i].matrix = Matrix4x4.TRS(UnityEngine.Random.onUnitSphere, UnityEngine.Random.rotation, UnityEngine.Random.onUnitSphere); Debug.Log("PreShader! Pos: " + data[i].point.ToString() + ", Matrix: " + data[i].matrix.ToString()); } ComputeBuffer buffer = new ComputeBuffer(data.Length, 76); int kernelHandle = shader.FindKernel("Multiply"); buffer.SetData(data); shader.SetBuffer(kernelHandle, "dataBuffer", buffer); shader.Dispatch(kernelHandle, data.Length, 1, 1); buffer.GetData(output); for (int i = 0; i < output.Length; i++) { Debug.Log("PostShader! Pos: " + output[i].point.ToString() + ", Matrix: " + output[i].matrix.ToString()); } buffer.Dispose(); /*public ComputeShader compute; public ComputeBuffer buffer; public int[] cols; void Start () { var mesh = GetComponent<MeshFilter>().mesh; int n = mesh.vertexCount; /// buffer = new ComputeBuffer (n, 16); /// cols = new int[n]; /// for (int i = 0; i < n; ++i) cols[i] = 0; buffer.SetData (cols); /// compute.SetBuffer(compute.FindKernel ("CSMain"),"bufColors", buffer); /// compute.Dispatch(0,4,4,1); /// buffer.GetData(cols); Debug.Log (cols[0]); */ }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; // NOISE VOLUME! RenderTexture DensityVolume = new RenderTexture(16, 16, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.sRGB); DensityVolume.volumeDepth = 16; DensityVolume.isVolume = true; DensityVolume.enableRandomWrite = true; DensityVolume.filterMode = FilterMode.Bilinear; DensityVolume.wrapMode = TextureWrapMode.Repeat; DensityVolume.Create(); int mgen_id = CShaderSimplex.FindKernel("FillEmpty"); // uses renderTexture rather than StructuredBuffer? CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); // Links RenderTexture to the "Result" RWTexture in the compute shader? CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // run computeShader "FillEmpty" with 1 x 1 x 31 threadGroups? mgen_id = CShaderSimplex.FindKernel("Simplex3d"); CShaderSimplex.SetTexture(mgen_id, "Result", DensityVolume); CShaderSimplex.Dispatch(mgen_id, 1, 1, 16); // Fill shared RenderTexture with GPU simplex Noise ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4)); cBufferSegmentTransform.SetData(critterSegmentTransforms); int kernelID = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform); CShaderBuildMC.SetTexture(kernelID, "noise_volume", DensityVolume); // Noise 3D texture //Debug.Log(DensityVolume.colorBuffer.ToString()); // Figure out how many chunks are needed: int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x / (cellResolution * 8f)); int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y / (cellResolution * 8f)); int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z / (cellResolution * 8f)); //Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")"); int totalNumChunks = numChunksX * numChunksY * numChunksZ; Poly[][] PolyArrayArray = new Poly[totalNumChunks][]; // This will hold the mesh data from the chunks calculated on the GPU int[] numPolysArray = new int[totalNumChunks]; int totalNumPolys = 0; // Get each chunk! int chunkIndex = 0; for(int x = 0; x < numChunksX; x++) { for(int y = 0; y < numChunksY; y++) { for(int z = 0; z < numChunksZ; z++) { // Figure out chunk offset amount: Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z) + GlobalBoundingBoxOffset - (GlobalBoundingBoxDimensions / 2f); int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x); CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y); CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z); CShaderBuildMC.SetFloat("_CellSize", cellResolution); CShaderBuildMC.SetVector("_ColorPrimary", colorPrimary); CShaderBuildMC.SetVector("_ColorSecondary", colorSecondary); CShaderBuildMC.SetFloat("_ColorNoiseScale", colorNoiseScale); CShaderBuildMC.SetFloat("_ColorSmlAmplitude", colorSmlAmplitude); CShaderBuildMC.SetFloat("_ColorMedAmplitude", colorMedAmplitude); CShaderBuildMC.SetFloat("_ColorLrgAmplitude", colorLrgAmplitude); CShaderBuildMC.SetFloat("_ColorContrast", colorContrast); CShaderBuildMC.SetFloat("_ColorThreshold", colorThreshold); CShaderBuildMC.SetVector("_SkinNoiseScale", skinNoiseScale); CShaderBuildMC.SetFloat("_SkinNoiseAmplitude", skinNoiseAmplitude); CShaderBuildMC.SetVector("_SkinLocalTaper", skinLocalTaper); CShaderBuildMC.SetVector("_SkinLocalSinFreq", skinLocalSinFreq); CShaderBuildMC.SetVector("_SkinLocalSinAmp", skinLocalSinAmp); // Local Segment-space modifications, sin, taper, etc. CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys //Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkOffset: " + chunkOffset.ToString()); totalNumPolys += numPolys[0]; numPolysArray[chunkIndex] = numPolys[0]; if(numPolys[0] > 0) { // only do this if there was at least 1 triangle in the test pass Poly[] polyArray = new Poly[numPolys[0]]; int cBufferStride = sizeof(float) * (18 + 9 + 6) + sizeof(int) * (6); ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], cBufferStride); // 18 floats x 4 bytes/float = 72 + COLORS! 9 x 4 = 36 = 108 + BONES! 6x4 = 24 + 6 xint... cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU PolyArrayArray[chunkIndex] = polyArray; cBuffer.Dispose(); } cBufferNumPoly.Dispose(); chunkIndex++; } } } CritterDecorationsTest.decorationStruct[] points = new CritterDecorationsTest.decorationStruct[totalNumPolys]; //Construct mesh using received data int vindex = 0; int decindex = 0; // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[totalNumPolys * 3]; Color[] colors = new Color[totalNumPolys * 3]; int[] tris = new int[totalNumPolys * 3]; Vector2[] uvs = new Vector2[totalNumPolys * 3]; Vector3[] normals = new Vector3[totalNumPolys * 3]; BoneWeight[] weights = new BoneWeight[totalNumPolys * 3]; //Parse triangles for(int i = 0; i < PolyArrayArray.Length; i++) { if(numPolysArray[i] > 0) { // only do this if there was at least 1 triangle in the test pass for (int ix = 0; ix < numPolysArray[i]; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CAR, PolyArrayArray[i][ix].CAG, PolyArrayArray[i][ix].CAB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexA0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexA1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightA0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightA1; points[decindex].pos = vPos; points[decindex].normal = normals[vindex]; points[decindex].color = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b); decindex++; vindex++; //B1,B2,B3 vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CBR, PolyArrayArray[i][ix].CBG, PolyArrayArray[i][ix].CBB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexB0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexB1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightB0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightB1; vindex++; //C1,C2,C3 vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); colors[vindex] = new Color(PolyArrayArray[i][ix].CCR, PolyArrayArray[i][ix].CCG, PolyArrayArray[i][ix].CCB, 1.0f); weights[vindex].boneIndex0 = PolyArrayArray[i][ix].BoneIndexC0; weights[vindex].boneIndex1 = PolyArrayArray[i][ix].BoneIndexC1; weights[vindex].weight0 = PolyArrayArray[i][ix].BoneWeightC0; weights[vindex].weight1 = PolyArrayArray[i][ix].BoneWeightC1; vindex++; } } } //We have got all data and are ready to setup a new mesh! Mesh newMesh = new Mesh(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.colors = colors; newMesh.Optimize(); // Set up SKINNING!!!: Transform[] bones = new Transform[critter.critterSegmentList.Count]; Matrix4x4[] bindPoses = new Matrix4x4[critter.critterSegmentList.Count]; // Try just using existing critter's GameObjects/Transforms: for(int seg = 0; seg < critter.critterSegmentList.Count; seg++) { bones[seg] = critter.critterSegmentList[seg].transform; bindPoses[seg] = bones[seg].worldToLocalMatrix * transform.localToWorldMatrix; // ????????????????? // the bind pose is the inverse of inverse transformation matrix of the bone, when the bone is in the bind pose .... unhelpful .... } newMesh.boneWeights = weights; newMesh.bindposes = bindPoses; SkinnedMeshRenderer skinnedMeshRenderer = this.GetComponent<SkinnedMeshRenderer>(); skinnedMeshRenderer.bones = bones; skinnedMeshRenderer.sharedMesh = newMesh; skinnedMeshRenderer.enabled = true; cBufferSegmentTransform.Release(); critterDecorationsTest.TurnOn(points); float calcTime = Time.realtimeSinceStartup - startTime; Debug.Log("MeshCreated! " + calcTime.ToString()); }
private void InitTerrain() { int meshGridSize = 16; int numTerrainMeshVertices = meshGridSize * meshGridSize; terrainMeshBuffer = new ComputeBuffer(numTerrainMeshVertices, sizeof(float) * (3 + 3 + 2 + 4)); int numStrokesPerVertX = 16; int numStrokesPerVertZ = 16; int numTerrainStrokes = meshGridSize * meshGridSize * numStrokesPerVertX * numStrokesPerVertZ; terrainStrokesBuffer = new ComputeBuffer(numTerrainStrokes, sizeof(float) * (3 + 3 + 3 + 3 + 3 + 2) + sizeof(int) * 1); //terrainGeneratorCompute = new ComputeShader(); int kernel_id = terrainGeneratorCompute.FindKernel("CSMain"); terrainGeneratorCompute.SetFloat("_GridSideLength", terrainSize); terrainGeneratorCompute.SetFloat("_NoiseFrequency", terrainNoiseFrequency); terrainGeneratorCompute.SetFloat("_NoiseAmplitude", terrainNoiseAmplitude); terrainGeneratorCompute.SetFloat("_GroundHeight", terrainAltitude); terrainGeneratorCompute.SetInt("_NumGroupsX", numStrokesPerVertX); terrainGeneratorCompute.SetInt("_NumGroupsZ", numStrokesPerVertZ); terrainGeneratorCompute.SetBuffer(kernel_id, "buf_StrokeData", terrainStrokesBuffer); terrainGeneratorCompute.SetBuffer(kernel_id, "buf_MeshData", terrainMeshBuffer); meshData[] meshDataArray = new meshData[numTerrainMeshVertices]; // memory to receive data from computeshader terrainGeneratorCompute.Dispatch(kernel_id, numStrokesPerVertX, 1, numStrokesPerVertZ); // fill buffers terrainMeshBuffer.GetData(meshDataArray); // download mesh Data // generate Mesh from data: //Construct mesh using received data // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[numTerrainMeshVertices]; Color[] colors = new Color[numTerrainMeshVertices]; int[] tris = new int[2 * (meshGridSize - 1) * (meshGridSize - 1) * 3]; Vector2[] uvs = new Vector2[numTerrainMeshVertices]; Vector3[] normals = new Vector3[numTerrainMeshVertices]; for(int i = 0; i < numTerrainMeshVertices; i++) { vertices[i] = meshDataArray[i].pos; normals[i] = meshDataArray[i].normal; uvs[i] = meshDataArray[i].uv; colors[i] = meshDataArray[i].color; } // Figure out triangles: int index = 0; int numSquares = meshGridSize - 1; for (int y = 0; y < numSquares; y++) { for(int x = 0; x < numSquares; x++) { // counterclockwise winding order: tris[index] = ((y + 1) * meshGridSize) + x; tris[index + 1] = (y * meshGridSize) + x + 1; tris[index + 2] = (y * meshGridSize) + x; tris[index + 3] = ((y + 1) * meshGridSize) + x; tris[index + 4] = ((y + 1) * meshGridSize) + x + 1; tris[index + 5] = (y * meshGridSize) + x + 1; index = index + 6; } } Mesh terrainMesh = new Mesh(); terrainMesh.vertices = vertices; terrainMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); terrainMesh.triangles = tris; terrainMesh.normals = normals; //NewMesh.RecalculateNormals(); terrainMesh.colors = colors; terrainMesh.RecalculateNormals(); terrainMesh.RecalculateBounds(); trainerTerrainManager.GetComponent<MeshFilter>().sharedMesh = terrainMesh; trainerTerrainManager.GetComponent<MeshCollider>().sharedMesh = terrainMesh; terrainMeshBuffer.Release(); terrainMeshBuffer.Dispose(); }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys Debug.Log("cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString()); _MaxBufferSize = numPolys[0]; Poly[] polyArray = new Poly[_MaxBufferSize]; ComputeBuffer cBuffer = new ComputeBuffer(_MaxBufferSize, 72); // 18 floats x 4 bytes/float = 72 cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU //Construct mesh using received data Mesh newMesh = new Mesh(); int vindex = 0; //int count = 0; //Count real data length --- Looks like there might be wasted data??? -- investigate how to Optimize /*for (count = 0; count < _MaxBufferSize; count++) { if (polyArray[count].A1 == 0.0f && polyArray[count].B1 == 0.0f && polyArray[count].C1 == 0.0 && polyArray[count].A2 == 0.0f && polyArray[count].B2 == 0.0f && polyArray[count].C2 == 0.0 && polyArray[count].A3 == 0.0f && polyArray[count].B3 == 0.0f && polyArray[count].C3 == 0.0) { break; } }*/ //Debug.Log(count+" triangles got"); // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[_MaxBufferSize * 3]; int[] tris = new int[_MaxBufferSize * 3]; Vector2[] uvs = new Vector2[_MaxBufferSize * 3]; Vector3[] normals = new Vector3[_MaxBufferSize * 3]; //Parse triangles for (int ix = 0; ix < _MaxBufferSize; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(polyArray[ix].A1, polyArray[ix].A2, polyArray[ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NA1, polyArray[ix].NA2, polyArray[ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //B1,B2,B3 vPos = new Vector3(polyArray[ix].B1, polyArray[ix].B2, polyArray[ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NB1, polyArray[ix].NB2, polyArray[ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //C1,C2,C3 vPos = new Vector3(polyArray[ix].C1, polyArray[ix].C2, polyArray[ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(polyArray[ix].NC1, polyArray[ix].NC2, polyArray[ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; } //We have got all data and are ready to setup a new mesh! //newMesh.Clear(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.RecalculateNormals(); newMesh.Optimize(); cBuffer.Dispose(); cBufferNumPoly.Dispose(); //cBuffer.Release(); this.GetComponent<MeshFilter>().sharedMesh = newMesh; }
public void BuildMesh() { float startTime = Time.realtimeSinceStartup; // CritterSegmentTransforms!! SegmentTransform[] critterSegmentTransforms = new SegmentTransform[2]; Quaternion rot = Quaternion.Euler(55f, 12f, -230f); Quaternion rot2 = Quaternion.Euler(-35f, 112f, -67f); SegmentTransform segmentTransform; segmentTransform.PX = 10f; segmentTransform.PY = 8f; segmentTransform.PZ = 13f; segmentTransform.RX = rot.x; segmentTransform.RY = rot.y; segmentTransform.RZ = rot.z; segmentTransform.RW = rot.w; segmentTransform.SX = 6f; segmentTransform.SY = 7f; segmentTransform.SZ = 2.5f; SegmentTransform segmentTransform2; segmentTransform2.PX = 22f; segmentTransform2.PY = 11f; segmentTransform2.PZ = 15f; segmentTransform2.RX = rot2.x; segmentTransform2.RY = rot2.y; segmentTransform2.RZ = rot2.z; segmentTransform2.RW = rot2.w; segmentTransform2.SX = 9f; segmentTransform2.SY = 3f; segmentTransform2.SZ = 7f; critterSegmentTransforms[0] = segmentTransform; critterSegmentTransforms[1] = segmentTransform2; ComputeBuffer cBufferSegmentTransform = new ComputeBuffer(critterSegmentTransforms.Length, sizeof(float) * (3 + 3 + 4)); cBufferSegmentTransform.SetData(critterSegmentTransforms); int kernelID = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetBuffer(kernelID, "segmentTransformBuffer", cBufferSegmentTransform); // Figure out how many chunks are needed: int numChunksX = Mathf.CeilToInt(GlobalBoundingBoxDimensions.x * cellResolution / 8f); int numChunksY = Mathf.CeilToInt(GlobalBoundingBoxDimensions.y * cellResolution / 8f); int numChunksZ = Mathf.CeilToInt(GlobalBoundingBoxDimensions.z * cellResolution / 8f); Debug.Log("numChunks: (" + numChunksX.ToString() + ", " + numChunksY.ToString() + ", " + numChunksZ.ToString() + ")"); int totalNumChunks = numChunksX * numChunksY * numChunksZ; Poly[][] PolyArrayArray = new Poly[totalNumChunks][]; // This will hold the mesh data from the chunks calculated on the GPU int[] numPolysArray = new int[totalNumChunks]; int totalNumPolys = 0; // Get each chunk! int chunkIndex = 0; for(int x = 0; x < numChunksX; x++) { for(int y = 0; y < numChunksY; y++) { for(int z = 0; z < numChunksZ; z++) { // Figure out chunk offset amount: Vector3 chunkOffset = new Vector3(cellResolution * 8f * x, cellResolution * 8f * y, cellResolution * 8f * z); int[] numPolys = new int[1]; ComputeBuffer cBufferNumPoly = new ComputeBuffer(1, sizeof(int)); cBufferNumPoly.SetData(numPolys); int id = CShaderBuildMC.FindKernel("CSMain"); CShaderBuildMC.SetInt("_CalcNumPolys", 1); // only calculate how many tris so I can correctly size the poly buffer CShaderBuildMC.SetFloat("_GlobalOffsetX", chunkOffset.x); CShaderBuildMC.SetFloat("_GlobalOffsetY", chunkOffset.y); CShaderBuildMC.SetFloat("_GlobalOffsetZ", chunkOffset.z); CShaderBuildMC.SetBuffer(id, "numPolyBuffer", cBufferNumPoly); CShaderBuildMC.Dispatch(id, 1, 1, 1); // calc num polys cBufferNumPoly.GetData(numPolys); // get numPolys Debug.Log("Chunk: " + (z + (numChunksZ * y) + (numChunksZ * numChunksY * x)).ToString() + ", cBufferNumPoly.GetData(numPolys): " + numPolys[0].ToString() + ", chunkIndex: " + chunkIndex.ToString()); totalNumPolys += numPolys[0]; numPolysArray[chunkIndex] = numPolys[0]; //_MaxBufferSize = numPolys[0]; if(numPolys[0] > 0) { // only do this if there was at least 1 triangle in the test pass Poly[] polyArray = new Poly[numPolys[0]]; ComputeBuffer cBuffer = new ComputeBuffer(numPolys[0], 72); // 18 floats x 4 bytes/float = 72 cBuffer.SetData(polyArray); CShaderBuildMC.SetBuffer(id, "buffer", cBuffer); CShaderBuildMC.SetInt("_CalcNumPolys", 0); // Actually calc tris CShaderBuildMC.Dispatch(id, 1, 1, 1); cBuffer.GetData(polyArray); // return data from GPU PolyArrayArray[chunkIndex] = polyArray; cBuffer.Dispose(); } cBufferNumPoly.Dispose(); chunkIndex++; } } } //Construct mesh using received data Mesh newMesh = new Mesh(); int vindex = 0; // Why same number of tris as vertices? == // because all triangles have duplicate verts - no shared vertices? Vector3[] vertices = new Vector3[totalNumPolys * 3]; int[] tris = new int[totalNumPolys * 3]; Vector2[] uvs = new Vector2[totalNumPolys * 3]; Vector3[] normals = new Vector3[totalNumPolys * 3]; //Parse triangles for(int i = 0; i < PolyArrayArray.Length; i++) { if(numPolysArray[i] > 0) { // only do this if there was at least 1 triangle in the test pass for (int ix = 0; ix < numPolysArray[i]; ix++) { Vector3 vPos; Vector3 vOffset = new Vector3(0, 0, 0); //??? offsets all vertices by this amount, but why 30?? //A1,A2,A3 vPos = new Vector3(PolyArrayArray[i][ix].A1, PolyArrayArray[i][ix].A2, PolyArrayArray[i][ix].A3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NA1, PolyArrayArray[i][ix].NA2, PolyArrayArray[i][ix].NA3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //B1,B2,B3 vPos = new Vector3(PolyArrayArray[i][ix].B1, PolyArrayArray[i][ix].B2, PolyArrayArray[i][ix].B3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NB1, PolyArrayArray[i][ix].NB2, PolyArrayArray[i][ix].NB3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; //C1,C2,C3 vPos = new Vector3(PolyArrayArray[i][ix].C1, PolyArrayArray[i][ix].C2, PolyArrayArray[i][ix].C3) + vOffset; vertices[vindex] = vPos * _Scale; normals[vindex] = new Vector3(PolyArrayArray[i][ix].NC1, PolyArrayArray[i][ix].NC2, PolyArrayArray[i][ix].NC3); tris[vindex] = vindex; uvs[vindex] = new Vector2(vertices[vindex].z, vertices[vindex].x); vindex++; } } } //We have got all data and are ready to setup a new mesh! //newMesh.Clear(); newMesh.vertices = vertices; newMesh.uv = uvs; //Unwrapping.GeneratePerTriangleUV(NewMesh); newMesh.triangles = tris; newMesh.normals = normals; //NewMesh.RecalculateNormals(); newMesh.RecalculateNormals(); newMesh.Optimize(); //cBuffer.Dispose(); //cBufferNumPoly.Dispose(); //cBuffer.Release(); cBufferSegmentTransform.Release(); this.GetComponent<MeshFilter>().sharedMesh = newMesh; float calcTime = Time.realtimeSinceStartup - startTime; Debug.Log("MeshCreated! " + calcTime.ToString()); }
/// <summary> /// Applies a custom kernel to an image. /// </summary> /// <param name="source">The texture to apply the kernel to.</param> /// <param name="destination">The texture to contain the result of the kernel operation.</param> /// <param name="kernel">The kernel to apply. ( Must be n x n size, 1D represented as row by row, bottom to top. )</param> /// <param name="filterFactor">The amount to divide the result of the kernel operation with. ( if left empty, will assume division by sum. )</param> public void ApplyCustomKernel(RenderTexture source, RenderTexture destination, int[] kernel, int filterFactor = -1) { // Declares a compute buffer to hold the kernel and other needed parameters. Its the size of the array // plus 3 other variables, the strie is the size of an int and its a standard structured buffer. ComputeBuffer buf = new ComputeBuffer(kernel.Length + 3, sizeof(int), ComputeBufferType.Default); // Create a new array and put in all the needed variables. int[] newArray = new int[kernel.Length + 3]; // Find out if its an equal or non-equal kernel. newArray[0] = kernel.Length % 2; // Put in the filter factor. If default use the sum of the kernel, otherwise use specified filterFactor. if (filterFactor == -1) newArray[1] = kernel.Sum(); else newArray[1] = filterFactor; // Lenght of the kernel newArray[2] = (int)Math.Sqrt(kernel.Length); // Copy in the kernel to the new array Array.Copy(kernel, 0, newArray, 3, kernel.Length); // Put the new array into the buffer. buf.SetData(newArray); // Call the compute shader function with the needed parameters. CustomKernelCall(source, destination, buf); // Discard the compute buffer to avoid memleak buf.Dispose(); }