Beispiel #1
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            rtSettings.doubleBuffered = true;

            if (!base.ProcessNode(cmd) || inputMesh?.mesh == null)
            {
                return(false);
            }

            UpdateTempRenderTexture(ref outputVolume);
            UpdateTempRenderTexture(ref rayMapBuffer, overrideGraphicsFormat: GraphicsFormat.R32_UInt);
            MixtureUtils.SetupComputeTextureDimension(cmd, computeShader, TextureDimension.Tex3D);

            // Clear 3D render texture
            int clearKernel = mode == Mode.Signed ? clearSignedKernel : clearUnsignedKernel;

            cmd.SetComputeTextureParam(computeShader, clearKernel, "_Output", outputVolume);
            cmd.SetComputeTextureParam(computeShader, clearKernel, "_RayMapsOutput", rayMapBuffer);
            DispatchCompute(cmd, clearKernel, outputVolume.width, outputVolume.height, outputVolume.volumeDepth);

            // Rasterize the mesh in the volume
            MixtureUtils.RasterizeMeshToTexture3D(cmd, inputMesh, outputVolume, conservativeRaster);

            // Generate a distance field with JFA
            JumpFlooding(cmd);

            return(true);
        }
        public static void ComputeLuminanceMinMax(CommandBuffer cmd, ComputeBuffer targetBuffer, Texture input)
        {
            MixtureUtils.SetupComputeTextureDimension(cmd, histogramCompute, input.dimension);

            // Clear buffers
            cmd.SetComputeBufferParam(histogramCompute, clearLuminanceKernel, "_ImageLuminance", luminanceBuffer);
            int dispatchCount = input.width * input.height * TextureUtils.GetSliceCount(input) / 64;
            // Limit computing to 8K textures
            int yCount = Mathf.Clamp(dispatchCount / dispatchGroupSizeX / 64, 1, dispatchGroupSizeX);
            int xCount = Mathf.Clamp(dispatchCount / yCount / 8, 1, dispatchGroupSizeX);

            cmd.SetComputeIntParam(histogramCompute, "_DispatchSizeX", dispatchGroupSizeX);
            cmd.DispatchCompute(histogramCompute, clearLuminanceKernel, xCount, yCount, TextureUtils.GetSliceCount(input));

            // Find luminance min / max in the texture
            cmd.SetComputeTextureParam(histogramCompute, computeLuminanceBufferKernel, "_Input", input);
            cmd.SetComputeBufferParam(histogramCompute, computeLuminanceBufferKernel, "_ImageLuminance", luminanceBuffer);
            cmd.SetComputeVectorParam(histogramCompute, "_InputTextureSize", new Vector4(input.width, input.height, TextureUtils.GetSliceCount(input), 0));
            MixtureUtils.SetTextureWithDimension(cmd, histogramCompute, computeLuminanceBufferKernel, "_Input", input);
            cmd.SetComputeVectorParam(histogramCompute, "_RcpTextureSize", new Vector4(1.0f / input.width, 1.0f / input.height, 1.0f / TextureUtils.GetSliceCount(input), 0));
            cmd.DispatchCompute(histogramCompute, computeLuminanceBufferKernel, Mathf.Max(1, input.width / 8), Mathf.Max(1, input.height / 8), TextureUtils.GetSliceCount(input));

            ReduceLuminanceBuffer(cmd, dispatchCount);

            cmd.SetComputeBufferParam(histogramCompute, copyMinMaxToBuffer, "_ImageLuminance", luminanceBuffer);
            cmd.SetComputeBufferParam(histogramCompute, copyMinMaxToBuffer, "_Target", targetBuffer);
            cmd.DispatchCompute(histogramCompute, copyMinMaxToBuffer, 1, 1, 1);
        }
        public static void ComputeHistogram(CommandBuffer cmd, Texture input, HistogramData data)
        {
            using (new ProfilingScope(cmd, new ProfilingSampler("Generate Histogram")))
            {
                MixtureUtils.SetupComputeTextureDimension(cmd, histogramCompute, input.dimension);

                // Clear buffers
                cmd.SetComputeBufferParam(histogramCompute, clearKernel, "_ImageLuminance", luminanceBuffer);
                cmd.SetComputeBufferParam(histogramCompute, clearKernel, "_Histogram", data.histogram);
                int dispatchCount = input.width * input.height * TextureUtils.GetSliceCount(input) / 64;
                // Limit computing to 8K textures
                int yCount = Mathf.Clamp(dispatchCount / dispatchGroupSizeX / 64, 1, dispatchGroupSizeX);
                int xCount = Mathf.Clamp(dispatchCount / yCount / 8, 1, dispatchGroupSizeX);
                cmd.SetComputeIntParam(histogramCompute, "_DispatchSizeX", dispatchGroupSizeX);
                cmd.DispatchCompute(histogramCompute, clearKernel, xCount, yCount, 1);

                // Find luminance min / max in the texture
                // TODO: handle texture 3D and Cube
                cmd.SetComputeTextureParam(histogramCompute, computeLuminanceBufferKernel, "_Input", input);
                cmd.SetComputeBufferParam(histogramCompute, computeLuminanceBufferKernel, "_ImageLuminance", luminanceBuffer);
                cmd.SetComputeVectorParam(histogramCompute, "_InputTextureSize", new Vector4(input.width, input.height, TextureUtils.GetSliceCount(input), 0));
                cmd.SetComputeVectorParam(histogramCompute, "_RcpTextureSize", new Vector4(1.0f / input.width, 1.0f / input.height, 1.0f / TextureUtils.GetSliceCount(input), 0));
                MixtureUtils.SetTextureWithDimension(cmd, histogramCompute, computeLuminanceBufferKernel, "_Input", input);
                cmd.DispatchCompute(histogramCompute, computeLuminanceBufferKernel, Mathf.Max(1, input.width / 8), Mathf.Max(1, input.height / 8), TextureUtils.GetSliceCount(input));

                ReduceLuminanceBuffer(cmd, dispatchCount);

                // Generate histogram data in compute buffer
                cmd.SetComputeBufferParam(histogramCompute, generateHistogramKernel, "_ImageLuminance", luminanceBuffer);
                cmd.SetComputeBufferParam(histogramCompute, generateHistogramKernel, "_Histogram", data.histogram);
                cmd.SetComputeTextureParam(histogramCompute, generateHistogramKernel, "_Input", input);
                cmd.SetComputeIntParam(histogramCompute, "_HistogramBucketCount", data.bucketCount);
                cmd.SetComputeVectorParam(histogramCompute, "_RcpTextureSize", new Vector4(1.0f / input.width, 1.0f / input.height, 1.0f / TextureUtils.GetSliceCount(input), 0));
                MixtureUtils.SetTextureWithDimension(cmd, histogramCompute, generateHistogramKernel, "_Input", input);
                cmd.DispatchCompute(histogramCompute, generateHistogramKernel, Mathf.Max(1, input.width / 8), Mathf.Max(1, input.height / 8), TextureUtils.GetSliceCount(input));

                cmd.SetComputeBufferParam(histogramCompute, computeHistogramDataKernel, "_HistogramData", data.histogramData);
                cmd.SetComputeBufferParam(histogramCompute, computeHistogramDataKernel, "_Histogram", data.histogram);
                cmd.DispatchCompute(histogramCompute, computeHistogramDataKernel, Mathf.Max(1, data.bucketCount / 64), 1, 1);

                // Request histogram data back for inspector
                cmd.RequestAsyncReadback(luminanceBuffer, 8, 0, (c) => {
                    var d = c.GetData <float>();
                    if (d.Length > 0)
                    {
                        data.minLuminance = d[0];
                        data.maxLuminance = d[1];
                    }
                });
            }
        }
Beispiel #4
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            // Force the double buffering for multi-pass flooding
            rtSettings.doubleBuffered = true;

            if (!base.ProcessNode(cmd) || input == null)
            {
                return(false);
            }

            UpdateTempRenderTexture(ref output);

            cmd.SetComputeFloatParam(computeShader, "_Threshold", threshold);
            cmd.SetComputeVectorParam(computeShader, "_Size", new Vector4(output.width, 1.0f / output.width));
            cmd.SetComputeFloatParam(computeShader, "_Distance", distance / 100.0f);
            cmd.SetComputeIntParam(computeShader, "_ThresholdMode", (int)thresholdMode);
            cmd.SetComputeIntParam(computeShader, "_DistanceMode", (int)distanceMode);
            cmd.SetComputeIntParam(computeShader, "_Mode", (int)mode);

            output.doubleBuffered = true;
            output.EnsureDoubleBufferConsistency();
            var rt = output.GetDoubleBufferRenderTexture();

            if (!rt.enableRandomWrite)
            {
                rt.Release();
                rt.enableRandomWrite = true;
                rt.Create();
            }

            MixtureUtils.SetupComputeTextureDimension(cmd, computeShader, input.dimension);

            MixtureUtils.SetTextureWithDimension(cmd, computeShader, fillUvKernel, "_Input", input);
            MixtureUtils.SetTextureWithDimension(cmd, computeShader, fillUvKernel, "_Output", output);
            MixtureUtils.SetTextureWithDimension(cmd, computeShader, fillUvKernel, "_FinalOutput", rt);
            cmd.SetComputeIntParam(computeShader, "_DistanceMode", (int)distanceMode);
            cmd.SetComputeFloatParam(computeShader, "_InputScaleFactor", (float)input.width / (float)output.width);
            DispatchCompute(cmd, fillUvKernel, output.width, output.height, output.volumeDepth);

            int maxLevels = (int)Mathf.Log(input.width, 2);

            for (int i = 0; i <= maxLevels; i++)
            {
                float offset = 1 << (maxLevels - i);
                cmd.SetComputeFloatParam(computeShader, "_InputScaleFactor", 1);
                cmd.SetComputeFloatParam(computeShader, "_Offset", offset);
                MixtureUtils.SetTextureWithDimension(cmd, computeShader, jumpFloodingKernel, "_Input", output);
                MixtureUtils.SetTextureWithDimension(cmd, computeShader, jumpFloodingKernel, "_Output", rt);
                cmd.SetComputeIntParam(computeShader, "_DistanceMode", (int)distanceMode);
                DispatchCompute(cmd, jumpFloodingKernel, output.width, output.height, output.volumeDepth);
                TextureUtils.CopyTexture(cmd, rt, output);
            }

            cmd.SetComputeFloatParam(computeShader, "_InputScaleFactor", (float)input.width / (float)output.width);
            cmd.SetComputeIntParam(computeShader, "_DistanceMode", (int)distanceMode);
            MixtureUtils.SetTextureWithDimension(cmd, computeShader, finalPassKernel, "_Input", input);
            MixtureUtils.SetTextureWithDimension(cmd, computeShader, finalPassKernel, "_Output", rt);
            MixtureUtils.SetTextureWithDimension(cmd, computeShader, finalPassKernel, "_FinalOutput", output);
            DispatchCompute(cmd, finalPassKernel, output.width, output.height, output.volumeDepth);

            return(true);
        }