Dispose() public method

public Dispose ( ) : void
return void
 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
 }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
    // 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();
    }
Esempio n. 4
0
        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));
     }
 }
Esempio n. 6
0
 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);
     }
 }
Esempio n. 7
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());
    }
Esempio n. 13
0
    /// <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();
    }