예제 #1
0
    void BitonicSort_fastest(ComputeBuffer gpu_data)
    {
        int n = gpu_data.count;

        //引数をセット
        shader.SetBuffer(kernel_ParallelBitonic_B16, "data", gpu_data);
        shader.SetBuffer(kernel_ParallelBitonic_B8, "data", gpu_data);
        shader.SetBuffer(kernel_ParallelBitonic_B4, "data", gpu_data);
        shader.SetBuffer(kernel_ParallelBitonic_B2, "data", gpu_data);
        shader.SetBuffer(kernel_ParallelBitonic_C4, "data", gpu_data);
        shader.SetBuffer(kernel_ParallelBitonic_C2, "data", gpu_data);

        int nlog = (int)(Mathf.Log(n, 2));
        int B_indx, inc;
        int kernel_id;

        for (int i = 0; i < nlog; i++)
        {
            inc = 1 << i;
            for (int j = 0; j < i + 1; j++)
            {
                if (inc <= 128)
                {
                    break;            //あとはshared memory内におさまるので
                }
                if (inc >= 2048)
                {
                    B_indx    = 16;
                    kernel_id = kernel_ParallelBitonic_B16;
                }
                else if (inc >= 1024)
                {
                    B_indx    = 8;
                    kernel_id = kernel_ParallelBitonic_B8;
                }
                else if (inc >= 512)
                {
                    B_indx    = 4;
                    kernel_id = kernel_ParallelBitonic_B4;
                }
                else
                {
                    B_indx    = 2;
                    kernel_id = kernel_ParallelBitonic_B2;
                }


                shader.SetInt("inc", inc * 2 / B_indx);
                shader.SetInt("dir", 2 << i);
                shader.Dispatch(kernel_id, n / B_indx / THREADNUM_X, 1, 1);
                inc /= B_indx;
            }

            //これ以降はshared memoryに収まりそうなサイズなので
            shader.SetInt("inc0", inc);
            shader.SetInt("dir", 2 << i);
            if ((inc == 8) | (inc == 32) | (inc == 128))
            {
                shader.Dispatch(kernel_ParallelBitonic_C4, n / 4 / 64, 1, 1);
            }
            else
            {
                shader.Dispatch(kernel_ParallelBitonic_C2, n / 2 / 128, 1, 1);
            }
        }//ループの終わり
    }
예제 #2
0
    /*void LoadSkyMaps()
     * {
     *  skybox_material = new Material(skybox_shader);
     *  m_cam = gameObject.GetComponent<Camera>();
     *  m_cam.depthTextureMode = DepthTextureMode.DepthNormals;
     *
     *      //Transmittance is responsible for the change in the sun color as it moves
     *      //The raw file is a 2D array of 32 bit floats with a range of 0 to 1
     *      string path = Application.dataPath + m_filePath + "/transmittance.raw";
     *
     *      rt_transmittanceT = new RenderTexture(TRANSMITTANCE_W, TRANSMITTANCE_H, 0, RenderTextureFormat.ARGBFloat);
     *      rt_transmittanceT.wrapMode = TextureWrapMode.Clamp;
     *      rt_transmittanceT.filterMode = FilterMode.Bilinear;
     *      rt_transmittanceT.enableRandomWrite = true;
     *      rt_transmittanceT.Create();
     *
     *      ComputeBuffer buffer = new ComputeBuffer(TRANSMITTANCE_W*TRANSMITTANCE_H, sizeof(float)*3);
     *      CBUtility.WriteIntoRenderTexture(rt_transmittanceT, 3, path, buffer, m_writeData);
     *      buffer.Release();
     *
     *      //Iirradiance is responsible for the change in the sky color as the sun moves
     *      //The raw file is a 2D array of 32 bit floats with a range of 0 to 1
     *      path = Application.dataPath + m_filePath + "/irradiance.raw";
     *
     *      rt_irradianceT[READ] = new RenderTexture(SKY_W, SKY_H, 0, RenderTextureFormat.ARGBFloat);
     *      rt_irradianceT[READ].wrapMode = TextureWrapMode.Clamp;
     *      rt_irradianceT[READ].filterMode = FilterMode.Bilinear;
     *      rt_irradianceT[READ].enableRandomWrite = true;
     *      rt_irradianceT[READ].Create();
     *
     *      buffer = new ComputeBuffer(SKY_W*SKY_H, sizeof(float)*3);
     *      CBUtility.WriteIntoRenderTexture(rt_irradianceT[READ], 3, path, buffer, m_writeData);
     *      buffer.Release();
     *
     *      //Inscatter is responsible for the change in the sky color as the sun moves
     *      //The raw file is a 4D array of 32 bit floats with a range of 0 to 1.589844
     *      //As there is not such thing as a 4D texture the data is packed into a 3D texture
     *      //and the shader manually performs the sample for the 4th dimension
     *      path = Application.dataPath + m_filePath + "/inscatter.raw";
     *
     *      rt_inscatterT[READ] = new RenderTexture(RES_MU_S * RES_NU, RES_MU, 0, RenderTextureFormat.ARGBFloat);
     *      rt_inscatterT[READ].volumeDepth = RES_R;
     *      rt_inscatterT[READ].wrapMode = TextureWrapMode.Clamp;
     *      rt_inscatterT[READ].filterMode = FilterMode.Bilinear;
     *      rt_inscatterT[READ].isVolume = true;
     *      rt_inscatterT[READ].enableRandomWrite = true;
     *      rt_inscatterT[READ].Create();
     *
     *      buffer = new ComputeBuffer(RES_MU_S*RES_NU*RES_MU*RES_R, sizeof(float)*4);
     *      CBUtility.WriteIntoRenderTexture(rt_inscatterT[READ], 4, path, buffer, m_writeData);
     *      buffer.Release();
     *
     *      InitUniforms(skybox_material);
     * }
     */

    void Preprocess()
    {
        if (m_step == 0)
        {
            // computes transmittance texture T (line 1 in algorithm 4.1)
            m_transmittance.SetTexture(0, "transmittanceWrite", rt_transmittanceT);
            m_transmittance.Dispatch(0, TRANSMITTANCE_W / NUM_THREADS, TRANSMITTANCE_H / NUM_THREADS, 1);
        }
        else if (m_step == 1)
        {
            // computes irradiance texture deltaE (line 2 in algorithm 4.1)
            m_irradiance1.SetTexture(0, "transmittanceRead", rt_transmittanceT);
            m_irradiance1.SetTexture(0, "deltaEWrite", rt_deltaET);
            m_irradiance1.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1);


            //if(WRITE_DEBUG_TEX)
            //	SaveAs8bit(SKY_W, SKY_H, 4, "/deltaE_debug", rt_deltaET);
        }
        else if (m_step == 2)
        {
            // computes single scattering texture deltaS (line 3 in algorithm 4.1)
            // Rayleigh and Mie separated in deltaSR + deltaSM
            m_inscatter1.SetTexture(0, "transmittanceRead", rt_transmittanceT);
            m_inscatter1.SetTexture(0, "deltaSRWrite", rt_deltaSRT);
            m_inscatter1.SetTexture(0, "deltaSMWrite", rt_deltaSMT);

            //The inscatter calc's can be quite demanding for some cards so process
            //the calc's in layers instead of the whole 3D data set.
            for (int i = 0; i < RES_R; i++)
            {
                m_inscatter1.SetInt("layer", i);
                m_inscatter1.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1);
            }

            /*if(WRITE_DEBUG_TEX)
             *      SaveAs8bit(RES_MU_S*RES_NU, RES_MU*RES_R, 4, "/deltaSR_debug", rt_deltaSRT);
             *
             * if(WRITE_DEBUG_TEX)
             *      SaveAs8bit(RES_MU_S*RES_NU, RES_MU*RES_R, 4, "/deltaSM_debug", rt_deltaSMT);
             */
        }
        else if (m_step == 3)
        {
            // copies deltaE into irradiance texture E (line 4 in algorithm 4.1)
            m_copyIrradiance.SetFloat("k", 0.0f);
            m_copyIrradiance.SetTexture(0, "deltaERead", rt_deltaET);
            m_copyIrradiance.SetTexture(0, "irradianceRead", rt_irradianceT[READ]);
            m_copyIrradiance.SetTexture(0, "irradianceWrite", rt_irradianceT[WRITE]);
            m_copyIrradiance.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1);

            //RTUtility.Swap(rt_irradianceT);
        }
        else if (m_step == 4)
        {
            // copies deltaS into inscatter texture S (line 5 in algorithm 4.1)
            m_copyInscatter1.SetTexture(0, "deltaSRRead", rt_deltaSRT);
            m_copyInscatter1.SetTexture(0, "deltaSMRead", rt_deltaSMT);
            m_copyInscatter1.SetTexture(0, "inscatterWrite", rt_inscatterT[WRITE]);

            //The inscatter calc's can be quite demanding for some cards so process
            //the calc's in layers instead of the whole 3D data set.
            for (int i = 0; i < RES_R; i++)
            {
                m_copyInscatter1.SetInt("layer", i);
                m_copyInscatter1.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1);
            }

            RTUtility.Swap(rt_inscatterT);
        }
        else if (m_step == 5)
        {
            // computes deltaJ (line 7 in algorithm 4.1)
            m_inscatterS.SetInt("first", (m_order == 2) ? 1 : 0);
            m_inscatterS.SetTexture(0, "transmittanceRead", rt_transmittanceT);
            m_inscatterS.SetTexture(0, "deltaERead", rt_deltaET);
            m_inscatterS.SetTexture(0, "deltaSRRead", rt_deltaSRT);
            m_inscatterS.SetTexture(0, "deltaSMRead", rt_deltaSMT);
            m_inscatterS.SetTexture(0, "deltaJWrite", rt_deltaJT);

            //The inscatter calc's can be quite demanding for some cards so process
            //the calc's in layers instead of the whole 3D data set.
            for (int i = 0; i < RES_R; i++)
            {
                m_inscatterS.SetInt("layer", i);
                m_inscatterS.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1);
            }
        }
        else if (m_step == 6)
        {
            // computes deltaE (line 8 in algorithm 4.1)
            m_irradianceN.SetInt("first", (m_order == 2) ? 1 : 0);
            m_irradianceN.SetTexture(0, "deltaSRRead", rt_deltaSRT);
            m_irradianceN.SetTexture(0, "deltaSMRead", rt_deltaSMT);
            m_irradianceN.SetTexture(0, "deltaEWrite", rt_deltaET);
            m_irradianceN.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1);
        }
        else if (m_step == 7)
        {
            // computes deltaS (line 9 in algorithm 4.1)
            m_inscatterN.SetTexture(0, "transmittanceRead", rt_transmittanceT);
            m_inscatterN.SetTexture(0, "deltaJRead", rt_deltaJT);
            m_inscatterN.SetTexture(0, "deltaSRWrite", rt_deltaSRT);

            //The inscatter calc's can be quite demanding for some cards so process
            //the calc's in layers instead of the whole 3D data set.
            for (int i = 0; i < RES_R; i++)
            {
                m_inscatterN.SetInt("layer", i);
                m_inscatterN.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1);
            }
        }
        else if (m_step == 8)
        {
            // adds deltaE into irradiance texture E (line 10 in algorithm 4.1)
            m_copyIrradiance.SetFloat("k", 1.0f);
            m_copyIrradiance.SetTexture(0, "deltaERead", rt_deltaET);
            m_copyIrradiance.SetTexture(0, "irradianceRead", rt_irradianceT[READ]);
            m_copyIrradiance.SetTexture(0, "irradianceWrite", rt_irradianceT[WRITE]);
            m_copyIrradiance.Dispatch(0, SKY_W / NUM_THREADS, SKY_H / NUM_THREADS, 1);

            //RTUtility.Swap(rt_irradianceT);
        }
        else if (m_step == 9)
        {
            // adds deltaS into inscatter texture S (line 11 in algorithm 4.1)
            m_copyInscatterN.SetTexture(0, "deltaSRead", rt_deltaSRT);
            m_copyInscatterN.SetTexture(0, "inscatterRead", rt_inscatterT[READ]);
            m_copyInscatterN.SetTexture(0, "inscatterWrite", rt_inscatterT[WRITE]);

            //The inscatter calc's can be quite demanding for some cards so process
            //the calc's in layers instead of the whole 3D data set.
            for (int i = 0; i < RES_R; i++)
            {
                m_copyInscatterN.SetInt("layer", i);
                m_copyInscatterN.Dispatch(0, (RES_MU_S * RES_NU) / NUM_THREADS, RES_MU / NUM_THREADS, 1);
            }

            RTUtility.Swap(rt_inscatterT);

            if (m_order < 4)
            {
                m_step   = 4;
                m_order += 1;
            }
        }
        else if (m_step == 10)
        {
            ReleaseRT();
            m_finished = true;
        }
        m_step += 1;
    }
예제 #3
0
    // Use this for initialization
    void Start ()
    {

        ComputeBuffer uniform01Data = new ComputeBuffer(512*512,16);
        float[] uniform01Array=new float[512*512*4];
        for (int i = 0; i < 512*512 * 4; ++i)
        {
            uniform01Array[i] = Random.Range(0.00001f, 1.0f);
        }
        uniform01Data.SetData(uniform01Array);

        ComputeBuffer uniform01Data2 = new ComputeBuffer(512 * 512, 16);
        float[] uniform01Array2 = new float[512 * 512 * 4];
        for (int i = 0; i < 512 * 512 * 4; ++i)
        {
            uniform01Array2[i] = Random.Range(0.00001f, 1.0f);
        }
        uniform01Data2.SetData(uniform01Array2);

        heightTex0=new RenderTexture(512,512,0,RenderTextureFormat.ARGBFloat);
        heightTex0.enableRandomWrite = true;
        heightTex0.filterMode = FilterMode.Bilinear;
        heightTex0.Create();
            
        pingpong01 = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        pingpong01.enableRandomWrite = true;
        pingpong01.filterMode = FilterMode.Bilinear;
        pingpong01.Create();

        pingpong02 = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        pingpong02.enableRandomWrite = true;
        pingpong02.filterMode = FilterMode.Bilinear;
        pingpong02.Create();

        pingpong[0] = pingpong01;
        pingpong[1] = pingpong02;



        pingpong01CP = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        pingpong01CP.enableRandomWrite = true;
        pingpong01CP.filterMode = FilterMode.Bilinear;
        pingpong01CP.Create();

        pingpong02CP = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        pingpong02CP.enableRandomWrite = true;
        pingpong02CP.filterMode = FilterMode.Bilinear;
        pingpong02CP.Create();

        pingpongCP[0] = pingpong01CP;
        pingpongCP[1] = pingpong02CP;


        butterfly = new RenderTexture(9, 512, 0, RenderTextureFormat.ARGBFloat);
        butterfly.enableRandomWrite = true;
        butterfly.filterMode = FilterMode.Bilinear;
        butterfly.Create();

        finalPassOutput = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        finalPassOutput.enableRandomWrite = true;
        finalPassOutput.filterMode = FilterMode.Bilinear;
        finalPassOutput.wrapMode = TextureWrapMode.Repeat;
        finalPassOutput.Create();
       

        normalMap = new RenderTexture(512, 512, 0, RenderTextureFormat.ARGBFloat);
        normalMap.enableRandomWrite = true;
        normalMap.filterMode = FilterMode.Bilinear;
        normalMap.wrapMode = TextureWrapMode.Repeat;
        normalMap.Create();
        

        int[] revIndices = new int[512];
        for (int i = 0; i < 512; ++i)
        {
            revIndices[i] = i;
        }

        int[] test= RadixSortByBits(revIndices,9);
        Debug.Log(string.Join(", ", value: test.Select(e=>e.ToString()).ToArray()));
        ComputeBuffer reserveBit = new ComputeBuffer(512,4);
        reserveBit.SetData(test);


        int k = OceanComputeShader.FindKernel("Height0");
        OceanComputeShader.SetTexture(k, "Height0Tex", heightTex0);
        OceanComputeShader.SetFloat("unit",100);
        OceanComputeShader.SetInt("N",512);
        OceanComputeShader.SetVector("windDirection",new Vector4(1,1,0,0));
        OceanComputeShader.SetFloat("windSpeed",10);
        OceanComputeShader.SetFloat("A", 2f);
        OceanComputeShader.SetFloat("gravity",9.81f);
        OceanComputeShader.SetBuffer(k, "uniform01Data", uniform01Data);
        OceanComputeShader.SetBuffer(k, "uniform01Data2", uniform01Data2);
        OceanComputeShader.Dispatch(k,512/8,512/8,1);

       

        int k3 = OceanComputeShader.FindKernel("Butterfly");
        OceanComputeShader.SetBuffer(k3, "reserveBit", reserveBit);
        OceanComputeShader.SetTexture(k3, "ButterflyTex", butterfly);
        OceanComputeShader.Dispatch(k3, 9, 512 / 8, 1);



      
       // Mat.SetTexture("_MainTex", butterfly);
        uniform01Data.Release();
        uniform01Data2.Release();
        reserveBit.Release();

    }
예제 #4
0
        public List <PackedUniformVolume> Reduce(PackedUniformVolume packedUniformVolume)
        {
            // Calculate the size of the array containing all the voxel data for all layers
            var bitCount = 0;

            for (var i = 0; i <= packedUniformVolume.Depth; i++)
            {
                bitCount += PackedUniformVolume.GetVolumeBitCount(i);
            }

            var dataCount = (int)math.ceil(bitCount / 32.0);

            // Setup an buffer that will contain all the reduction layers and fill it with the finest layer values
            // To start the reduction process
            var packedVolumes = new ComputeBuffer(dataCount, sizeof(uint));

            packedVolumes.SetData(packedUniformVolume.Voxels);
            _reduceComputeShader.SetBuffer(_reduceKernelId, "packed_volumes", packedVolumes);

            // Setup an buffer that will contain all the hashed reduction layers
            var hashedVolumes = new ComputeBuffer(bitCount, sizeof(uint));

            _reduceComputeShader.SetBuffer(_reduceKernelId, "hashed_volumes", hashedVolumes);

            // Bit offsets to use when reading from src layer or writing to the dst layer
            var dstPackedVolumeStartOffsetBitIndex = 0;

            var dstHashedVolumeStartOffsetIndex = 0;

            for (var i = packedUniformVolume.Depth; i > 0; i--)
            {
                // Set the src packed volume to the dst packed volume for next iteration
                var srcPackedVolumeStartOffsetBitIndex = dstPackedVolumeStartOffsetBitIndex;

                var srcHashedVolumeStartOffsetIndex = dstHashedVolumeStartOffsetIndex;

                // Assign the dimensions of the source volume
                var srcPackedVolumeBitDimensions = PackedUniformVolume.GetVolumeBitDimensions(i);
                _reduceComputeShader.SetInts("src_packed_volume_bit_dimensions", srcPackedVolumeBitDimensions.x, srcPackedVolumeBitDimensions.y, srcPackedVolumeBitDimensions.z);
                // Assign the offset to use when reading bits from the src layer
                _reduceComputeShader.SetInt("src_packed_volume_start_offset_bit_index", srcPackedVolumeStartOffsetBitIndex);

                // Assign dimensions of the destination volume
                var dstPackedVolumeBitDimensions = srcPackedVolumeBitDimensions / 2;
                _reduceComputeShader.SetInts("dst_packed_volume_bit_dimensions", dstPackedVolumeBitDimensions.x, dstPackedVolumeBitDimensions.y, dstPackedVolumeBitDimensions.z);
                // Increment destination offset so we write to the area reserved for the next layer
                dstPackedVolumeStartOffsetBitIndex += PackedUniformVolume.GetVolumeBitCount(i);
                _reduceComputeShader.SetInt("dst_packed_volume_start_offset_bit_index", dstPackedVolumeStartOffsetBitIndex);


                _reduceComputeShader.SetInts("src_hashed_volume_dimensions", srcPackedVolumeBitDimensions.x, srcPackedVolumeBitDimensions.y, srcPackedVolumeBitDimensions.z);
                _reduceComputeShader.SetInt("src_hashed_volume_start_offset_index", srcHashedVolumeStartOffsetIndex);

                _reduceComputeShader.SetInts("dst_hashed_volume_dimensions", dstPackedVolumeBitDimensions.x, dstPackedVolumeBitDimensions.y, dstPackedVolumeBitDimensions.z);
                // Increment destination offset so we write to the area reserved for the next layer
                dstHashedVolumeStartOffsetIndex += PackedUniformVolume.GetVolumeBitCount(i);
                _reduceComputeShader.SetInt("dst_hashed_volume_start_offset_index", dstHashedVolumeStartOffsetIndex);


                // Dispatch to the GPU. /8 is used for better utilization of the GPU
                var dispatchVolumeDimensions = math.max(new int3(1), dstPackedVolumeBitDimensions / 8);
                _reduceComputeShader.Dispatch(
                    _reduceKernelId,
                    dispatchVolumeDimensions.x,
                    dispatchVolumeDimensions.y,
                    dispatchVolumeDimensions.z
                    );
            }

            //Collect all the reduction data from the gpu
            var reducedPackedVolumes = new uint[dataCount];

            packedVolumes.GetData(reducedPackedVolumes);

            var reducedHashedVolumes = new uint[bitCount];

            hashedVolumes.GetData(reducedHashedVolumes);

            var packedVolumeList        = new List <PackedUniformVolume>();
            var voxelWorldScaleInMeters = packedUniformVolume.VoxelWorldScaleInMeters;

            var bitOffset = 0;

            for (var i = packedUniformVolume.Depth; i > 0; i--)
            {
                bitCount = PackedUniformVolume.GetVolumeBitCount(i);
                var intCount  = (int)math.ceil(bitCount / 32.0);
                var intOffset = (int)math.ceil(bitOffset / 32.0);
                packedVolumeList.Add(new PackedUniformVolume(voxelWorldScaleInMeters, i)
                {
                    Voxels = reducedPackedVolumes.Skip(intOffset).Take(intCount).ToArray(),
                    Hashes = reducedHashedVolumes.Skip(bitOffset).Take(bitCount).ToArray()
                });

                bitOffset += bitCount;

                voxelWorldScaleInMeters *= 2;
            }

            packedVolumes.Dispose();

            DEBUG = packedVolumeList;

            return(packedVolumeList);
        }
예제 #5
0
        void RenderAsSolid()
        {
            CreateSolidMaterial();

            // TODO: camera
            var camera = Camera.main;

            int width  = camera.pixelWidth;
            int height = camera.pixelHeight;
            int size   = Math.Max(Mathf.NextPowerOfTwo(width), Mathf.NextPowerOfTwo(height));

            if (rt == null || rt.width != camera.pixelWidth || rt.height != camera.pixelHeight)
            {
                rt?.Release();
                rt = new RenderTexture(width, height, 24, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
                rt.enableRandomWrite = true;
                rt.autoGenerateMips  = false;
                rt.useMipMap         = false;
                rt.Create();

                rtPos?.Release();
                rtPos = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
                rtPos.enableRandomWrite = true;
                rtPos.autoGenerateMips  = false;
                rtPos.useMipMap         = false;
                rtPos.Create();

                rtMask?.Release();
                rtMask = new RenderTexture(width, height, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
                rtMask.enableRandomWrite = true;
                rtMask.autoGenerateMips  = false;
                rtMask.useMipMap         = false;
                rtMask.Create();

                rtPosition?.Release();
                rtPosition = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
                rtPosition.enableRandomWrite = true;
                rtPosition.autoGenerateMips  = false;
                rtPosition.useMipMap         = true;
                rtPosition.Create();

                rtColor?.Release();
                rtColor = new RenderTexture(size, size, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
                rtColor.enableRandomWrite = true;
                rtColor.autoGenerateMips  = false;
                rtColor.useMipMap         = true;
                rtColor.Create();

                rtDepth?.Release();
                rtDepth = new RenderTexture(size, size, 0, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear);
                rtDepth.enableRandomWrite = true;
                rtDepth.autoGenerateMips  = false;
                rtDepth.useMipMap         = true;
                rtDepth.Create();
            }

            int maxLevel = 0;

            while ((size >> maxLevel) > 8)
            {
                maxLevel++;
            }

            Graphics.SetRenderTarget(new[] { rt.colorBuffer, rtPos.colorBuffer }, rt.depthBuffer);
            GL.Clear(true, true, Color.clear);

            SolidRenderMaterial.SetInt("_Colorize", (int)Colorize);
            SolidRenderMaterial.SetFloat("_MinHeight", Data.Bounds.min.y);
            SolidRenderMaterial.SetFloat("_MaxHeight", Data.Bounds.max.y);
            SolidRenderMaterial.SetMatrix("_Transform", camera.worldToCameraMatrix * transform.localToWorldMatrix);
            SolidRenderMaterial.SetMatrix("_ViewToClip", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false));
            SolidRenderMaterial.SetPass(0);
            Graphics.DrawProceduralNow(MeshTopology.Points, Buffer.count);

            var setupClear = SolidComputeShader.FindKernel("SetupClear");

            SolidComputeShader.SetTexture(setupClear, "_SetupClearPosition", rtPosition, 0);
            SolidComputeShader.SetTexture(setupClear, "_SetupClearColor", rtColor, 0);
            SolidComputeShader.SetTexture(setupClear, "_SetupClearDepth", rtDepth, 0);
            SolidComputeShader.Dispatch(setupClear, size / 8, size / 8, 1);

            var setupCopy = SolidComputeShader.FindKernel("SetupCopy");

            SolidComputeShader.SetTexture(setupCopy, "_SetupCopyInput", rt, 0);
            SolidComputeShader.SetTexture(setupCopy, "_SetupCopyInputPos", rtPos, 0);
            SolidComputeShader.SetTexture(setupCopy, "_SetupCopyPosition", rtPosition, 0);
            SolidComputeShader.SetTexture(setupCopy, "_SetupCopyColor", rtColor, 0);
            SolidComputeShader.SetTexture(setupCopy, "_SetupCopyDepth", rtDepth, 0);
            SolidComputeShader.SetFloat("_SetupCopyMaxDepth", camera.farClipPlane);
            SolidComputeShader.SetMatrix("_SetupCopyProj", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false));
            SolidComputeShader.SetMatrix("_SetupCopyInverseProj", GL.GetGPUProjectionMatrix(camera.projectionMatrix, false).inverse);
            SolidComputeShader.Dispatch(setupCopy, size / 8, size / 8, 1);

            if (SolidRemoveHidden)
            {
                var posMax     = new[] { width - 1, height - 1 };
                var downsample = SolidComputeShader.FindKernel("Downsample");
                for (int i = 1; i <= maxLevel + 3; i++)
                {
                    SolidComputeShader.SetInts("_DownsamplePosMax", posMax);
                    posMax[0] = (posMax[0] + 1) / 2 - 1;
                    posMax[1] = (posMax[1] + 1) / 2 - 1;
                    SolidComputeShader.SetTexture(downsample, "_DownsampleInput", rtPosition, i - 1);
                    SolidComputeShader.SetTexture(downsample, "_DownsampleOutput", rtPosition, i);
                    SolidComputeShader.SetTexture(downsample, "_DownsampleDepthInput", rtDepth, i - 1);
                    SolidComputeShader.SetTexture(downsample, "_DownsampleDepthOutput", rtDepth, i);
                    SolidComputeShader.Dispatch(downsample, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1);
                }

                float metric            = DebugSolidMetric / 100f;
                float removeHiddenMagic = 10 * metric * camera.pixelHeight * 0.5f / Mathf.Tan(0.5f * camera.fieldOfView * Mathf.Deg2Rad);

                DebugSolidFixedLevel = Math.Min(Math.Max(DebugSolidFixedLevel, 0), maxLevel);

                var removeHidden = SolidComputeShader.FindKernel("RemoveHidden");
                SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenMask", rtMask);
                SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenPosition", rtPosition);
                SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenColor", rtColor, 0);
                SolidComputeShader.SetTexture(removeHidden, "_RemoveHiddenDepth", rtDepth);
                SolidComputeShader.SetFloat("_RemoveHiddenMagic", removeHiddenMagic);
                SolidComputeShader.SetInt("_RemoveHiddenLevel", DebugSolidFixedLevel);
                SolidComputeShader.Dispatch(removeHidden, size / 8, size / 8, 1);
            }

            if (DebugSolidPullPush)
            {
                var pullKernel = SolidComputeShader.FindKernel("PullKernel");
                for (int i = 1; i <= maxLevel; i++)
                {
                    SolidComputeShader.SetTexture(pullKernel, "_PullInput", rtColor, i - 1);
                    SolidComputeShader.SetTexture(pullKernel, "_PullOutput", rtColor, i);
                    SolidComputeShader.Dispatch(pullKernel, Math.Max(1, (size >> i) / 8), Math.Max(1, (size >> i) / 8), 1);
                }

                var pushKernel = SolidComputeShader.FindKernel("PushKernel");
                SolidComputeShader.SetTexture(pushKernel, "_PushMaskTex", rtMask);
                SolidComputeShader.SetTexture(pushKernel, "_PushPosition", rtPosition);
                SolidComputeShader.SetFloat("_PushAlwaysFillDistance", DebugSolidAlwaysFillDistance);

                for (int i = maxLevel; i > 0; i--)
                {
                    SolidComputeShader.SetInt("_PushOutputLevel", i - 1);
                    SolidComputeShader.SetTexture(pushKernel, "_PushInput", rtColor, i);
                    SolidComputeShader.SetTexture(pushKernel, "_PushOutput", rtColor, i - 1);
                    SolidComputeShader.Dispatch(pushKernel, Math.Max(1, (size >> (i - 1)) / 8), Math.Max(1, (size >> (i - 1)) / 8), 1);
                }
            }

            DebugSolidBlitLevel = Math.Min(Math.Max(DebugSolidBlitLevel, 0), maxLevel);

            SolitBlitMaterial.SetTexture("_ColorTex", rtColor);
            SolitBlitMaterial.SetTexture("_MaskTex", rtMask);
            SolitBlitMaterial.SetInt("_DebugLevel", DebugSolidBlitLevel);

            Graphics.DrawProcedural(SolitBlitMaterial, GetWorldBounds(), MeshTopology.Triangles, 3, camera: camera, layer: 1);
        }
예제 #6
0
 /// <summary>
 /// This function determines where and whether fluid will be filled in the cellular automaton.
 /// </summary>
 /// <param name="fill">An array of size 4. The first three values determine the position, where fluid will be filled in (a coordinate outside the borders will stop filling).</param>
 /// <param name="element">The type of element, that is filled in.</param>
 /// <param name="radius">The radius.</param>
 public void Fill(float[] fill, int element, int radius)
 {
     cellularAutomaton.SetInt("radius", radius);
     cellularAutomaton.SetInts("fill", new int[] { (int)(fill[0] * dimensions.x * 16.0), (int)(fill[1] * dimensions.y * 16.0), (int)(fill[2] * dimensions.z * 16.0), element });
 }
예제 #7
0
    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;
    }
예제 #8
0
    private void CalculateVisibleInstances()
    {
        // Global data
        m_camPosition = mainCamera.transform.position;

        //Matrix4x4 m = mainCamera.transform.localToWorldMatrix;
        Matrix4x4 v = mainCamera.worldToCameraMatrix;
        Matrix4x4 p = mainCamera.projectionMatrix;

        m_MVP = p * v;//*m;

        m_bounds.center  = m_camPosition;
        m_bounds.extents = Vector3.one * 10000;


        //////////////////////////////////////////////////////
        // Reset the arguments buffer
        //////////////////////////////////////////////////////
        Profiler.BeginSample("Resetting args buffer");
        {
            m_argsBuffer.SetData(m_args);
        }
        Profiler.EndSample();

        //////////////////////////////////////////////////////
        // Sort the position buffer based on distance from camera
        //////////////////////////////////////////////////////
        Profiler.BeginSample("01 LOD Sorting");
        {
            RunGpuSorting(ref m_camPosition);
        }
        Profiler.EndSample();

        //////////////////////////////////////////////////////
        // Set up compute shader to perform the occlusion culling
        //////////////////////////////////////////////////////
        Profiler.BeginSample("02 Occlusion");
        {
            // Input
            occlusionCS.SetInt("_ShouldFrustumCull", enableFrustumCulling ? 1 : 0);
            occlusionCS.SetInt("_ShouldOcclusionCull", enableOcclusionCulling ? 1 : 0);
            occlusionCS.SetInt("_ShouldDetailCull", enableDetailCulling ? 1 : 0);
            occlusionCS.SetInt("_ShouldLOD", enableLOD ? 1 : 0);

            occlusionCS.SetInt("_Cascades", QualitySettings.shadowCascades);
            occlusionCS.SetFloat("_DetailCullingScreenPercentage", detailCullingScreenPercentage);
            occlusionCS.SetMatrix("_UNITY_MATRIX_MVP", m_MVP);
            occlusionCS.SetVector("_HiZTextureSize", hiZBuffer.TextureSize);
            occlusionCS.SetVector("_CamPosition", m_camPosition);
            occlusionCS.SetBuffer(m_occlusionKernelID, "_InstanceDataBuffer", m_instanceDataBuffer);
            occlusionCS.SetTexture(m_occlusionKernelID, "_Unity_WorldToShadow", GetWorldToShadowMatrixTexture());
            occlusionCS.SetTexture(m_occlusionKernelID, "_HiZMap", hiZBuffer.HiZDepthTexture);

            // Output
            occlusionCS.SetBuffer(m_occlusionKernelID, "_ArgsBuffer", m_argsBuffer);
            occlusionCS.SetBuffer(m_occlusionKernelID, "_IsVisibleBuffer", m_isVisibleBuffer);

            // Dispatch
            int groupX = Mathf.Max(m_numberOfInstances / 64, 1);
            occlusionCS.Dispatch(m_occlusionKernelID, groupX, 1, 1);
        }
        Profiler.EndSample();

        //////////////////////////////////////////////////////
        // Perform scan of instance predicates
        //////////////////////////////////////////////////////
        Profiler.BeginSample("03 Scan Instances");
        {
            int groupX = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE);

            // Input
            scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_InstancePredicatesIn", m_isVisibleBuffer);

            // Output
            scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_GroupSumArray", m_groupSumArray);
            scanInstancesCS.SetBuffer(m_scanInstancesKernelID, "_ScannedInstancePredicates", m_scannedInstancePredicates);

            // Dispatch
            scanInstancesCS.Dispatch(m_scanInstancesKernelID, groupX, 1, 1);
        }
        Profiler.EndSample();

        //////////////////////////////////////////////////////
        // Perform scan of group sums
        //////////////////////////////////////////////////////
        Profiler.BeginSample("04 Scan Thread Groups");
        {
            // Input
            int numOfGroups = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE);
            scanGroupSumsCS.SetInt("_NumOfGroups", numOfGroups);
            scanGroupSumsCS.SetBuffer(m_scanGroupSumsKernelID, "_GroupSumArrayIn", m_groupSumArray);

            // Output
            scanGroupSumsCS.SetBuffer(m_scanGroupSumsKernelID, "_GroupSumArrayOut", m_scannedGroupSumBuffer);

            // Dispatch
            scanGroupSumsCS.Dispatch(m_scanGroupSumsKernelID, 1, 1, 1);
        }
        Profiler.EndSample();

        //////////////////////////////////////////////////////
        // Perform stream compaction
        // Calculate instance offsets and store in drawcall arguments buffer
        //////////////////////////////////////////////////////
        Profiler.BeginSample("05 Copy Instance Data");
        {
            int groupX = m_numberOfInstances / (2 * SCAN_THREAD_GROUP_SIZE);

            // Input
            copyInstanceDataCS.SetInt("_NumberOfInstanceTypes", m_numberOfInstanceTypes * NUMBER_OF_DRAW_CALLS);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceData", m_instanceDataBuffer);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceDrawData", m_instanceDrawDataBuffer);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstancePredicatesIn", m_isVisibleBuffer);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_GroupSumArray", m_scannedGroupSumBuffer);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_ScannedInstancePredicates", m_scannedInstancePredicates);

            // Output
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_DrawcallDataOut", m_argsBuffer);
            copyInstanceDataCS.SetBuffer(m_copyInstanceDataKernelID, "_InstanceDataOut", m_culledInstanceBuffer);

            // Dispatch
            copyInstanceDataCS.Dispatch(m_copyInstanceDataKernelID, groupX, 1, 1);
        }
        Profiler.EndSample();

        LogStats();
    }
    void Update()
    {
        Vector2 mousePos = new Vector2 {
            x = Input.mousePosition.x / (float)Screen.width,
            y = Input.mousePosition.y / (float)Screen.height
        };
        Vector2 resolution = new Vector2 {
            x = _doubleBuffer.width,
            y = _doubleBuffer.height
        };

        Shader.SetGlobalVector("_Resolution", new Vector4 {
            x = resolution.x,
            y = resolution.y,
            z = 1f / resolution.x,
            w = 1f / resolution.y
        });
        Shader.SetGlobalVector("_Mouse", mousePos);
        Shader.SetGlobalFloat("_Time", Time.time);
        Shader.SetGlobalFloat("_DeltaTime", Time.deltaTime);

        if (Input.GetMouseButton(0))
        {
            particleShader.SetInt("_MaxParticles", maxParticles);
            particleShader.SetBuffer(particleSeedKernel, "_CounterBuf", indirectArgsBuf);
            particleShader.SetBuffer(particleSeedKernel, "_WriteParticles", pBufA);
            particleShader.Dispatch(particleSeedKernel, 1, 1, 1);
        }

        ComputeBuffer.CopyCount(pBufA, indirectArgsBuf, 0);
        indirectArgsShader.SetBuffer(0, "_IndirectArgsBuf", indirectArgsBuf);
        indirectArgsShader.Dispatch(0, 1, 1, 1);

        particleShader.SetBuffer(particleSimKernel, "_CounterBuf", indirectArgsBuf);
        particleShader.SetBuffer(particleSimKernel, "_ReadParticles", pBufA);
        particleShader.SetBuffer(particleSimKernel, "_WriteParticles", pBufB);
        particleShader.SetTexture(particleSimKernel, "_ReadTexture", _doubleBuffer.read);
        particleShader.SetTexture(particleSimKernel, "_WriteTexture", _doubleBuffer.write);
        uniforms.Bind(particleShader);

        particleShader.DispatchIndirect(particleSimKernel, indirectArgsBuf, sizeof(int));

        ComputeBuffer.CopyCount(pBufB, indirectArgsBuf, 0);

        // flip buffers
        var tmp = pBufA;

        pBufA = pBufB;
        pBufB = tmp;

        _doubleBuffer.Flip();
        {
            colorDiffuseShader.SetFloat("_DecayRate", decayRate);
            colorDiffuseShader.SetTexture(0, "_ReadTexture", _doubleBuffer.read);
            colorDiffuseShader.SetTexture(0, "_WriteTexture", _doubleBuffer.write);
            colorDiffuseShader.GetKernelThreadGroupSizes(0, out var threadsX, out var threadsY, out var threadsZ);
            var threadGroupsX = _doubleBuffer.width / (int)threadsX;
            var threadGroupsY = _doubleBuffer.height / (int)threadsY;
            colorDiffuseShader.Dispatch(0, threadGroupsX, threadGroupsY, 1);
        }
        renderer.material.SetTexture("_MainTex", _doubleBuffer.write);
    }
예제 #10
0
    private void OnPreRender()
    {
        primitives.SetData(linesData);
        for (int i = 0; i < verts.Length; i++)
        {
            verts[i] += Vector2.left * (Input.GetKey(KeyCode.LeftArrow)?Time.deltaTime * 0.1f:0);
            verts[i] += Vector2.right * (Input.GetKey(KeyCode.RightArrow) ? Time.deltaTime * 0.1f : 0);
            verts[i] += Vector2.up * (Input.GetKey(KeyCode.UpArrow) ? Time.deltaTime * 0.1f : 0);
            verts[i] += Vector2.down * (Input.GetKey(KeyCode.DownArrow) ? Time.deltaTime * 0.1f : 0);
        }
        vertices.SetData(verts);



        ComputeBuffer filterCounts = new ComputeBuffer(1, 4);

        int[] fdat = { numLines };
        filterCounts.SetData(fdat);

        ComputeBuffer primIds      = index;
        int           filterTilesX = 1;
        int           filterTilesY = 1;

        for (int i = 0; i < 2; i++)
        {
            int kernel = kernels[i];
            shader.SetBuffer(kernel, "filterCounts", filterCounts);

            shader.SetBuffer(kernel, "buffer", primitives);
            shader.SetBuffer(kernel, "vertices", vertices);
            shader.SetBuffer(kernel, "lines", primIds);
            shader.SetBuffer(kernel, "counts", counts[i]);

            shader.SetInt("filterXtiles", filterTilesX);
            shader.SetInt("filterYtiles", filterTilesY);

            shader.SetInt("xtiles", (Screen.width / tileSize[i]));
            shader.SetInt("ytiles", (Screen.height / tileSize[i]));

            shader.SetInt("tileLines", tileLines[i]);
            shader.SetFloat("distCheck", Mathf.Sqrt(2) * tileSize[i] / Screen.width);
            shader.SetBuffer(kernel, "tiles", tiles[i]);

            uint x, y, z;

            shader.GetKernelThreadGroupSizes(kernel, out x, out y, out z);



            shader.Dispatch(kernel, Screen.width / (int)x / tileSize[i], Screen.height / (int)y / tileSize[i], 1);

            if (i == 0)
            {
                filterCounts.Release();
            }
            filterCounts = counts[i];
            filterTilesX = Screen.width / tileSize[i];
            filterTilesY = Screen.height / tileSize[i];
            primIds      = tiles[i];
        }
    }
예제 #11
0
파일: SEGI.cs 프로젝트: hybridherbst/SEGI
    void OnPreRender()
    {
        //Force reinitialization to make sure that everything is working properly if one of the cameras was unexpectedly destroyed
        if (!voxelCamera || !shadowCam)
        {
            initChecker = null;
        }

        InitCheck();

        if (notReadyToRender)
        {
            return;
        }

        if (!updateGI)
        {
            return;
        }

        //Cache the previous active render texture to avoid issues with other Unity rendering going on
        RenderTexture previousActive = RenderTexture.active;

        Shader.SetGlobalInt("SEGIVoxelAA", voxelAA ? 1 : 0);



        //Main voxelization work
        if (renderState == RenderState.Voxelize)
        {
            activeVolume         = voxelFlipFlop == 0 ? volumeTextures[0] : volumeTextureB;                             //Flip-flopping volume textures to avoid simultaneous read and write errors in shaders
            previousActiveVolume = voxelFlipFlop == 0 ? volumeTextureB : volumeTextures[0];

            //float voxelTexel = (1.0f * voxelSpaceSize) / (int)voxelResolution * 0.5f;			//Calculate the size of a voxel texel in world-space units



            //Setup the voxel volume origin position
            float   interval = voxelSpaceSize / 8.0f;                                                                                                   //The interval at which the voxel volume will be "locked" in world-space
            Vector3 origin;
            if (followTransform)
            {
                origin = followTransform.position;
            }
            else
            {
                //GI is still flickering a bit when the scene view and the game view are opened at the same time
                origin = transform.position + transform.forward * voxelSpaceSize / 4.0f;
            }
            //Lock the voxel volume origin based on the interval
            voxelSpaceOrigin = new Vector3(Mathf.Round(origin.x / interval) * interval, Mathf.Round(origin.y / interval) * interval, Mathf.Round(origin.z / interval) * interval);

            //Calculate how much the voxel origin has moved since last voxelization pass. Used for scrolling voxel data in shaders to avoid ghosting when the voxel volume moves in the world
            voxelSpaceOriginDelta = voxelSpaceOrigin - previousVoxelSpaceOrigin;
            Shader.SetGlobalVector("SEGIVoxelSpaceOriginDelta", voxelSpaceOriginDelta / voxelSpaceSize);

            previousVoxelSpaceOrigin = voxelSpaceOrigin;



            //Set the voxel camera (proxy camera used to render the scene for voxelization) parameters
            voxelCamera.enabled          = false;
            voxelCamera.orthographic     = true;
            voxelCamera.orthographicSize = voxelSpaceSize * 0.5f;
            voxelCamera.nearClipPlane    = 0.0f;
            voxelCamera.farClipPlane     = voxelSpaceSize;
            voxelCamera.depth            = -2;
            voxelCamera.renderingPath    = RenderingPath.Forward;
            voxelCamera.clearFlags       = CameraClearFlags.Color;
            voxelCamera.backgroundColor  = Color.black;
            voxelCamera.cullingMask      = giCullingMask;


            //Move the voxel camera game object and other related objects to the above calculated voxel space origin
            voxelCameraGO.transform.position = voxelSpaceOrigin - Vector3.forward * voxelSpaceSize * 0.5f;
            voxelCameraGO.transform.rotation = rotationFront;

            leftViewPoint.transform.position = voxelSpaceOrigin + Vector3.left * voxelSpaceSize * 0.5f;
            leftViewPoint.transform.rotation = rotationLeft;
            topViewPoint.transform.position  = voxelSpaceOrigin + Vector3.up * voxelSpaceSize * 0.5f;
            topViewPoint.transform.rotation  = rotationTop;



            //Set matrices needed for voxelization
            Shader.SetGlobalMatrix("WorldToCamera", attachedCamera.worldToCameraMatrix);
            Shader.SetGlobalMatrix("SEGIVoxelViewFront", TransformViewMatrix(voxelCamera.transform.worldToLocalMatrix));
            Shader.SetGlobalMatrix("SEGIVoxelViewLeft", TransformViewMatrix(leftViewPoint.transform.worldToLocalMatrix));
            Shader.SetGlobalMatrix("SEGIVoxelViewTop", TransformViewMatrix(topViewPoint.transform.worldToLocalMatrix));
            Shader.SetGlobalMatrix("SEGIWorldToVoxel", voxelCamera.worldToCameraMatrix);
            Shader.SetGlobalMatrix("SEGIVoxelProjection", voxelCamera.projectionMatrix);
            Shader.SetGlobalMatrix("SEGIVoxelProjectionInverse", voxelCamera.projectionMatrix.inverse);

            Shader.SetGlobalInt("SEGIVoxelResolution", (int)voxelResolution);

            Matrix4x4 voxelToGIProjection = (shadowCam.projectionMatrix) * (shadowCam.worldToCameraMatrix) * (voxelCamera.cameraToWorldMatrix);
            Shader.SetGlobalMatrix("SEGIVoxelToGIProjection", voxelToGIProjection);
            Shader.SetGlobalVector("SEGISunlightVector", sun ? Vector3.Normalize(sun.transform.forward) : Vector3.up);

            //Set paramteters
            Shader.SetGlobalColor("GISunColor", sun == null ? Color.black : new Color(Mathf.Pow(sun.color.r, 2.2f), Mathf.Pow(sun.color.g, 2.2f), Mathf.Pow(sun.color.b, 2.2f), Mathf.Pow(sun.intensity, 2.2f)));
            Shader.SetGlobalColor("SEGISkyColor", new Color(Mathf.Pow(skyColor.r * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.g * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.b * skyIntensity * 0.5f, 2.2f), Mathf.Pow(skyColor.a, 2.2f)));
            Shader.SetGlobalFloat("GIGain", giGain);
            Shader.SetGlobalFloat("SEGISecondaryBounceGain", infiniteBounces ? secondaryBounceGain : 0.0f);
            Shader.SetGlobalFloat("SEGISoftSunlight", softSunlight);
            Shader.SetGlobalInt("SEGISphericalSkylight", sphericalSkylight ? 1 : 0);
            Shader.SetGlobalInt("SEGIInnerOcclusionLayers", innerOcclusionLayers);


            //Render the depth texture from the sun's perspective in order to inject sunlight with shadows during voxelization
            if (sun != null)
            {
                shadowCam.cullingMask = giCullingMask;

                Vector3 shadowCamPosition = voxelSpaceOrigin + Vector3.Normalize(-sun.transform.forward) * shadowSpaceSize * 0.5f * shadowSpaceDepthRatio;

                shadowCamTransform.position = shadowCamPosition;
                shadowCamTransform.LookAt(voxelSpaceOrigin, Vector3.up);

                shadowCam.renderingPath     = RenderingPath.Forward;
                shadowCam.depthTextureMode |= DepthTextureMode.None;

                shadowCam.orthographicSize = shadowSpaceSize;
                shadowCam.farClipPlane     = shadowSpaceSize * 2.0f * shadowSpaceDepthRatio;


                Graphics.SetRenderTarget(sunDepthTexture);
                shadowCam.SetTargetBuffers(sunDepthTexture.colorBuffer, sunDepthTexture.depthBuffer);

                shadowCam.RenderWithShader(sunDepthShader, "");

                Shader.SetGlobalTexture("SEGISunDepth", sunDepthTexture);
            }



            //Clear the volume texture that is immediately written to in the voxelization scene shader
            clearCompute.SetTexture(0, "RG0", integerVolume);
            clearCompute.SetInt("Res", (int)voxelResolution);
            clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);



            //Render the scene with the voxel proxy camera object with the voxelization shader to voxelize the scene to the volume integer texture
            Graphics.SetRandomWriteTarget(1, integerVolume);
            voxelCamera.targetTexture = dummyVoxelTextureAAScaled;
            voxelCamera.RenderWithShader(voxelizationShader, "");
            Graphics.ClearRandomWriteTargets();


            //Transfer the data from the volume integer texture to the main volume texture used for GI tracing.
            transferIntsCompute.SetTexture(0, "Result", activeVolume);
            transferIntsCompute.SetTexture(0, "PrevResult", previousActiveVolume);
            transferIntsCompute.SetTexture(0, "RG0", integerVolume);
            transferIntsCompute.SetInt("VoxelAA", voxelAA ? 1 : 0);
            transferIntsCompute.SetInt("Resolution", (int)voxelResolution);
            transferIntsCompute.SetVector("VoxelOriginDelta", (voxelSpaceOriginDelta / voxelSpaceSize) * (int)voxelResolution);
            transferIntsCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);

            Shader.SetGlobalTexture("SEGIVolumeLevel0", activeVolume);

            //Manually filter/render mip maps
            for (int i = 0; i < numMipLevels - 1; i++)
            {
                RenderTexture source = volumeTextures[i];

                if (i == 0)
                {
                    source = activeVolume;
                }

                int destinationRes = (int)voxelResolution / Mathf.RoundToInt(Mathf.Pow((float)2, (float)i + 1.0f));
                mipFilterCompute.SetInt("destinationRes", destinationRes);
                mipFilterCompute.SetTexture(mipFilterKernel, "Source", source);
                mipFilterCompute.SetTexture(mipFilterKernel, "Destination", volumeTextures[i + 1]);
                mipFilterCompute.Dispatch(mipFilterKernel, destinationRes / 8, destinationRes / 8, 1);
                Shader.SetGlobalTexture("SEGIVolumeLevel" + (i + 1).ToString(), volumeTextures[i + 1]);
            }

            //Advance the voxel flip flop counter
            voxelFlipFlop += 1;
            voxelFlipFlop  = voxelFlipFlop % 2;

            if (infiniteBounces)
            {
                renderState = RenderState.Bounce;
            }
        }
        else if (renderState == RenderState.Bounce)
        {
            //Clear the volume texture that is immediately written to in the voxelization scene shader
            clearCompute.SetTexture(0, "RG0", integerVolume);
            clearCompute.Dispatch(0, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);

            //Set secondary tracing parameters
            Shader.SetGlobalInt("SEGISecondaryCones", secondaryCones);
            Shader.SetGlobalFloat("SEGISecondaryOcclusionStrength", secondaryOcclusionStrength);

            //Render the scene from the voxel camera object with the voxel tracing shader to render a bounce of GI into the irradiance volume
            Graphics.SetRandomWriteTarget(1, integerVolume);
            voxelCamera.targetTexture = dummyVoxelTextureFixed;
            voxelCamera.RenderWithShader(voxelTracingShader, "");
            Graphics.ClearRandomWriteTargets();


            //Transfer the data from the volume integer texture to the irradiance volume texture. This result is added to the next main voxelization pass to create a feedback loop for infinite bounces
            transferIntsCompute.SetTexture(1, "Result", secondaryIrradianceVolume);
            transferIntsCompute.SetTexture(1, "RG0", integerVolume);
            transferIntsCompute.SetInt("Resolution", (int)voxelResolution);
            transferIntsCompute.Dispatch(1, (int)voxelResolution / 16, (int)voxelResolution / 16, 1);

            Shader.SetGlobalTexture("SEGIVolumeTexture1", secondaryIrradianceVolume);

            renderState = RenderState.Voxelize;
        }



        RenderTexture.active = previousActive;
    }
예제 #12
0
    public override bool Calculate()
    {
        Texture texL = texLKnob.GetValue <Texture>();

        if (!texLKnob.connected() || texL == null)
        {
            outputTexKnob.ResetValue();
            outputSize = Vector2Int.zero;

            if (outputTex != null)
            {
                outputTex.Release();
            }
            return(true);
        }

        Texture texR = texRKnob.GetValue <Texture>();

        if (!texRKnob.connected() || texR == null)
        {
            outputTexKnob.ResetValue();
            outputSize = Vector2Int.zero;

            if (outputTex != null)
            {
                outputTex.Release();
            }
            return(true);
        }

        var inputSize = new Vector2Int(texL.width, texL.height);

        if (inputSize != outputSize)
        {
            outputSize = inputSize;
            InitializeRenderTexture();
        }



        patternShader.SetInt("width", outputSize.x);
        patternShader.SetInt("height", outputSize.y);
        int kernel = 0;

        switch (mergeModeSelection.Selected)
        {
        case "Simple":
            crossfader = crossfaderKnob.connected() ? crossfaderKnob.GetValue <float>() : crossfader;
            patternShader.SetFloat("crossfader", crossfader);
            kernel = fadeKernel;
            break;

        case "Layers":
            kernel = layerKernel;
            break;
        }

        patternShader.SetTexture(kernel, "texL", texL);
        patternShader.SetTexture(kernel, "texR", texR);
        patternShader.SetTexture(kernel, "outputTex", outputTex);

        uint tx, ty, tz;

        patternShader.GetKernelThreadGroupSizes(kernel, out tx, out ty, out tz);
        var threadGroupX = Mathf.CeilToInt(((float)outputSize.x) / tx);
        var threadGroupY = Mathf.CeilToInt(((float)outputSize.y) / ty);

        patternShader.Dispatch(kernel, threadGroupX, threadGroupY, 1);
        outputTexKnob.SetValue(outputTex);

        return(true);
    }
예제 #13
0
    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            InitBuffer();
        }

        if (Input.GetKey(KeyCode.RightArrow))
        {
            m_ElementCount += 10;
        }

        if (Input.GetKey(KeyCode.LeftArrow))
        {
            m_ElementCount -= 10;
        }

        m_ElementCount = Mathf.Clamp(m_ElementCount, 0, kCount);

        if (Input.GetKeyDown(KeyCode.UpArrow))
        {
            ++m_MaxPassCount;
        }

        if (Input.GetKeyDown(KeyCode.DownArrow))
        {
            --m_MaxPassCount;
        }

        m_MaxPassCount = Mathf.Clamp(m_MaxPassCount, 0, Log2(kGroupCount));

        // sort
        Profiler.BeginSample("Sort");

        sortShader.SetInt("elementCount", m_ElementCount);

        sortShader.SetBuffer(sortKernelBitonic, "inputSequence", inputBuffer);
        sortShader.SetBuffer(sortKernelBitonic, "sortedSequence", scratchBuffer[0]);
        sortShader.SetBuffer(sortKernelBitonic, "deadElementCount", deadElementCount);
        sortShader.Dispatch(sortKernelBitonic, kGroupCount, 1, 1);

        sortedBuffer = scratchBuffer[0];

        int arraySize = kElementCount;

        for (int i = 0; i < m_MaxPassCount; ++i)
        {
            sortShader.SetInt("subArraySize", arraySize);
            sortShader.SetBuffer(mergeKernel, "inputSequence", scratchBuffer[0]);
            sortShader.SetBuffer(mergeKernel, "sortedSequence", scratchBuffer[1]);
            sortShader.SetBuffer(mergeKernel, "deadElementCount", deadElementCount);

            sortShader.Dispatch(mergeKernel, (kElementCount * kGroupCount) / 64, 1, 1);

            sortedBuffer = scratchBuffer[1];

            // swap
            ComputeBuffer tmp = scratchBuffer[0];
            scratchBuffer[0] = scratchBuffer[1];
            scratchBuffer[1] = tmp;

            arraySize <<= 1;
        }

        Profiler.EndSample();

        sortedMat1.SetBuffer("buffer", sortedBuffer);
        sortedMat1.SetInt("totalCount", m_ElementCount);
        sortedMat1.SetInt("elementCount", kElementCount);
        sortedMat1.SetInt("groupCount", kGroupCount);

        inputMat.SetBuffer("buffer", inputBuffer);
        inputMat.SetInt("totalCount", m_ElementCount);
        inputMat.SetInt("elementCount", kElementCount);
        inputMat.SetInt("groupCount", kGroupCount);

        /*sortShader.SetBuffer(sortKernelMerge, "inputSequence", inputBuffer);
         * sortShader.SetBuffer(sortKernelMerge, "sortedSequence", sortedBuffer1);
         * sortShader.Dispatch(sortKernelMerge, kGroupCount, 1, 1);*/
    }
예제 #14
0
        void UpdateHistogram(RenderTexture source, Rect rect, HistogramMode mode)
        {
            if (m_HistogramMaterial == null)
            {
                m_HistogramMaterial = ImageEffectHelper.CheckShaderAndCreateMaterial(concreteTarget.histogramShader);
            }

            if (m_HistogramBuffer == null)
            {
                m_HistogramBuffer = new ComputeBuffer(256, sizeof(uint) << 2);
            }

            m_HistogramBuffer.SetData(k_EmptyBuffer);

            ComputeShader cs = concreteTarget.histogramComputeShader;

            int kernel = cs.FindKernel("KHistogramGather");

            cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer);
            cs.SetTexture(kernel, "_Source", source);

            int[] channels = null;
            switch (mode)
            {
            case HistogramMode.Luminance:
                channels = new[] { 0, 0, 0, 1 };
                break;

            case HistogramMode.RGB:
                channels = new[] { 1, 1, 1, 0 };
                break;

            case HistogramMode.Red:
                channels = new[] { 1, 0, 0, 0 };
                break;

            case HistogramMode.Green:
                channels = new[] { 0, 1, 0, 0 };
                break;

            case HistogramMode.Blue:
                channels = new[] { 0, 0, 1, 0 };
                break;
            }

            cs.SetInts("_Channels", channels);
            cs.SetInt("_IsLinear", concreteTarget.isGammaColorSpace ? 0 : 1);
            cs.Dispatch(kernel, Mathf.CeilToInt(source.width / 32f), Mathf.CeilToInt(source.height / 32f), 1);

            kernel = cs.FindKernel("KHistogramScale");
            cs.SetBuffer(kernel, "_Histogram", m_HistogramBuffer);
            cs.SetFloat("_Height", rect.height);
            cs.Dispatch(kernel, 1, 1, 1);

            if (m_HistogramTexture == null)
            {
                DestroyImmediate(m_HistogramTexture);
                m_HistogramTexture           = new RenderTexture((int)rect.width, (int)rect.height, 0, RenderTextureFormat.ARGB32);
                m_HistogramTexture.hideFlags = HideFlags.HideAndDontSave;
            }

            m_HistogramMaterial.SetBuffer("_Histogram", m_HistogramBuffer);
            m_HistogramMaterial.SetVector("_Size", new Vector2(m_HistogramTexture.width, m_HistogramTexture.height));
            m_HistogramMaterial.SetColor("_ColorR", redCurveColor);
            m_HistogramMaterial.SetColor("_ColorG", greenCurveColor);
            m_HistogramMaterial.SetColor("_ColorB", blueCurveColor);
            m_HistogramMaterial.SetColor("_ColorL", masterCurveColor);
            m_HistogramMaterial.SetInt("_Channel", (int)mode);
            Graphics.Blit(m_HistogramTexture, m_HistogramTexture, m_HistogramMaterial, (mode == HistogramMode.RGB) ? 1 : 0);
        }
예제 #15
0
    public void ComputePressureWithRGGS()
    {
        // red-black gauss-sebel

        UploadGlobalParameters(mComputePressure);
        int formPoissonKernel = mComputePressure.FindKernel("FormPoisson");

        // 1. compute poisson
        mComputePressure.SetTexture(formPoissonKernel, "gPoisson0", mPoisson0.Source);
        mComputePressure.SetTexture(formPoissonKernel, "gPoisson1", mPoisson1.Source);
        mComputePressure.SetTexture(formPoissonKernel, "gPoisson2", mPoisson2.Source);
        mComputePressure.SetTexture(formPoissonKernel, "gGridMarker", mGridMarker.Source);
        mComputePressure.SetTexture(formPoissonKernel, "gLevelSet", mLevelSet[READ].Source);
        mComputePressure.Dispatch(formPoissonKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1);

        // 2. red-black gaus sebel
        int RBGSKernel = mComputePressure.FindKernel("RBGS");

        for (int i = 0; i < 200; i++)
        {
            mComputePressure.SetInt("_redOrBlack", 0);
            mComputePressure.SetTexture(RBGSKernel, "gGridMarker", mGridMarker.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPressure", mPressure.Source);
            mComputePressure.SetTexture(RBGSKernel, "gVelocityDivergence", mDivergence.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson0", mPoisson0.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson1", mPoisson1.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson2", mPoisson2.Source);
            mComputePressure.Dispatch(RBGSKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1);

            mComputePressure.SetInt("_redOrBlack", 1);
            mComputePressure.SetTexture(RBGSKernel, "gGridMarker", mGridMarker.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPressure", mPressure.Source);
            mComputePressure.SetTexture(RBGSKernel, "gVelocityDivergence", mDivergence.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson0", mPoisson0.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson1", mPoisson1.Source);
            mComputePressure.SetTexture(RBGSKernel, "gPoisson2", mPoisson2.Source);
            mComputePressure.Dispatch(RBGSKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1);
        }

        // 3. projection (subtract divergence of pressure)
        bool notUseSimpleSubtract = true;

        if (notUseSimpleSubtract)
        {
            // TODO: Exist some bug...
            int subtractPressureGradientXKernel = mComputePressure.FindKernel("SubtractPressureGradientX");
            mComputePressure.SetTexture(subtractPressureGradientXKernel, "gPressure", mPressure.Source);
            mComputePressure.SetTexture(subtractPressureGradientXKernel, "gVelocityU", mVelocityU[READ].Source);
            mComputePressure.SetTexture(subtractPressureGradientXKernel, "gGridMarker", mGridMarker.Source);
            mComputePressure.SetTexture(subtractPressureGradientXKernel, "gLevelSet", mLevelSet[READ].Source);
            mComputePressure.Dispatch(subtractPressureGradientXKernel, Mathf.CeilToInt((mWidth + 1) * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1);

            int subtractPressureGradientYKernel = mComputePressure.FindKernel("SubtractPressureGradientY");
            mComputePressure.SetTexture(subtractPressureGradientYKernel, "gPressure", mPressure.Source);
            mComputePressure.SetTexture(subtractPressureGradientYKernel, "gVelocityV", mVelocityV[READ].Source);
            mComputePressure.SetTexture(subtractPressureGradientYKernel, "gGridMarker", mGridMarker.Source);
            mComputePressure.SetTexture(subtractPressureGradientYKernel, "gLevelSet", mLevelSet[READ].Source);
            mComputePressure.Dispatch(subtractPressureGradientYKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt((mHeight + 1) * 1.0f / mGroupThreadSizeX), 1);
        }
        else
        {
            int applyPressureKernel = mComputePressure.FindKernel("ApplyPressure");
            mComputePressure.SetTexture(applyPressureKernel, "gPressure", mPressure.Source);
            mComputePressure.SetTexture(applyPressureKernel, "gVelocityU", mVelocityU[READ].Source);
            mComputePressure.SetTexture(applyPressureKernel, "gVelocityV", mVelocityV[READ].Source);
            mComputePressure.Dispatch(applyPressureKernel, Mathf.CeilToInt(mWidth * 1.0f / mGroupThreadSizeX), Mathf.CeilToInt(mHeight * 1.0f / mGroupThreadSizeX), 1);
        }
    }
예제 #16
0
    private void InitShaderData()
    {
        //Force field compute shader init
        shaderForceFieldCompute.SetInt("_N", N);
        _forceFieldBufferData = new Vector2[(N + 2) * (N + 2)];
        _forceFieldBuffer     = new ComputeBuffer(_forceFieldBufferData.Length, 2 * 4);
        _forceFieldBuffer.SetData(_forceFieldBufferData);
        shaderForceFieldCompute.SetBuffer(kernelForceFieldCompute, "Result", _forceFieldBuffer);
        _sourcesBuffer = new ComputeBuffer(maxSource, 2 * 4 + 4);
        shaderForceFieldCompute.SetBuffer(kernelForceFieldCompute, "_sources", _sourcesBuffer);

        //Force field apply shader init
        shaderForceFieldApply.SetInt("_N", N);
        shaderForceFieldApply.SetFloat("_speedLim", speedLim);
        _ufBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_u", _ufBuffer);
        _vfBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_v", _vfBuffer);
        _fBuffer = new ComputeBuffer((N + 2) * (N + 2), 2 * 4);
        shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_f", _fBuffer);
        _dfBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderForceFieldApply.SetBuffer(kernelForceFieldApply, "_d", _dfBuffer);

        //Diffusion shader init
        shaderDiffusion.SetInt("_N", N);
        _x0Buffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderDiffusion.SetBuffer(kernelDiffusion, "_x0", _x0Buffer);
        _xBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderDiffusion.SetBuffer(kernelDiffusion, "Result", _xBuffer);

        //Advection shader init
        shaderAdvection.SetInt("_N", N);
        _dBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderAdvection.SetBuffer(kernelAdvection, "_d", _dBuffer);
        _d0Buffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderAdvection.SetBuffer(kernelAdvection, "_d0", _d0Buffer);
        _uaBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderAdvection.SetBuffer(kernelAdvection, "_u", _uaBuffer);
        _vaBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderAdvection.SetBuffer(kernelAdvection, "_v", _vaBuffer);

        //ProjectionCompute shader init
        shaderProjectionCompute.SetInt("_N", N);
        _uInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_u", _uInBuffer);
        _vInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_v", _vInBuffer);
        _pOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionCompute.SetBuffer(kernelProjectionCompute, "_p", _pOutBuffer);

        //ProjectionApply shader init
        shaderProjectionApply.SetInt("_N", N);
        _uOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionApply.SetBuffer(kernelProjectionApply, "_u", _uOutBuffer);
        _vOutBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionApply.SetBuffer(kernelProjectionApply, "_v", _vOutBuffer);
        _pInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderProjectionApply.SetBuffer(kernelProjectionApply, "_p", _pInBuffer);

        //FillFluidRenderTex shader init
        shaderFillFluidRTex.SetInt("_N", N);
        _urInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_u", _urInBuffer);
        _vrInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_v", _vrInBuffer);
        _drInBuffer = new ComputeBuffer((N + 2) * (N + 2), 4);
        shaderFillFluidRTex.SetBuffer(kernelFillFluidRTex, "_d", _drInBuffer);
        fluidRenderTexture = new RenderTexture(N, N, 1);
        fluidRenderTexture.enableRandomWrite = true;
        fluidRenderTexture.Create();
        shaderFillFluidRTex.SetTexture(kernelFillFluidRTex, "Result", fluidRenderTexture);
    }
예제 #17
0
        // updates the floor parameters async
        private IEnumerator UpdateFloorAsync()
        {
            while (isRoutineRunning)
            {
                // wait for imu vector & depth frame
                while (/**!isImuVectorSet ||*/ !isDepthFrameSet)
                {
                    yield return(null);
                }

                //isImuVectorSet = false;
                isDepthFrameSet = false;

                KinectInterop.SetComputeShaderInt2(floorDetOffsetEstShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight);
                //KinectInterop.SetComputeShaderFloat2(floorDetOffsetEstShader, "SpaceScale", sensorData.sensorSpaceScale.x, sensorData.sensorSpaceScale.y);
                KinectInterop.SetComputeShaderFloat3(floorDetOffsetEstShader, "ImuUpVector", imuUpVector);

                floorDetOffsetEstShader.SetInt("MinDepth", minDepthDistance);
                floorDetOffsetEstShader.SetInt("MaxDepth", maxDepthDistance);

                floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "SpaceTable", pointCloudSpaceBuffer);
                floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "DepthMap", pointCloudDepthBuffer);

                floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudPos", pointCloudPosBuffer);
                floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudOfs", pointCloudOfsBuffer);
                floorDetOffsetEstShader.SetBuffer(floorDetOffsetEstKernel, "PointCloudMask", pointCloudMaskBuffer);

                floorDetOffsetEstShader.Dispatch(floorDetOffsetEstKernel, sensorData.depthImageWidth / 8, sensorData.depthImageHeight / 8, 1);

                // FloorDetectionOffsetMinMaxShader
                KinectInterop.SetComputeShaderInt2(floorDetOffsetMinMaxShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight);
                floorDetOffsetMinMaxShader.SetInt("OfsHistBinLength", histBufferLength);
                floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "PointCloudOfs", pointCloudOfsBuffer);
                floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "PointCloudMask", pointCloudMaskBuffer);

                floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "OfsMinMax", ofsHistMinMaxBuffer);
                floorDetOffsetMinMaxShader.SetBuffer(floorDetOffsetMinMaxKernel, "OfsHistBinCount", ofsHistBinCountBuffer);

                floorDetOffsetMinMaxShader.Dispatch(floorDetOffsetMinMaxKernel, 1, 1, 1);

                //ofsHistMinMaxBuffer.GetData(histMinMax);
                //Debug.Log("Hist min: " + histMinMax[0] + ", max: " + histMinMax[1]);

                // FloorDetectionOffsetHistShader
                KinectInterop.SetComputeShaderInt2(floorDetOffsetHistShader, "PointCloudRes", sensorData.depthImageWidth, sensorData.depthImageHeight);
                //floorDetOffsetHistShader.SetInt("PointCloudOfsLength", sensorData.depthImageWidth * sensorData.depthImageHeight);
                floorDetOffsetHistShader.SetInt("OfsHistBinLength", histBufferLength);
                floorDetOffsetHistShader.SetFloat("BinSize", histBinSize);

                floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "PointCloudOfs", pointCloudOfsBuffer);
                floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "PointCloudMask", pointCloudMaskBuffer);
                floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsMinMax", ofsHistMinMaxBuffer);

                floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsHistBinCount", ofsHistBinCountBuffer);
                //floorDetOffsetHistShader.SetBuffer(floorDetOffsetHistKernel, "OfsHistBinLeft", ofsHistBinLeftBuffer);

                floorDetOffsetHistShader.Dispatch(floorDetOffsetHistKernel, sensorData.depthImageWidth / 1, sensorData.depthImageHeight / 1, 1);
                //floorDetOffsetHistShader.Dispatch(floorDetOffsetHistKernel, 1, 1, 1);

                // FloorDetectionPlanePointsShader
                floorDetPlaneEstShader.SetInt("OfsHistBinLength", histBufferLength);
                floorDetPlaneEstShader.SetInt("PointCloudOfsLength", sensorData.depthImageWidth * sensorData.depthImageHeight);
                floorDetPlaneEstShader.SetFloat("BinSize", histBinSize);
                floorDetPlaneEstShader.SetInt("BinAggregation", binAggregation);
                floorDetPlaneEstShader.SetInt("MinimumFloorPointCount", minFloorPointCount / 4);

                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsHistBinCount", ofsHistBinCountBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudPos", pointCloudPosBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudOfs", pointCloudOfsBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PointCloudMask", pointCloudMaskBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsMinMax", ofsHistMinMaxBuffer);

                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "OfsHistBinLeft", ofsHistBinLeftBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "HistCumulativeCount", histCumulativeCountBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "InlierIndices", planeIndicesBuffer);
                floorDetPlaneEstShader.SetBuffer(floorDetPlaneEstKernel, "PlanePosNorm", planePosNormBuffer);

                floorDetPlaneEstShader.Dispatch(floorDetPlaneEstKernel, 1, 1, 1);

                // wait some frames before GetData()
                for (int i = 0; i < WAIT_FRAMES_BEFORE_GPUGET; i++)
                {
                    yield return(null);
                }

                //uint[] histCumCount = new uint[histBufferLength];
                //histCumulativeCountBuffer.GetData(histCumCount);
                //uint maxDiffCount = 0;

                //System.Text.StringBuilder sbCumCount = new System.Text.StringBuilder();
                //for(int i = 1; (i + binAggregation) < histCumCount.Length; i++)  // i += binAggregation
                //{
                //    uint diffCount = histCumCount[i + binAggregation - 1] - histCumCount[i - 1];
                //    if (maxDiffCount < diffCount)
                //        maxDiffCount = diffCount;

                //    if (diffCount > 0)
                //        sbCumCount.Append(i).Append('-').Append(diffCount).Append("  ");
                //}
                //Debug.Log("histCumCount(" + maxDiffCount + "): " + sbCumCount);

                planePosNormBuffer.GetData(planePosNorm);

                vPlanePos  = new Vector3(planePosNorm[0], planePosNorm[1], planePosNorm[2]);
                vPlaneNorm = new Vector3(planePosNorm[3], planePosNorm[4], planePosNorm[5]);
                //Vector3 vPlaneOfs = new Vector3(planePosNorm[6], planePosNorm[7], planePosNorm[8]);
                //Vector3 vPlaneOfs2 = new Vector3(planePosNorm[9], planePosNorm[10], planePosNorm[11]);

                bPlaneValid = (vPlaneNorm != Vector3.zero);

                if (bPlaneValid)
                {
                    //Debug.Log("Plane pos: " + vPlanePos + ", norm: " + vPlaneNorm.normalized + ", rot: " + qSensorRot.eulerAngles + ", ofs: " + vPlaneOfs + ", ofs2: " + vPlaneOfs2);

                    vPlaneNorm = vPlaneNorm.normalized;
                    if (Vector3.Dot(vPlaneNorm, imuUpVector) < 0f)
                    {
                        vPlaneNorm = -vPlaneNorm;
                        //Debug.Log("Inverted plane normal: " + vPlaneNorm);
                    }

                    float floorTiltInDeg = Mathf.Acos(Vector3.Dot(vPlaneNorm, imuUpVector)) * Mathf.Rad2Deg;
                    if (floorTiltInDeg < planeMaxTiltInDeg)
                    {
                        // For reduced jitter, use gravity for floor normal.
                        vPlaneNorm = imuUpVector;
                        //Debug.Log("Used gravity for normal: " + vPlaneNorm + ", tiltAngle: " + floorTiltInDeg);
                    }

                    // get results
                    float fCurTimeSecs  = Time.time;
                    bool  bSmoothResult = (fCurTimeSecs - fLastTimeSecs) < SMOOTH_TIME_THRESHOLD;
                    //Debug.Log("SmoothResult: " + bSmoothResult);
                    fLastTimeSecs = fCurTimeSecs;

                    vPlanePos  = new Vector3(vPlanePos.x * spaceScale.x, vPlanePos.y * spaceScale.y, vPlanePos.z * spaceScale.z);
                    vPlaneNorm = new Vector3(vPlaneNorm.x * spaceScale.x, vPlaneNorm.y * spaceScale.y, vPlaneNorm.z * spaceScale.z);

                    Quaternion curSensorRot = Quaternion.FromToRotation(vPlaneNorm, Vector3.up);
                    qSensorRot = bSmoothResult ? Quaternion.Slerp(qSensorRot, curSensorRot, smoothFactor * Time.deltaTime) : curSensorRot;

                    floorPlane = new Plane(vPlaneNorm, vPlanePos);
                    float curSensorHeight = floorPlane.GetDistanceToPoint(Vector3.zero);
                    fSensorHeight = bSmoothResult ? Mathf.Lerp(fSensorHeight, curSensorHeight, smoothFactor * Time.deltaTime) : curSensorHeight;

                    //Debug.Log("Floor pos: " + vPlanePos + ", norm: " + vPlaneNorm + ", rot: " + qSensorRot.eulerAngles + ", height: " + curSensorHeight + ", smoothed: " + fSensorHeight);
                }
            }
        }
        private void Bake(AnimationClip[] clips)
        {
            if (!infoTexGen)
            {
                infoTexGen = (ComputeShader)Resources.Load("AnimationBaker/Shaders/MeshInfoTextureGen", typeof(ComputeShader));
            }
            if (!playShader)
            {
                playShader = (Shader)Resources.Load("AnimationBaker/Shaders/LitBakedStatePlayer", typeof(Shader));
            }

            AssetDatabase.SaveAssets();

            var instance          = Instantiate(graph.Prefab, Vector3.zero, Quaternion.identity);
            var instanceTransform = instance.transform;
            var skinRenderer      = FindSkinnedMeshRenderer(instanceTransform);

            for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++)
            {
                var mat          = skinRenderer.sharedMaterials[i];
                var materialPath = outputPath + "/" + mat.name + ".mat";
                if (File.Exists(materialPath))
                {
                    File.Delete(materialPath);
                }
            }

            var dataPathLength = Application.dataPath.Length - 6;

            var meshPath = outputPath + "/" + cleanName + "Mesh.asset";

            if (File.Exists(meshPath))
            {
                File.Delete(meshPath);
            }
            meshPath = meshPath.Substring(dataPathLength);

            var positionTexturePath = StringUtils.Combine(outputPath, "Positions.asset");

            if (File.Exists(positionTexturePath))
            {
                File.Delete(positionTexturePath);
            }
            positionTexturePath = positionTexturePath.Substring(dataPathLength);

            var normalTexturePath = StringUtils.Combine(outputPath, "Normals.asset");

            if (File.Exists(normalTexturePath))
            {
                File.Delete(normalTexturePath);
            }
            normalTexturePath = normalTexturePath.Substring(dataPathLength);

            var prefabPath = StringUtils.Combine(outputPath, cleanName + ".prefab");

            if (File.Exists(prefabPath))
            {
                File.Delete(prefabPath);
            }
            prefabPath = prefabPath.Substring(dataPathLength);

            AssetDatabase.Refresh();

            var newAnimation = FindAnimation(instanceTransform);
            var boneMeshes   = new List <MeshFilter>();

            FindMeshInBones(boneMeshes, instanceTransform);
            var  skinTransform = skinRenderer.transform;
            var  oldMesh       = skinRenderer.sharedMesh;
            Mesh newMesh       = new Mesh();
            var  offset        = PopulateMesh(newMesh, oldMesh, boneMeshes, skinRenderer.transform);
            var  verticesCount = newMesh.vertexCount;

            // Save mesh

            AssetDatabase.CreateAsset(newMesh, meshPath);
            graph.rendererData.Mesh         = newMesh;
            graph.rendererData.SubMeshCount = newMesh.subMeshCount;

            var scale = Vector3.one;

            scale.x = 1 / rootBone.localScale.x;
            scale.y = 1 / rootBone.localScale.y;
            scale.z = 1 / rootBone.localScale.z;

            var totalClips  = 0;
            var frames      = new List <int>();
            var frameDeltas = new List <float>();
            var totalFrames = 0;
            var finalClips  = new List <AnimationClip>();

            for (int i = 0; i < clips.Length; i++)
            {
                var clip  = clips[i];
                var delta = clip.frameRate * 0.001f;
                var frame = Mathf.CeilToInt(clip.length / delta);
                frames.Add(frame);
                frameDeltas.Add(delta);
                totalFrames += frame;
                totalClips++;
                finalClips.Add(clip);
            }

            // to store metadata
            totalFrames += 1;

            var texHeight = Mathf.NextPowerOfTwo(totalFrames);
            var texWidth  = Mathf.NextPowerOfTwo(verticesCount);

            // store first cell:
            // total clips

            // second cell and beyond:
            // x: frame count
            // y: 1 / framerate
            // z: offset
            // w: wrap mode:
            //    0 play once the revert to default
            //    1 play once the revert to default
            //    2 loop
            //    4 not implemented
            //    8 play once then hold

            var infoList = new List <VertInfo>();

            int texOffset = 1;

            // infoList.Add(new VertInfo { position = new Vector3(totalClips, 0, 0), normal = Vector3.zero });

            for (int i = 0; i < frames.Count; i++)
            {
                infoList.Add(new VertInfo
                {
                    position = new Vector3(frames[i], finalClips[i].length, texOffset),
                    normal   = Vector3.zero,
                    extra    = (int)finalClips[i].wrapMode
                });
                texOffset += (int)frames[i];
            }
            for (int i = totalClips; i < verticesCount; i++)
            {
                infoList.Add(new VertInfo
                {
                    position = Vector3.zero, normal = Vector3.zero
                });
            }

            var boneOffset = Vector3.zero;
            var boneScale  = 0f;
            var animMesh   = new Mesh();

            for (int i = 0; i < finalClips.Count; i++)
            {
                var clip = finalClips[i];
                var dt   = 0f;
                var len  = 0;
                while (dt < clip.length)
                {
                    clip.SampleAnimation(instance, Mathf.Clamp(dt, 0, clip.length));
                    skinRenderer.BakeMesh(animMesh);
                    if (boneScale == 0)
                    {
                        var bounds = new Bounds();
                        for (int j = 0; j < animMesh.vertexCount; j++)
                        {
                            var point = skinTransform.TransformPoint(animMesh.vertices[j]);
                            if (j == 0)
                            {
                                bounds.center = point;
                            }
                            bounds.Encapsulate(point);
                        }
                        foreach (var filter in boneMeshes)
                        {
                            var boneMesh = filter.sharedMesh;
                            for (int j = 0; j < boneMesh.vertexCount; j++)
                            {
                                var point = filter.transform.TransformPoint(boneMesh.vertices[j]);
                                bounds.Encapsulate(point);
                            }
                        }
                        boneScale    = newMesh.bounds.size.y / bounds.size.y;
                        boneOffset.y = 0 - bounds.min.y;
                    }

                    for (int j = 0; j < animMesh.vertexCount; j++)
                    {
                        var vert = (skinTransform.TransformPoint(animMesh.vertices[j]) + boneOffset) * boneScale;
                        infoList.Add(new VertInfo {
                            position = vert, normal = animMesh.normals[j], extra = 1
                        });
                    }
                    foreach (var filter in boneMeshes)
                    {
                        var mesh = filter.sharedMesh;
                        for (int k = 0; k < mesh.vertexCount; k++)
                        {
                            var vert = (filter.transform.TransformPoint(mesh.vertices[k]) + boneOffset) * boneScale;
                            infoList.Add(new VertInfo {
                                position = vert, normal = mesh.normals[k], extra = 1
                            });
                        }
                    }
                    len++;
                    dt += frameDeltas[i];
                }
            }

            var positionsRenderTexture = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);
            var normalRenderTexture    = new RenderTexture(texWidth, texHeight, 0, RenderTextureFormat.ARGBHalf);
            var positionTexture        = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);

            positionTexture.wrapMode   = TextureWrapMode.Clamp;
            positionTexture.filterMode = FilterMode.Point;
            var normalTexture = new Texture2D(texWidth, texHeight, TextureFormat.RGBAHalf, false, false);

            normalTexture.wrapMode   = TextureWrapMode.Clamp;
            normalTexture.filterMode = FilterMode.Point;

            foreach (var rt in new [] { positionsRenderTexture, normalRenderTexture })
            {
                rt.enableRandomWrite = true;
                rt.Create();
                RenderTexture.active = rt;
                GL.Clear(true, true, Color.clear);
            }

            var buffer = new ComputeBuffer(infoList.Count, System.Runtime.InteropServices.Marshal.SizeOf(typeof(VertInfo)));

            buffer.SetData(infoList.ToArray());

            var  kernel = infoTexGen.FindKernel("CSMain");
            uint x, y, z;

            infoTexGen.GetKernelThreadGroupSizes(kernel, out x, out y, out z);

            infoTexGen.SetInt("VertCount", verticesCount);
            infoTexGen.SetBuffer(kernel, "Info", buffer);
            infoTexGen.SetTexture(kernel, "OutPosition", positionsRenderTexture);
            infoTexGen.SetTexture(kernel, "OutNormal", normalRenderTexture);
            infoTexGen.Dispatch(kernel, verticesCount / (int)x + 1, texHeight / (int)y + 1, 1);

            var posTex  = RenderTextureToTexture2D.Convert(positionsRenderTexture);
            var normTex = RenderTextureToTexture2D.Convert(normalRenderTexture);

            Graphics.CopyTexture(posTex, positionTexture);
            Graphics.CopyTexture(normTex, normalTexture);

            positionsRenderTexture.Release();
            normalRenderTexture.Release();

            buffer.Release();

            AssetDatabase.CreateAsset(positionTexture, positionTexturePath);
            AssetDatabase.CreateAsset(normalTexture, normalTexturePath);

            // var pngData = positionTexture.EncodeToPNG();
            // System.IO.File.WriteAllBytes(Utils.Combine(outputPath, "DebugPositions.png"), pngData);

            AssetDatabase.Refresh();

            var materials = new Material[skinRenderer.sharedMaterials.Length];

            graph.rendererData.Materials         = new Material[skinRenderer.sharedMaterials.Length];
            graph.rendererData.ShadowCastingMode = skinRenderer.shadowCastingMode;
            graph.rendererData.ReceivesShadows   = skinRenderer.receiveShadows;
            for (int i = 0; i < skinRenderer.sharedMaterials.Length; i++)
            {
                var mat = new Material(playShader);
                mat.name = string.Format("{0}.{1}.Material", cleanName, i);
                mat.SetTexture("_MainTex", skinRenderer.sharedMaterials[i].mainTexture);
                mat.SetColor("_Color", skinRenderer.sharedMaterials[i].color);
                mat.SetTexture("_PosTex", positionTexture);
                mat.SetTexture("_NmlTex", normalTexture);
                mat.enableInstancing = true;
                var materialPath = outputPath + "/" + mat.name + ".mat";
                materialPath = materialPath.Substring(dataPathLength);
                AssetDatabase.CreateAsset(mat, materialPath);
                materials[i] = mat;
                graph.rendererData.Materials[i] = mat;
            }
            var go = new GameObject(cleanName);

            go.AddComponent <MeshFilter>().sharedMesh = newMesh;
            AssetDatabase.Refresh();
            var assembly      = Assembly.GetAssembly(typeof(StateGraph));
            var componentType = assembly.GetType("AnimationBaker.Baked." + cleanName + "Component");

            go.AddComponent(componentType);
            var mr = go.AddComponent <MeshRenderer>();

            mr.sharedMaterials = materials;
            mr.material        = materials[0];

            PrefabUtility.CreatePrefab(prefabPath, go);
            DestroyImmediate(go);
            DestroyImmediate(instance);
            EditorUtility.SetDirty(graph.rendererData);
        }
예제 #19
0
        void Update()
        {
            if (_pointSource == null || _template == null ||
                _material == null || _gradient == null)
            {
                return;
            }

            // Lazy initialization.
            if (_drawArgsBuffer == null)
            {
                // Initialize the indirect draw args buffer.
                _drawArgsBuffer = new ComputeBuffer(
                    1, 5 * sizeof(uint), ComputeBufferType.IndirectArguments
                    );

                _drawArgsBuffer.SetData(new uint[5] {
                    _template.GetIndexCount(0), (uint)InstanceCount, 0, 0, 0
                });

                // Allocate compute buffers.
                _positionBuffer  = _pointSource.CreatePositionBuffer();
                _normalBuffer    = _pointSource.CreateNormalBuffer();
                _tangentBuffer   = _pointSource.CreateTangentBuffer();
                _transformBuffer = new ComputeBuffer(TotalThreadCount * 3, 4 * 4);
            }

            // Use a cloned material to avoid issue 914787 ("Only one shadow is
            // cast when using Graphics.DrawMeshInstancedIndirect more than one
            // time per frame").
            // FIXME: remove this when issue 914787 gets fixed.
            if (_tempMaterial == null)
            {
                _tempMaterial = new Material(_material);
            }
            else
            {
                _tempMaterial.CopyPropertiesFromMaterial(_material);
            }

            // Calculate the time-based parameters.
            var noiseOffset = Vector2.one * _randomSeed + _noiseSpeed * _time;
            var pulseTime   = _pulseSpeed * _time + _randomSeed * 443;

            // Invoke the update compute kernel.
            var kernel = _compute.FindKernel("ClonerUpdate");

            _compute.SetInt("InstanceCount", InstanceCount);
            _compute.SetInt("BufferStride", TotalThreadCount);

            _compute.SetFloat("PositionNoise", _displacementByNoise);
            _compute.SetFloat("NormalNoise", _rotationByNoise);

            _compute.SetFloat("BaseScale", _templateScale);
            _compute.SetFloat("ScaleNoise", _scaleByNoise);
            _compute.SetFloat("ScalePulse", _scaleByPulse);

            _compute.SetFloat("NoiseFrequency", _noiseFrequency);
            _compute.SetVector("NoiseOffset", noiseOffset);
            _compute.SetFloat("PulseProbability", _pulseProbability);
            _compute.SetFloat("PulseTime", pulseTime);

            _compute.SetBuffer(kernel, "PositionBuffer", _positionBuffer);
            _compute.SetBuffer(kernel, "NormalBuffer", _normalBuffer);
            _compute.SetBuffer(kernel, "TangentBuffer", _tangentBuffer);
            _compute.SetBuffer(kernel, "TransformBuffer", _transformBuffer);

            _compute.Dispatch(kernel, ThreadGroupCount, 1, 1);

            // Draw the template mesh with instancing.
            if (_props == null)
            {
                _props = new MaterialPropertyBlock();
            }

            _props.SetVector("_GradientA", _gradient.coeffsA);
            _props.SetVector("_GradientB", _gradient.coeffsB);
            _props.SetVector("_GradientC", _gradient.coeffsC2);
            _props.SetVector("_GradientD", _gradient.coeffsD2);

            _props.SetMatrix("_LocalToWorld", transform.localToWorldMatrix);
            _props.SetMatrix("_WorldToLocal", transform.worldToLocalMatrix);

            _props.SetBuffer("_TransformBuffer", _transformBuffer);
            _props.SetFloat("_BufferStride", TotalThreadCount);

            Graphics.DrawMeshInstancedIndirect(
                _template, 0, _tempMaterial, TransformedBounds,
                _drawArgsBuffer, 0, _props
                );

            // Advance the time.
            if (!_timeControlled && Application.isPlaying)
            {
                _time += Time.deltaTime;
            }
        }
예제 #20
0
    public IEnumerator InitModel()
    {
        RenTexture = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat)
        {
            enableRandomWrite = true,
            volumeDepth       = N,
            dimension         = UnityEngine.Rendering.TextureDimension.Tex3D,
            filterMode        = FilterMode.Point,
            wrapMode          = TextureWrapMode.Clamp
        };
        RenTexture.Create();

        Buffer = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat)
        {
            enableRandomWrite = true,
            volumeDepth       = N,
            dimension         = UnityEngine.Rendering.TextureDimension.Tex3D,
            filterMode        = FilterMode.Point,
            wrapMode          = TextureWrapMode.Clamp
        };
        Buffer.Create();

        Display = new RenderTexture(N, N, 24, RenderTextureFormat.RFloat)
        {
            enableRandomWrite = true,
            volumeDepth       = N,
            dimension         = UnityEngine.Rendering.TextureDimension.Tex3D,
            filterMode        = FilterMode,
            wrapMode          = TextureWrapMode.Clamp
        };
        Display.Create();


        yield return(new WaitForSeconds(1));


        PlaneMaterial.SetTexture("_MainTex", Display);
        PlaneMaterial.SetFloat("_MaxValue", StartPotential);



        var initKernelId = Init.FindKernel("CSMain");

        Init.SetTexture(initKernelId, "_Result", RenTexture);
        Init.SetFloat("_InitialValue", StartPotential);
        Init.SetFloat("_NodesCount", N);

        mFigures      = mTree.GetComponentsInChildren <Figure>();
        mFiguresCount = mFigures.Length;

        //Init.SetInt("_MaxStep", mMaxSteps);
        //Init.SetFloat("_MaxDist", MaxDistance);
        Init.SetInt("_FiguresCount", mFiguresCount);

        mBuffer = new ComputeBuffer(mFiguresCount, 132);
        var data = mFigures.Select((x) => new ShaderFigure
        {
            Type   = (int)x.Type,
            Matr   = x.transform.worldToLocalMatrix,
            Params = x.Params
        }).ToArray();

        mBuffer.SetData(data);

        Init.SetBuffer(initKernelId, "_Figures", mBuffer);
        var n4 = N / 4;

        Init.Dispatch(initKernelId, n4, n4, n4);
        //buffer.Dispose();

        yield return(new WaitForSeconds(1));


        mIterationKernelId = Iteraition.FindKernel("CSMain");
        Iteraition.SetTexture(mIterationKernelId, "_Source", RenTexture);
        Iteraition.SetTexture(mIterationKernelId, "_Result", Buffer);


        mIterationHardKernelId = IterationHard.FindKernel("CSMain");
        IterationHard.SetTexture(mIterationKernelId, "_Source", RenTexture);
        IterationHard.SetTexture(mIterationKernelId, "_Result", Buffer);
        IterationHard.SetFloat("_InitialValue", StartPotential);
        IterationHard.SetFloat("_NodesCount", N);
        IterationHard.SetInt("_MaxStep", MaxSteps);
        IterationHard.SetFloat("_Dist", 1f / (N - 1));
        //IterationHard.SetFloat("_MaxDist", MaxDistance);
        IterationHard.SetInt("_FiguresCount", mFiguresCount);
        IterationHard.SetBuffer(mIterationHardKernelId, "_Figures", mBuffer);

        mCopyKernelId = Copy.FindKernel("CSMain");
        Copy.SetTexture(mCopyKernelId, "_Source", Buffer);
        Copy.SetTexture(mCopyKernelId, "_Result", RenTexture);
        Copy.SetTexture(mCopyKernelId, "_ResultAbs", Display);


        yield return(new WaitForSeconds(1));

        mCutFigure = Instantiate(mCutPrefab, mTree);
        mCutFigure.SetActive(Cut);
        mCutFigure.GetComponent <Synch>().From = mCutAnchor;

        mPlane.CanShow = true;

        mStart = true;
        yield break;
    }
    public void BuildMesh(ref TrainerCritterBrushstrokeManager trainerCritterBrushstrokeManagerRef)
    {
        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

        // 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++;
                }
            }
        }

        // OLD: // CritterDecorationsTest.decorationStruct[] points = new CritterDecorationsTest.decorationStruct[totalNumPolys];
        critterPointsDataArray = new TrainerRenderManager.strokeStruct[totalNumPolys];  // first try brushstrokes

        //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;

                    critterPointsDataArray[decindex].pos    = vPos;
                    critterPointsDataArray[decindex].col    = new Vector3(colors[vindex].r, colors[vindex].g, colors[vindex].b);
                    critterPointsDataArray[decindex].normal = normals[vindex];
                    //critterPointsDataArray[decindex].tangent = ;  // Tangent is calculated during initial Skinning (when determining weights)
                    critterPointsDataArray[decindex].prevPos    = vPos;
                    critterPointsDataArray[decindex].dimensions = new Vector2(1f, 1f);
                    critterPointsDataArray[decindex].brushType  = 0; // default
                    // OLD:
                    //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!
        if (critterMesh == null)
        {
            critterMesh = new Mesh();
        }
        else
        {
            critterMesh.Clear();
        }
        //Mesh newMesh = new Mesh();
        critterMesh.vertices  = vertices;
        critterMesh.uv        = uvs;     //Unwrapping.GeneratePerTriangleUV(NewMesh);
        critterMesh.triangles = tris;
        critterMesh.normals   = normals; //NewMesh.RecalculateNormals();
        critterMesh.colors    = colors;
        critterMesh.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 ....
        }
        critterMesh.boneWeights = weights;
        critterMesh.bindposes   = bindPoses;
        SkinnedMeshRenderer skinnedMeshRenderer = this.GetComponent <SkinnedMeshRenderer>();

        skinnedMeshRenderer.bones             = bones;
        skinnedMeshRenderer.sharedMesh        = critterMesh;
        skinnedMeshRenderer.enabled           = true;
        skinnedMeshRenderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.ShadowsOnly;

        cBufferSegmentTransform.Release();


        trainerCritterBrushstrokeManagerRef.TurnOn(critterPointsDataArray);  // Initializes Buffers for Brushstroke
        //critterPointsBuffer = new ComputeBuffer(critterPointsDataArray.Length, sizeof(float) * 3);
        //critterPointsBuffer.SetData(critterPointsDataArray);
        //Debug.Log("BuildMesh count: " + critterPointsDataArray.Length.ToString() + ", 0: " + critterPointsDataArray[0].pos.ToString() + ", 500: " + critterPointsDataArray[500].pos.ToString());
        // OLD: //critterDecorationsTest.TurnOn(points);

        float calcTime = Time.realtimeSinceStartup - startTime;

        //Debug.Log("MeshCreated! " + calcTime.ToString());

        HideSegmentCubes();
    }
예제 #22
0
        public void SetParameters(ComputeShader cs, AtmosphereParameters AP)
        {
            if (cs == null)
            {
                return;
            }

            cs.SetFloat("Rg", AP.bRg);
            cs.SetFloat("Rt", AP.bRt);
            cs.SetFloat("RL", AP.bRl);
            cs.SetInt("TRANSMITTANCE_W", AtmosphereConstants.TRANSMITTANCE_W);
            cs.SetInt("TRANSMITTANCE_H", AtmosphereConstants.TRANSMITTANCE_H);
            cs.SetInt("SKY_W", AtmosphereConstants.SKY_W);
            cs.SetInt("SKY_H", AtmosphereConstants.SKY_H);
            cs.SetInt("RES_R", AtmosphereConstants.RES_R);
            cs.SetInt("RES_MU", AtmosphereConstants.RES_MU);
            cs.SetInt("RES_MU_S", AtmosphereConstants.RES_MU_S);
            cs.SetInt("RES_NU", AtmosphereConstants.RES_NU);
            cs.SetFloat("AVERAGE_GROUND_REFLECTANCE", AP.AVERAGE_GROUND_REFLECTANCE);
            cs.SetFloat("HR", AP.HR);
            cs.SetFloat("HM", AP.HM);

            cs.SetInt("TRANSMITTANCE_INTEGRAL_SAMPLES", AtmosphereConstants.TRANSMITTANCE_INTEGRAL_SAMPLES);
            cs.SetInt("INSCATTER_INTEGRAL_SAMPLES", AtmosphereConstants.INSCATTER_INTEGRAL_SAMPLES);
            cs.SetInt("IRRADIANCE_INTEGRAL_SAMPLES", AtmosphereConstants.IRRADIANCE_INTEGRAL_SAMPLES);
            cs.SetInt("IRRADIANCE_INTEGRAL_SAMPLES_HALF", AtmosphereConstants.IRRADIANCE_INTEGRAL_SAMPLES_HALF);
            cs.SetInt("INSCATTER_SPHERICAL_INTEGRAL_SAMPLES", AtmosphereConstants.INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);

            cs.SetVector("betaR", AP.BETA_R);
            cs.SetVector("betaMSca", AP.BETA_MSca);
            cs.SetVector("betaMEx", AP.BETA_MEx);
            cs.SetFloat("mieG", Mathf.Clamp(AP.MIE_G, 0.0f, 0.99f));
        }
예제 #23
0
    void FixedUpdate()
    {
        //output.Release();
        //output.Create();
        ComputeVoxels.SetTexture(0, "_Result", output);
        ComputeVoxels.Dispatch(0, GridSize / ThreadCount, GridSize / ThreadCount, GridSize / ThreadCount);

        Collider[] cols = Physics.OverlapBox(transform.position, transform.lossyScale * 0.5f, transform.rotation);
        foreach (Collider c in cols)
        {
            Mesh m = c.GetComponent <MeshFilter>().mesh;
            if (m == null)
            {
                return;
            }

            /* Vector3 scale = new Vector3(transform.localScale.x / GridSize, transform.localScale.y / GridSize, transform.localScale.z / GridSize);
             * Matrix4x4 sim2world = Matrix4x4.TRS(transform.position + new Vector3(-.5f * GridSize * scale.x, -.5f * GridSize * scale.y, -.5f * GridSize * scale.z), Quaternion.identity, scale);
             * Matrix4x4 world2sim = sim2world.inverse;
             *
             * Vector3 min = world2sim.MultiplyPoint(c.bounds.min);
             * Vector3 max = world2sim.MultiplyPoint(c.bounds.max);
             *
             * Vector3Int offset;
             * Vector3Int ilength;
             *
             * offset = new Vector3Int(Mathf.FloorToInt(Mathf.Clamp(min.x, 0, GridSize)), Mathf.FloorToInt(Mathf.Clamp(min.y, 0, GridSize)), Mathf.FloorToInt(Mathf.Clamp(min.z, 0, GridSize)));
             *
             * ilength = new Vector3Int(Mathf.CeilToInt(max.x - min.x), Mathf.CeilToInt(max.y - min.y), Mathf.CeilToInt(max.z - min.z));
             * ilength.x = Mathf.Max(GetNearPow2(ilength.x), ThreadCount);
             * ilength.y = Mathf.Max(GetNearPow2(ilength.y), ThreadCount);
             * ilength.z = Mathf.Max(GetNearPow2(ilength.z), ThreadCount);
             *
             * Vector3[] vertices = m.vertices;
             * int[] triangles = m.triangles;
             *
             * Rigidbody rb = c.GetComponent<Rigidbody>();
             * Vector3 vel = rb != null ? rb.velocity : Vector3.zero;
             *
             * ComputeBuffer input_verts = new ComputeBuffer(vertices.Length, sizeof(float) * 3);
             * ComputeBuffer input_tris = new ComputeBuffer(triangles.Length, sizeof(int));
             *
             * input_verts.SetData(vertices);
             * input_tris.SetData(triangles);
             *
             * ComputeVoxels.SetInt("_NumTriangles", triangles.Length);
             * ComputeVoxels.SetVector("_Offset", new Vector3(offset.x, offset.y, offset.z));
             *
             * ComputeVoxels.SetMatrix("_Sim2WorldMat", sim2world);
             * ComputeVoxels.SetMatrix("_Obj2WorldMat", c.transform.localToWorldMatrix);
             *
             * ComputeVoxels.SetBuffer(0, "_Vertices", input_verts);
             * ComputeVoxels.SetBuffer(0, "_Triangles", input_tris);
             * ComputeVoxels.SetTexture(0, "_Result", output);
             *
             * ComputeVoxels.Dispatch(0, ilength.x / ThreadCount, ilength.y / ThreadCount, ilength.z / ThreadCount);
             *
             * DebugMaterial.SetTexture("_Voxels", output);
             *
             * input_verts.Release();
             * input_tris.Release();*/

            Vector3   scale     = new Vector3(transform.localScale.x / GridSize, transform.localScale.y / GridSize, transform.localScale.z / GridSize);
            Matrix4x4 sim2world = Matrix4x4.TRS(transform.position + new Vector3(-.5f * GridSize * scale.x, -.5f * GridSize * scale.y, -.5f * GridSize * scale.z), Quaternion.identity, scale);
            Matrix4x4 world2sim = sim2world.inverse;

            int num_triangles = m.triangles.Length / 3;

            Vector3[] vertices  = m.vertices;
            int[]     triangles = m.triangles;

            ComputeBuffer input_verts = new ComputeBuffer(vertices.Length, sizeof(float) * 3);
            ComputeBuffer input_tris  = new ComputeBuffer(triangles.Length, sizeof(int));

            input_verts.SetData(vertices);
            input_tris.SetData(triangles);

            ComputeVoxels.SetInt("_NumTriangles", num_triangles);

            ComputeVoxels.SetMatrix("_Sim2WorldMat", world2sim);
            ComputeVoxels.SetMatrix("_Obj2WorldMat", c.transform.localToWorldMatrix);

            ComputeVoxels.SetBuffer(1, "_Vertices", input_verts);
            ComputeVoxels.SetBuffer(1, "_Triangles", input_tris);
            ComputeVoxels.SetTexture(1, "_Result", output);

            ComputeVoxels.Dispatch(1, num_triangles / 8 + 1, 1, 1);

            DebugMaterial.SetTexture("_Voxels", output);

            input_verts.Release();
            input_tris.Release();
        }
    }
예제 #24
0
    void Start()
    {
        // Grab phosphor manager
        phosphorManager = FindObjectOfType <PhosphorManager>();
        // Grab chat
        chat = FindObjectOfType <Chat>();

        // Create Kernels and Material
        KernelMain    = computeShader.FindKernel("KMain");
        KInit         = computeShader.FindKernel("KInit");
        KSpawn        = computeShader.FindKernel("KSpawn");
        KInstantiate  = computeShader.FindKernel("KInstantiate");
        KPhosphorFeed = computeShader.FindKernel("KPhosphorFeed");
        KReturn       = computeShader.FindKernel("KReturn");

        triMaterial = new Material(triShader);

        ///
        // Create Buffers
        // Agent Buffers
        agentBuffer0 = new ComputeBuffer(maxAgents, AgentData.size);
        agentBuffer1 = new ComputeBuffer(maxAgents, AgentData.size);

        // Spawn Buffer
        spawnBuffer    = new ComputeBuffer(BLOCK_SIZE * spawnerBlockCount, AgentData.size);
        spawningAgents = new List <AgentData>(BLOCK_SIZE * spawnerBlockCount);

        // Free Buffer
        freeBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append);
        freeBuffer.ClearAppendBuffer();

        // Triangle Instance Buffer
        agentInstanceBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append);
        agentInstanceBuffer.ClearAppendBuffer();

        // Args Buffer
        agentCountArgBuffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.DrawIndirect);
        int[] dArgs = new int[] { 0, 1, 0, 0 };
        agentCountArgBuffer.SetData(dArgs);

        // Targets Buffer
        targetsBuffer = new ComputeBuffer(phosphorManager.phosphorsToSpawn + 1, sizeof(float) * 4);
        targetsArray  = new Vector4[phosphorManager.phosphorsToSpawn + 1];
        // Set home target end of array to zero
        targetsArray[phosphorManager.phosphorsToSpawn] = Vector4.zero;

        // Return Buffer... awful way to do this?
        returnBuffer = new ComputeBuffer(maxAgents, sizeof(int), ComputeBufferType.Append);
        returnIds    = new int[maxAgents];
        returnBuffer.ClearAppendBuffer();


        // Run init shader on initial buffer
        computeShader.SetBuffer(KInit, "appendFreeBuffer", freeBuffer);
        computeShader.SetBuffer(KInit, "agentBufferOut", agentBuffer0);
        computeShader.Dispatch(KInit, maxAgents / BLOCK_SIZE, 1, 1);


        // Init constant uniforms
        computeShader.SetInt("maxAgents", maxAgents);
        computeShader.SetInt("maxPhosphors", phosphorManager.phosphorsToSpawn);
    }
예제 #25
0
    public ColumnResult Generate(int Y_Min, int Y_Max, int xStart, int zStart)
    {
        Stopwatch watch_overall = new Stopwatch();

        watch_overall.Start();

        Stopwatch watch = new Stopwatch();

        watch.Start();
        Sampler.ComputeNoiseGrid(Y_Min, Y_Max, xStart, zStart);
        watch.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): ComputeNoiseGrid: {0}", watch.Elapsed);

        int y_height = (Y_Max - Y_Min) + 2;

        watch.Restart();

        int[]         args      = new int[] { 0, 1, 0, 0 };
        ComputeBuffer argBuffer = new ComputeBuffer(4, sizeof(int), ComputeBufferType.IndirectArguments);

        argBuffer.SetData(args);

        Data       = new ComputeBuffer(Sampler.iso_type_buffer.count, sizeof(int), ComputeBufferType.Append);
        Data_DEBUG = new ComputeBuffer(Sampler.iso_type_buffer.count, sizeof(float) * 2, ComputeBufferType.Append);

        Data.SetCounterValue(0);
        Data_DEBUG.SetCounterValue(0);

        shader.SetBuffer(CS_Generate, "HeightMap", Sampler.height_buffer);
        shader.SetBuffer(CS_Generate, "ISO_Type_Map", Sampler.iso_type_buffer);

        shader.SetBuffer(CS_Generate, "Data", Data);
        shader.SetBuffer(CS_Generate, "Data_DEBUG", Data_DEBUG);

        watch.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Init buffers: {0}", watch.Elapsed);

        watch.Restart();

        shader.SetInt("Y_Min", Y_Min);
        shader.SetInt("Y_Max", Y_Max);
        shader.SetInt("xStart", xStart);
        shader.SetInt("zStart", zStart);
        shader.SetInt("y_height", y_height);

        watch.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Init shader globals: {0}", watch.Elapsed);

        watch.Restart();

        //Debug.LogFormat("GPU Generate: {0} x {1} x {2}", ChunkSizeX, y_height, ChunkSizeZ);
        shader.Dispatch(CS_Generate, ChunkSizeX / 6, y_height - 1, ChunkSizeZ / 6);

        watch.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Dispatch: {0}", watch.Elapsed);

        watch.Restart();

        ComputeBuffer.CopyCount(Data, argBuffer, 0);
        argBuffer.GetData(args);

        Result.surfaceBlocksCount = args[0];
        Result.surfaceBlocks      = new uint[Result.surfaceBlocksCount];
        Data.GetData(Result.surfaceBlocks);

        watch.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Get surfaceBlocks: {0}", watch.Elapsed);

        watch.Restart();

        Debug_Data_Res[] debug_data = new Debug_Data_Res[0];

        if (true)
        {
            debug_data = new Debug_Data_Res[Result.surfaceBlocksCount];
            Data_DEBUG.GetData(debug_data);
        }


        watch.Stop();
        watch_overall.Stop();

        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Get debug_data: {0}", watch.Elapsed);
        UnityGameServer.Logger.Log("GPU_ColumnBuilder Generate(): Overall: {0}", watch_overall.Elapsed);


        Data.Dispose();
        Data_DEBUG.Dispose();

        Sampler.Dispose_ISO_Types();

        for (int i = 0; i < debug_data.Length; i++)
        {
            Vector3Int p1    = debug_data[i].p1;
            Vector3Int p2    = debug_data[i].p2;
            Vector3    orig  = new Vector3(p2.x, p2.y, p2.z);
            Vector3    other = new Vector3(p1.x, p1.y, p1.z);

            UnityEngine.Debug.DrawLine(orig, other, UnityEngine.Color.red, 50000);
        }

        return(Result);
    }
    void PrintCubemap()
    {
        float3[][] forwd = new float3[6][];
        for (int i = 0; i < 6; ++i)
        {
            forwd[i] = new float3[4];
        }
        //Forward
        forwd[4][0] = normalize(float3(-1, 1, 1));
        forwd[4][1] = normalize(float3(1, 1, 1));
        forwd[4][2] = normalize(float3(-1, -1, 1));
        forwd[4][3] = normalize(float3(1, -1, 1));
        //Left
        forwd[1][0] = normalize(float3(-1, 1, -1));
        forwd[1][1] = normalize(float3(-1, 1, 1));
        forwd[1][2] = normalize(float3(-1, -1, -1));
        forwd[1][3] = normalize(float3(-1, -1, 1));
        //Back
        forwd[5][0] = normalize(float3(1, 1, -1));
        forwd[5][1] = normalize(float3(-1, 1, -1));
        forwd[5][2] = normalize(float3(1, -1, -1));
        forwd[5][3] = normalize(float3(-1, -1, -1));

        //Right
        forwd[0][0] = normalize(float3(1, 1, 1));
        forwd[0][1] = normalize(float3(1, 1, -1));
        forwd[0][2] = normalize(float3(1, -1, 1));
        forwd[0][3] = normalize(float3(1, -1, -1));

        //up
        forwd[2][0] = normalize(float3(-1, 1, -1));
        forwd[2][1] = normalize(float3(1, 1, -1));
        forwd[2][2] = normalize(float3(-1, 1, 1));
        forwd[2][3] = normalize(float3(1, 1, 1));

        //down
        forwd[3][0] = normalize(float3(-1, -1, 1));
        forwd[3][1] = normalize(float3(1, -1, 1));
        forwd[3][2] = normalize(float3(-1, -1, -1));
        forwd[3][3] = normalize(float3(1, -1, -1));
        uint2 size = uint2(max((uint)texture.width, 1024), max((uint)texture.height, 1024));

        ComputeBuffer cb       = new ComputeBuffer((int)size.x * (int)size.y, sizeof(float4), ComputeBufferType.Default);
        int           mipCount = useMipMap ? (int)(log2(size.x / 16) + 0.1) : 1;
        TextureData   data     = new TextureData
        {
            depth       = 6,
            width       = size.x,
            height      = size.y,
            mipCount    = (uint)mipCount,
            format      = TextureData.LoadFormat.LoadFormat_RGBAFloat16,
            textureType = TextureType.Cubemap
        };

        readCS.SetTexture(0, "_MainTex", texture);
        readCS.SetBuffer(0, "_ResultBuffer", cb);
        float4[]          readbackValues = new float4[size.x * size.y];
        NativeList <byte> lst            = new NativeList <byte>((int)(size.x * size.y * 1.4), Unity.Collections.Allocator.Temp);
        byte *            headerPtr      = (byte *)data.Ptr();

        for (int i = 0; i < sizeof(TextureData); ++i)
        {
            lst.Add(headerPtr[i]);
        }
        Vector4[] setterArray = new Vector4[4];
        for (int face = 0; face < 6; ++face)
        {
            size = uint2(max((uint)texture.width, 1024), max((uint)texture.height, 1024));
            for (int i = 0; i < mipCount; ++i)
            {
                readCS.SetInt("_TargetMipLevel", i);
                readCS.SetInt("_Count", (int)size.x);
                for (int j = 0; j < 4; ++j)
                {
                    setterArray[j] = (Vector3)forwd[face][j];
                }
                readCS.SetVectorArray("_Directions", setterArray);
                readCS.Dispatch(0, max(1, Mathf.CeilToInt(size.x / 8f)), max(1, Mathf.CeilToInt(size.y / 8f)), 1);
                int cum = (int)(size.x * size.y);
                cb.GetData(readbackValues, 0, 0, cum);
                int pixelSize = 0;
                if (isCubemapCompress)
                {
                    pixelSize = 1;
                    NativeArray <byte> compressedData = new NativeArray <byte>(cum, Allocator.Temp, NativeArrayOptions.UninitializedMemory);
                    BC6UHCompressJob   job;
                    job.dest   = (uint4 *)compressedData.GetUnsafePtr();
                    job.source = readbackValues.Ptr();
                    job.width  = (int)size.x;
                    JobHandle handle = job.Schedule((cum / 16), max((cum / 16) / 20, 1));
                    handle.Complete();
                    for (int a = 0; a < compressedData.Length; ++a)
                    {
                        lst.Add(compressedData[a]);
                    }
                }
                else
                {
                    pixelSize = sizeof(half4);
                    for (int j = 0; j < cum; ++j)
                    {
                        half4 hlfResult = (half4)readbackValues[j];
                        byte *b         = (byte *)hlfResult.Ptr();
                        for (int z = 0; z < sizeof(half4); ++z)
                        {
                            lst.Add(b[z]);
                        }
                    }
                }
                for (int j = cum * pixelSize; j < 512; ++j)
                {
                    lst.Add(0);
                }
                size /= 2;
                size  = max(size, 1);
            }
        }
        byte[] finalArray = new byte[lst.Length];
        UnsafeUtility.MemCpy(finalArray.Ptr(), lst.unsafePtr, lst.Length);
        using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write))
        {
            fs.Write(finalArray, 0, lst.Length);
        }
    }
예제 #27
0
        private static bool CaptureViews(
            Transform root,
            BillboardImposter imposter,
            Snapshots[] snapshots,
            Transform lightingRoot,
            Shader albedoBake,
            Shader normalBake,
            ComputeShader processCompute)
        {
            Vector3 originalScale = root.localScale;

            root.localScale = Vector3.one;
            var prevRt    = RenderTexture.active;
            var baseAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);

            baseAtlas.enableRandomWrite = true;
            baseAtlas.Create();

            var packAtlas = RenderTexture.GetTemporary(_atlasResolution, _atlasResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);

            packAtlas.enableRandomWrite = true;
            packAtlas.Create();
            var tempAtlas = RenderTexture.GetTemporary(baseAtlas.descriptor);

            tempAtlas.Create();

            var frameReso = _atlasResolution / imposter.Frames;
            var frame     = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);

            frame.enableRandomWrite = true;
            frame.Create();

            var packFrame = RenderTexture.GetTemporary(frameReso, frameReso, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);

            packFrame.Create();

            var tempFrame = RenderTexture.GetTemporary(frame.descriptor);

            tempFrame.Create();

            var frameResUpscale = frameReso * 4;
            var superSizedFrame = RenderTexture.GetTemporary(frameResUpscale, frameResUpscale, 32, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);

            superSizedFrame.enableRandomWrite = true;
            superSizedFrame.Create();

            var superSizedFrameTemp = RenderTexture.GetTemporary(superSizedFrame.descriptor);
            var superSizedAlphaMask = RenderTexture.GetTemporary(superSizedFrame.descriptor);

            superSizedAlphaMask.Create();

            imposter.BaseTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true);
            imposter.PackTexture = new Texture2D(baseAtlas.width, baseAtlas.height, TextureFormat.ARGB32, true, true);

            ComputeBuffer minDistancesBuffer = new ComputeBuffer(frame.width * frame.height, sizeof(float));
            ComputeBuffer maxDistanceBuffer  = new ComputeBuffer(1, sizeof(float));

            const int layer      = 30;
            var       clearColor = Color.clear;

            var camera = new GameObject().AddComponent <Camera>();

            camera.gameObject.hideFlags = HideFlags.DontSave;
            camera.cullingMask          = 1 << layer;
            camera.clearFlags           = CameraClearFlags.SolidColor;
            camera.backgroundColor      = clearColor;
            camera.orthographic         = true;
            camera.nearClipPlane        = 0f;
            camera.farClipPlane         = imposter.Radius * 2f;
            camera.orthographicSize     = imposter.Radius;
            camera.allowMSAA            = false;
            camera.enabled = false;

            var frameCount = imposter.Frames * imposter.Frames;

            var originalLayers = new Dictionary <GameObject, int>();

            StoreLayers(root, layer, ref originalLayers);

            var originalLights = new Dictionary <Light, bool>();
            var customLit      = lightingRoot != null;

            if (customLit)
            {
                var lights = FindObjectsOfType <Light>();
                for (var i = 0; i < lights.Length; i++)
                {
                    if (!lights[i].transform.IsChildOf(lightingRoot))
                    {
                        if (originalLights.ContainsKey(lights[i]))
                        {
                            continue;
                        }
                        originalLights.Add(lights[i], lights[i].enabled);
                        lights[i].enabled = false;
                    }
                    else
                    {
                        lights[i].enabled = true;
                        if (!originalLights.ContainsKey(lights[i]))
                        {
                            originalLights.Add(lights[i], false);
                        }
                    }
                }
            }

            var tempMinMaxRT = RenderTexture.GetTemporary(frame.width, frame.height, 0, RenderTextureFormat.ARGB32);

            tempMinMaxRT.Create();

            Graphics.SetRenderTarget(tempMinMaxRT);
            GL.Clear(true, true, Color.clear);

            camera.clearFlags      = CameraClearFlags.Nothing;
            camera.backgroundColor = clearColor;
            camera.targetTexture   = tempMinMaxRT;

            var min = Vector2.one * frame.width;
            var max = Vector2.zero;

            for (var i = 0; i < frameCount; i++)
            {
                if (i > snapshots.Length - 1)
                {
                    Debug.LogError("[Imposter] snapshot data length less than frame count! this shouldn't happen!");
                    continue;
                }

                //position camera with the current snapshot info
                var snap = snapshots[i];
                camera.transform.position = snap.Position;
                camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up);

                //render alpha only
                Shader.SetGlobalFloat("_ImposterRenderAlpha", 1f);
                camera.RenderWithShader(albedoBake, "");
                camera.ResetReplacementShader();

                //render without clearing (accumulating filled pixels)
                camera.Render();

                //supply the root position taken into camera space
                //this is for the min max, in the case root is further from opaque pixels
                var viewPos = camera.WorldToViewportPoint(root.position);
                var texPos  = new Vector2(viewPos.x, viewPos.y) * frame.width;
                texPos.x = Mathf.Clamp(texPos.x, 0f, frame.width);
                texPos.y = Mathf.Clamp(texPos.y, 0f, frame.width);
                min.x    = Mathf.Min(min.x, texPos.x);
                min.y    = Mathf.Min(min.y, texPos.y);
                max.x    = Mathf.Max(max.x, texPos.x);
                max.y    = Mathf.Max(max.y, texPos.y);
            }

            camera.clearFlags      = CameraClearFlags.SolidColor;
            camera.backgroundColor = clearColor;
            camera.targetTexture   = null;

            //now read render texture
            var tempMinMaxTex = new Texture2D(tempMinMaxRT.width, tempMinMaxRT.height, TextureFormat.ARGB32, false);

            RenderTexture.active = tempMinMaxRT;
            tempMinMaxTex.ReadPixels(new Rect(0f, 0f, tempMinMaxRT.width, tempMinMaxRT.height), 0, 0);
            tempMinMaxTex.Apply();

            var tempTexC = tempMinMaxTex.GetPixels32();

            //loop pixels get min max
            for (var c = 0; c < tempTexC.Length; c++)
            {
                if (tempTexC[c].r != 0x00)
                {
                    var texPos = Get2DIndex(c, tempMinMaxRT.width);
                    min.x = Mathf.Min(min.x, texPos.x);
                    min.y = Mathf.Min(min.y, texPos.y);
                    max.x = Mathf.Max(max.x, texPos.x);
                    max.y = Mathf.Max(max.y, texPos.y);
                }
            }

            DestroyImmediate(tempMinMaxTex, true);
            RenderTexture.ReleaseTemporary(tempMinMaxRT);

            //rescale radius
            var len   = new Vector2(max.x - min.x, max.y - min.y);
            var maxR  = Mathf.Max(len.x, len.y);
            var ratio = maxR / frame.width;

            imposter.Radius         = imposter.Radius * ratio;
            camera.farClipPlane     = imposter.Radius * 2f;
            camera.orthographicSize = imposter.Radius;

            Vector3 scaleFactor = new Vector3(root.localScale.x / originalScale.x, root.localScale.y / originalScale.y, root.localScale.z / originalScale.z);

            imposter.Offset = Vector3.Scale(imposter.Offset, scaleFactor);

            snapshots = UpdateSnapshots(imposter.Frames, imposter.Radius, root.position + imposter.Offset, imposter.IsHalf);


            for (var frameIndex = 0; frameIndex < frameCount; frameIndex++)
            {
                if (frameIndex > snapshots.Length - 1)
                {
                    Debug.LogError("[Imposter] snapshot data length less than frame count! this shouldn't happen!");
                    continue;
                }

                var snap = snapshots[frameIndex];
                camera.transform.position = snap.Position;
                camera.transform.rotation = Quaternion.LookRotation(snap.Ray, Vector3.up);
                clearColor = Color.clear;

                //target and clear base frame
                Graphics.SetRenderTarget(superSizedFrame);
                GL.Clear(true, true, clearColor);
                Graphics.SetRenderTarget(superSizedFrameTemp);
                GL.Clear(true, true, clearColor);

                camera.targetTexture   = superSizedFrameTemp;
                camera.backgroundColor = clearColor;

                if (!customLit)
                {
                    Shader.SetGlobalFloat("_ImposterRenderAlpha", 0f);
                    camera.RenderWithShader(albedoBake, "");
                    camera.ResetReplacementShader();
                }
                else
                {
                    camera.Render();
                }

                camera.targetTexture   = superSizedAlphaMask;
                camera.backgroundColor = clearColor;
                camera.Render();

                Graphics.Blit(superSizedAlphaMask, superSizedFrame, _processingMat, 3);
                Graphics.Blit(superSizedFrame, superSizedAlphaMask);

                _processingMat.SetTexture("_MainTex", superSizedFrameTemp);
                _processingMat.SetTexture("_MainTex2", superSizedAlphaMask);
                _processingMat.SetFloat("_Step", 1f);

                Graphics.Blit(superSizedFrameTemp, superSizedFrame, _processingMat, 1);

                Graphics.SetRenderTarget(frame);
                GL.Clear(true, true, clearColor);
                Graphics.Blit(superSizedFrame, frame);

                Graphics.SetRenderTarget(superSizedFrameTemp);
                GL.Clear(true, true, clearColor);
                Graphics.SetRenderTarget(superSizedFrame);
                GL.Clear(true, true, clearColor);

                clearColor             = new Color(0.0f, 0.0f, 0.0f, 0.5f);
                camera.targetTexture   = superSizedFrame;
                camera.backgroundColor = clearColor;
                camera.RenderWithShader(normalBake, "");
                camera.ResetReplacementShader();

                Graphics.SetRenderTarget(packFrame);
                GL.Clear(true, true, clearColor);
                Graphics.Blit(superSizedFrame, packFrame);


                Graphics.SetRenderTarget(tempFrame);
                GL.Clear(true, true, Color.clear);

                int threadsX, threadsY, threadsZ;
                CalcWorkSize(packFrame.width * packFrame.height, out threadsX, out threadsY, out threadsZ);
                processCompute.SetTexture(0, "Source", packFrame);
                processCompute.SetTexture(0, "SourceMask", frame);
                processCompute.SetTexture(0, "Result", tempFrame);
                processCompute.SetBool("AllChannels", true);
                processCompute.SetBool("NormalsDepth", true);
                processCompute.Dispatch(0, threadsX, threadsY, threadsZ);

                Graphics.Blit(tempFrame, packFrame);

                Graphics.SetRenderTarget(tempFrame);
                GL.Clear(true, true, Color.clear);

                CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
                processCompute.SetTexture(0, "Source", frame);
                processCompute.SetTexture(0, "SourceMask", frame);
                processCompute.SetTexture(0, "Result", tempFrame);
                processCompute.SetBool("AllChannels", false);
                processCompute.SetBool("NormalsDepth", false);
                processCompute.Dispatch(0, threadsX, threadsY, threadsZ);

                Graphics.Blit(tempFrame, frame);

                Graphics.SetRenderTarget(tempFrame);
                GL.Clear(true, true, Color.clear);

                CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
                processCompute.SetTexture(1, "Source", frame);
                processCompute.SetTexture(1, "SourceMask", frame);
                processCompute.SetBuffer(1, "MinDistances", minDistancesBuffer);
                processCompute.Dispatch(1, threadsX, threadsY, threadsZ);

                processCompute.SetInt("MinDistancesLength", minDistancesBuffer.count);
                processCompute.SetBuffer(2, "MaxOfMinDistances", maxDistanceBuffer);
                processCompute.SetBuffer(2, "MinDistances", minDistancesBuffer);
                processCompute.Dispatch(2, 1, 1, 1);

                CalcWorkSize(frame.width * frame.height, out threadsX, out threadsY, out threadsZ);
                processCompute.SetTexture(3, "Source", frame);
                processCompute.SetTexture(3, "SourceMask", frame);
                processCompute.SetTexture(3, "Result", tempFrame);
                processCompute.SetBuffer(3, "MinDistances", minDistancesBuffer);
                processCompute.SetBuffer(3, "MaxOfMinDistances", maxDistanceBuffer);
                processCompute.Dispatch(3, threadsX, threadsY, threadsZ);

                Graphics.Blit(tempFrame, frame);

                int x;
                int y;
                XYFromIndex(frameIndex, imposter.Frames, out x, out y);

                x *= frame.width;
                y *= frame.height;

                Graphics.CopyTexture(frame, 0, 0, 0, 0, frame.width, frame.height, baseAtlas, 0, 0, x, y);
                Graphics.CopyTexture(packFrame, 0, 0, 0, 0, packFrame.width, packFrame.height, packAtlas, 0, 0, x, y);
            }

            Graphics.SetRenderTarget(packAtlas);
            imposter.PackTexture.ReadPixels(new Rect(0f, 0f, packAtlas.width, packAtlas.height), 0, 0);

            Graphics.SetRenderTarget(baseAtlas);
            imposter.BaseTexture.ReadPixels(new Rect(0f, 0f, baseAtlas.width, baseAtlas.height), 0, 0);

            RenderTexture.active = prevRt;
            baseAtlas.Release();
            frame.Release();
            packAtlas.Release();
            packFrame.Release();

            RenderTexture.ReleaseTemporary(baseAtlas);
            RenderTexture.ReleaseTemporary(packAtlas);
            RenderTexture.ReleaseTemporary(tempAtlas);

            RenderTexture.ReleaseTemporary(frame);
            RenderTexture.ReleaseTemporary(packFrame);
            RenderTexture.ReleaseTemporary(tempFrame);

            RenderTexture.ReleaseTemporary(superSizedFrame);
            RenderTexture.ReleaseTemporary(superSizedAlphaMask);
            RenderTexture.ReleaseTemporary(superSizedFrameTemp);

            minDistancesBuffer.Dispose();
            maxDistanceBuffer.Dispose();

            DestroyImmediate(camera.gameObject, true);

            //restore layers
            RestoreLayers(originalLayers);

            //restore lights
            var enumerator2 = originalLights.Keys.GetEnumerator();

            while (enumerator2.MoveNext())
            {
                var light = enumerator2.Current;
                if (light != null)
                {
                    light.enabled = originalLights[light];
                }
            }

            enumerator2.Dispose();
            originalLights.Clear();

            var savePath   = "";
            var file       = "";
            var filePrefab = "";

            if (imposter.AssetReference != null)
            {
                savePath = AssetDatabase.GetAssetPath(imposter.AssetReference);
                var lastSlash = savePath.LastIndexOf("/", StringComparison.Ordinal);
                var folder    = savePath.Substring(0, lastSlash);
                file       = savePath.Substring(lastSlash + 1, savePath.LastIndexOf(".", StringComparison.Ordinal) - lastSlash - 1);
                filePrefab = file;
                savePath   = folder + "/" + file + "_Imposter" + ".asset";
            }
            else //no prefab, ask where to save
            {
                file     = root.name;
                savePath = EditorUtility.SaveFilePanelInProject("Save Billboard Imposter", file + "_Imposter", "asset", "Select save location");
            }

            imposter.PrefabSuffix = _suffix;
            imposter.name         = file;
            AssetDatabase.CreateAsset(imposter, savePath);

            imposter.Save(savePath, file, _createUnityBillboard);

            //spawn
            var spawned = imposter.Spawn(root.position, true, filePrefab);

            spawned.transform.position   = root.position + new Vector3(2f, 0f, 2f);
            spawned.transform.rotation   = root.rotation;
            spawned.transform.localScale = originalScale;

            root.localScale = originalScale;

            return(true);
        }
예제 #28
0
    // Update is called once per frame
    void Update()
    {
        //Vector3 offset = target.position - transform.position;
        //offset = new Vector3(Mathf.Round(offset.x * simulationWidth) / simulationWidth, 0.0f, Mathf.Round(offset.z * simulationHeight)/simulationHeight);
        //transform.position = new Vector3(transform.position.x + offset.x, transform.position.y, transform.position.z + offset.z);
        //transform.position = new Vector3(target.position.x, transform.position.y, target.position.z );

        float simW = (float)simulationWidth;
        float simH = (float)simulationHeight;

        Vector3 offset = target.position - transform.position;
        float   scale  = transform.lossyScale.x;
        float   offX   = Mathf.Ceil(offset.x * simW / scale);
        float   offY   = Mathf.Ceil(offset.z * simH / scale);
        float   wOffX  = offX * scale / simW;
        float   wOffY  = offY * scale / simW;

        offset = new Vector3(offX, 0.0f, offY);
        Vector3 offsetWorld = new Vector3(wOffX, 0.0f, wOffY);

        Vector3 newWorldPos = new Vector3(transform.position.x + offsetWorld.x, transform.position.y, transform.position.z + offsetWorld.z);

        //        Debug.Log(offset + "sinW : " + simW + "scale : " + scale + "world :" + offsetWorld);

        m_orthoCam.Render();


        if (currentArray)
        {
            simulateWater.SetBuffer(0, "readBuffer", waterBuffer1);
            simulateWater.SetBuffer(0, "writeBuffer", waterBuffer2);
            renderWater.SetBuffer(0, "simulationBuffer", waterBuffer2);
        }
        else
        {
            simulateWater.SetBuffer(0, "readBuffer", waterBuffer2);
            simulateWater.SetBuffer(0, "writeBuffer", waterBuffer1);
            renderWater.SetBuffer(0, "simulationBuffer", waterBuffer1);
        }

        currentArray = !currentArray;

        //  Debug.Log("dT" + Time.deltaTime);
        simulateWater.SetFloat("deltaTime", Time.deltaTime);
        simulateWater.SetFloat("time", Time.time);

        simulateWater.SetInt("simulationWidth", simulationWidth);
        simulateWater.SetInt("simulationHeight", simulationHeight);
        simulateWater.SetFloat("springStrength", springStrength);
        simulateWater.SetFloat("viscosity", viscosity);
        simulateWater.SetFloat("neighbourSpeedAveraging", neighbourSpeedAveraging);
        simulateWater.SetFloat("neighbourHeightAveraging", neighbourHeightAveraging);
        simulateWater.SetFloat("speedDifferenceToFoam", speedDifferenceToFoam);

        simulateWater.SetFloat("waveHeight", waveHeight[0]);
        simulateWater.SetFloat("waveHeight2", waveHeight[1]);
        simulateWater.SetFloat("waveHeight3", waveHeight[2]);
        simulateWater.SetFloat("waveHeight4", waveHeight[3]);
        simulateWater.SetFloat("waveRadius", waveRadius[0]);
        simulateWater.SetFloat("waveRadius2", waveRadius[1]);
        simulateWater.SetFloat("waveRadius3", waveRadius[2]);
        simulateWater.SetFloat("waveRadius4", waveRadius[3]);
        simulateWater.SetFloat("borderMaskSize", borderMaskSize);

        simulateWater.SetVector("wavePosition", wavePosition[0]);
        simulateWater.SetVector("wavePosition2", wavePosition[1]);
        simulateWater.SetVector("wavePosition3", wavePosition[2]);
        simulateWater.SetVector("wavePosition4", wavePosition[3]);
        simulateWater.SetVector("waterPosition", new Vector4(transform.position.x,
                                                             transform.position.y,
                                                             transform.position.z,
                                                             transform.lossyScale.x));


        simulateWater.SetTextureFromGlobal(0, "_OrthoCollisionsTex", "_OrthoCollisionsTex");


        simulateWater.SetVector("offset", offset);
        simulateWater.SetVector("oldWaterPosition", oldWaterPosition);

        simulateWater.Dispatch(0, simulationWidth * simulationHeight / 32, 1, 1);

        renderWater.SetInt("simulationWidth", simulationWidth);
        renderWater.SetInt("simulationHeight", simulationHeight);
        renderWater.SetTexture(0, "albedo", albedoWater);
        renderWater.SetTexture(0, "normal", normalWater);

        renderWater.Dispatch(0, width / 8, height / 8, 1);

        transform.position = newWorldPos;
        m_orthoCam.transform.SetPositionAndRotation(transform.position - Vector3.up * (waveAverageAmplitude + collisionRenderNearClipBias), Quaternion.LookRotation(Vector3.up, Vector3.forward));



        oldWaterPosition = transform.position;
    }
예제 #29
0
    // Start is called before the first frame update
    void Init()
    {
        shader.SetInt("size", size);
        shader.SetInt("iterations", iterations);
        shader.SetFloat("viscosity", viscosity);
        shader.SetFloat("dt", Time.deltaTime);



        //Lin solve diffuse
        linsolve = shader.FindKernel("LinearSolve");
        shader.SetBuffer(linsolve, "v", velocities);
        shader.SetBuffer(linsolve, "v0", velocities0);
        float a = Time.deltaTime * viscosity * (size - 2) * (size - 2);

        shader.SetFloat("a", a);
        shader.SetFloat("c", 1 + 4 * a);
        //

        // Set bounds V0 true
        setboundsv0 = shader.FindKernel("Setboundsv0");
        shader.SetBuffer(setboundsv0, "v0", velocities0);
        //

        //// Project
        // start
        projectStart = shader.FindKernel("ProjectStart");
        shader.SetBuffer(projectStart, "v", velocities);
        shader.SetBuffer(projectStart, "v0", velocities0);
        //Lin solve 2
        linsolve2 = shader.FindKernel("LinearSolve2");
        shader.SetBuffer(linsolve2, "v", velocities);
        //end
        projectEnd = shader.FindKernel("ProjectEnd");
        shader.SetBuffer(projectEnd, "v", velocities);
        shader.SetBuffer(projectEnd, "v0", velocities0);
        ////


        // Advect
        advect = shader.FindKernel("Advect");
        shader.SetBuffer(advect, "v", velocities);
        shader.SetBuffer(advect, "v0", velocities0);
        shader.SetFloat("dtx", Time.deltaTime * (size - 2));
        shader.SetFloat("dty", Time.deltaTime * (size - 2));
        shader.SetFloat("sizefloat", size);
        //

        //// Project  2
        // start2
        projectStart2 = shader.FindKernel("ProjectStart2");
        shader.SetBuffer(projectStart2, "v", velocities);
        shader.SetBuffer(projectStart2, "v0", velocities0);
        //Lin solve 22
        linsolve22 = shader.FindKernel("LinearSolve22");
        shader.SetBuffer(linsolve22, "v0", velocities0);
        //end2
        projectEnd2 = shader.FindKernel("ProjectEnd2");
        shader.SetBuffer(projectEnd2, "v", velocities);
        shader.SetBuffer(projectEnd2, "v0", velocities0);
        ////


        render = shader.FindKernel("Render");
        shader.SetBuffer(render, "v", velocities);
        shader.SetTexture(render, "Result", result);


        addVelocity = shader.FindKernel("AddVelocity");
        shader.SetBuffer(addVelocity, "v", velocities);

        shader.SetFloats("velToAdd", d);
        int[] i = new int[2];
        i[0] = 50;
        i[1] = 50;
        shader.SetInts("position", i);



        FluidUpdate();
    }
    void InitShaders()
    {
        // Link kernels with shader
        fwdTransfKernel     = shader.FindKernel("MultiplyWToL");
        bckTransfKernel     = shader.FindKernel("MultiplyLToW");
        dispKernel          = shader.FindKernel("movePoints");
        FDEUKernel          = shader.FindKernel("executeFDEUB");
        fwdTransfNormalKern = shader.FindKernel("MultiplyWToLNorm");
        bckTransfNormalKern = shader.FindKernel("MultiplyLToWNorm");
        fwdTransfObsKern    = shader.FindKernel("MultiplyWToLObs");
        bckTransfObsKern    = shader.FindKernel("MultiplyLToWObs");
        fwdTransPlanKern    = shader.FindKernel("MultiplyWToLPla");
        bckTransPlanKern    = shader.FindKernel("MultiplyLToWPla");

        // Link buffer with RWTextures in shader
        myLineBuffer = new ComputeBuffer(lineTab.Length, 3 * sizeof(float));
        myLineBuffer.SetData(lineTab);
        myDisplacementBuffer = new ComputeBuffer(lineTab.Length, 3 * sizeof(float));
        normSrcVecBuffer     = new ComputeBuffer(beginLineNormal.Length, 3 * sizeof(float));
        normSrcVecBuffer.SetData(beginLineNormal);
        normDestVecBuffer = new ComputeBuffer(endLineNormal.Length, 3 * sizeof(float));
        normDestVecBuffer.SetData(endLineNormal);
        if (pointsToAvoid.Length > 0)
        {
            myAvoidPointBuffer = new ComputeBuffer(pointsToAvoid.Length, 3 * sizeof(float));

            myAvoidPointBuffer.SetData(pointsToAvoid);
        }
        else
        {
            myAvoidPointBuffer = new ComputeBuffer(1, 3 * sizeof(float));
            Vector3[] dummyPoint = new Vector3[1];
            dummyPoint[0] = new Vector3(0, 0, 0);
            myAvoidPointBuffer.SetData(dummyPoint);
        }
        myBundleIdBuffer = new ComputeBuffer(bundleId.Length, sizeof(int));
        myBundleIdBuffer.SetData(bundleId);
        int nbPlane = (int)(planeCoord.Length / 4.0);

        //Debug.Log("Nb Plane: "+nbPlane);
        if (nbPlane > 0)
        {
            myAttractivePlane = new ComputeBuffer(planeCoord.Length, 3 * sizeof(float));
            myAttractivePlane.SetData(planeCoord);
        }
        else
        {
            myAttractivePlane = new ComputeBuffer(1, 3 * sizeof(float));
            Vector3[] dummyPoint = new Vector3[1];
            dummyPoint[0] = new Vector3(0, 0, 0);
            myAttractivePlane.SetData(dummyPoint);
        }


        // Coord Transform Buffers
        shader.SetBuffer(fwdTransfKernel, "pos", myLineBuffer);
        shader.SetBuffer(bckTransfKernel, "pos", myLineBuffer);
        shader.SetBuffer(bckTransfKernel, "dispVec", myDisplacementBuffer);
        //Normal coordinate change
        shader.SetBuffer(fwdTransfNormalKern, "normSrcVec", normSrcVecBuffer);
        shader.SetBuffer(fwdTransfNormalKern, "normDestVec", normDestVecBuffer);
        shader.SetBuffer(bckTransfNormalKern, "normSrcVec", normSrcVecBuffer);
        shader.SetBuffer(bckTransfNormalKern, "normDestVec", normDestVecBuffer);
        // Obstacle coordinate change
        if (pointsToAvoid.Length > 0)
        {
            shader.SetBuffer(fwdTransfObsKern, "avoidPoints", myAvoidPointBuffer);
            shader.SetBuffer(bckTransfObsKern, "avoidPoints", myAvoidPointBuffer);
        }
        //Plane Attraction Coordinate change
        if (planeCoord.Length > 0)
        {
            shader.SetBuffer(fwdTransPlanKern, "attracPlane", myAttractivePlane);
            shader.SetBuffer(bckTransPlanKern, "attracPlane", myAttractivePlane);
        }
        // FD Kernel Buffers
        shader.SetBuffer(FDEUKernel, "pos", myLineBuffer);
        shader.SetBuffer(FDEUKernel, "dispVec", myDisplacementBuffer);
        shader.SetBuffer(FDEUKernel, "normSrcVec", normSrcVecBuffer);
        shader.SetBuffer(FDEUKernel, "normDestVec", normDestVecBuffer);
        //if (pointsToAvoid.Length > 0)
        //{
        shader.SetBuffer(FDEUKernel, "avoidPoints", myAvoidPointBuffer);
        //}
        //if(planeCoord.Length > 0)
        //if(nbPlane > 0)
        //{
        //Debug.Log("Set AttractPlane property...");
        shader.SetBuffer(FDEUKernel, "attracPlane", myAttractivePlane);
        //}
        shader.SetBuffer(FDEUKernel, "bundleId", myBundleIdBuffer);
        // Displacement kernel Buffers
        shader.SetBuffer(dispKernel, "pos", myLineBuffer);
        shader.SetBuffer(dispKernel, "dispVec", myDisplacementBuffer);

        // Link shader uniforms
        shader.SetInt("lineNb", lineNb);
        shader.SetInt("obsNb", pointsToAvoid.Length);
        shader.SetFloat("k", springConstant);
        shader.SetFloat("kr", repulsionConstant);
        shader.SetFloat("ka", attractionConstant);
        shader.SetFloat("kor", obstacleRepulsionConstant);
        shader.SetFloat("dmin", obstacleDMin);
        shader.SetFloat("dmax", distanceMaxNormal);
        shader.SetFloat("fmax", forceMaxNormal);
        shader.SetInt("nbPlane", planeCoord.Length);
        shader.SetFloat("dmaxP", distancePlane);
        shader.SetFloat("fmaxP", forcePlane);
    }