Exemple #1
0
        void JumpFlooding(CommandBuffer cmd)
        {
            // TODO: add non-cube support for JFA
            cmd.SetComputeVectorParam(computeShader, "_Size", new Vector4(outputVolume.width, 1.0f / outputVolume.width));

            var rt            = outputVolume.GetDoubleBufferRenderTexture();
            var rayMapBuffer2 = rayMapBuffer.GetDoubleBufferRenderTexture();

            int jumpFloodingKernel = jumpFloodingUnsignedKernel;
            int fillUVKernel       = fillUVUnsignedKernel;
            int finalPassKernel    = finalPassUnsignedKernel;

            if (mode == Mode.Signed)
            {
                jumpFloodingKernel = jumpFloodingSignedKernel;
                fillUVKernel       = fillUVSignedKernel;
                finalPassKernel    = finalPassSignedKernel;
            }

            // TODO: try to get rid of the copies again
            TextureUtils.CopyTexture(cmd, outputVolume, rt);

            // Jump flooding implementation based on https://www.comp.nus.edu.sg/~tants/jfa.html
            // ANd signed version based on 'Generating signed distance fields on the GPU with ray maps'
            cmd.SetComputeTextureParam(computeShader, fillUVKernel, "_Input", rt);
            cmd.SetComputeTextureParam(computeShader, fillUVKernel, "_Output", outputVolume);
            cmd.SetComputeTextureParam(computeShader, fillUVKernel, "_RayMapsOutput", rayMapBuffer2);
            DispatchCompute(cmd, fillUVKernel, outputVolume.width, outputVolume.height, outputVolume.volumeDepth);

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

            for (int i = 0; i <= maxLevels; i++)
            {
                float offset = 1 << (maxLevels - i);
                cmd.SetComputeFloatParam(computeShader, "_Offset", offset);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_Input", outputVolume);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_Output", rt);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_RayMapsInput", rayMapBuffer2);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_RayMapsOutput", rayMapBuffer);
                DispatchCompute(cmd, jumpFloodingKernel, outputVolume.width, outputVolume.height, outputVolume.volumeDepth);
                TextureUtils.CopyTexture(cmd, rt, outputVolume);
                if (mode == Mode.Signed)
                {
                    TextureUtils.CopyTexture(cmd, rayMapBuffer, rayMapBuffer2);
                }
            }

            // TODO: compute sign based on ray maps
            if (mode == Mode.Signed)
            {
            }

            // TODO: in final pass, combine signness with distance for SDF

            cmd.SetComputeTextureParam(computeShader, finalPassKernel, "_Input", rt);
            cmd.SetComputeTextureParam(computeShader, finalPassKernel, "_Output", outputVolume);
            cmd.SetComputeTextureParam(computeShader, finalPassKernel, "_RayMapsInput", rayMapBuffer2);
            cmd.SetComputeTextureParam(computeShader, finalPassKernel, "_RayMapsOutput", rayMapBuffer);
            DispatchCompute(cmd, finalPassKernel, outputVolume.width, outputVolume.height, outputVolume.volumeDepth);
        }
Exemple #2
0
        void UpdateIsDirtyAndPreview()
        {
            if (updateNeededInfoBox == null)
            {
                return;
            }

            isDirty = variant.IsDirty();
            updateNeededInfoBox.style.display = isDirty ? DisplayStyle.Flex : DisplayStyle.None;

            if (isDirty)
            {
                // Copy the result into the inspector preview RT
                var output = graph.outputNode.outputTextureSettings.FirstOrDefault(n => n.name == defaultTextureEditor.target.name);
                if (output == null)
                {
                    output = graph.outputNode.outputTextureSettings.First();
                }

                // Refresh the preview in the inspector:
                var graphicsFormat = graph.outputNode.settings.GetGraphicsFormat(graph);
                var width          = graph.outputNode.settings.GetResolvedWidth(graph);
                var height         = graph.outputNode.settings.GetResolvedHeight(graph);
                var depth          = graph.outputNode.settings.GetResolvedDepth(graph);
                var filterMode     = graph.outputNode.settings.GetResolvedFilterMode(graph);
                var wrapMode       = graph.outputNode.settings.GetResolvedWrapMode(graph);
                var dimension      = graph.outputNode.settings.GetResolvedTextureDimension(graph);

                if (variantPreview.graphicsFormat != graphicsFormat ||
                    variantPreview.height != height ||
                    variantPreview.width != width ||
                    variantPreview.volumeDepth != depth ||
                    variantPreview.filterMode != filterMode ||
                    variantPreview.wrapMode != wrapMode ||
                    variantPreview.dimension != dimension ||
                    variantPreview.useMipMap != output.hasMipMaps)
                {
                    variantPreview.Release();
                    variantPreview.graphicsFormat = graphicsFormat;
                    variantPreview.width          = width;
                    variantPreview.height         = height;
                    variantPreview.volumeDepth    = depth;
                    variantPreview.filterMode     = filterMode;
                    variantPreview.wrapMode       = wrapMode;
                    variantPreview.dimension      = dimension;
                    variantPreview.name           = target.name + "*";
                    variantPreview.useMipMap      = output.hasMipMaps;
                    variantPreview.Create();
                }

                // Update the texture in the inspector
                variant.ProcessGraphWithOverrides();

                TextureUtils.CopyTexture(output.finalCopyRT, variantPreview);

                // If the parentGraph is opened in the editor, we don't want to mess with previews
                // so we update the parentGraph with the original params again.
                if (IsMixtureEditorOpened(graph))
                {
                    MixtureGraphProcessor.RunOnce(graph);
                }

                if (variantPreviewEditor == null || variantPreviewEditor.target != variantPreview)
                {
                    Editor.CreateCachedEditor(variantPreview, renderTextureEditorType, ref variantPreviewEditor);
                }
            }
        }
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            rtSettings.doubleBuffered = true;
            if (!base.ProcessNode(cmd) || input == null)
            {
                return(false);
            }

            TextureUtils.CopyTexture(cmd, input, output, false);

            var mipmapGenMat = GetTempMaterial("Hidden/Mixture/GenerateMipMaps");

            if (mode == Mode.Custom)
            {
                mipmapGenMat = material;
            }
            else
            {
                output.material = null;
            }

            if (mode == Mode.Auto)
            {
                cmd.GenerateMips(output);
            }
            else
            {
                var props = new MaterialPropertyBlock();
                MixtureUtils.SetupDimensionKeyword(mipmapGenMat, rtSettings.GetTextureDimension(graph));
                mipmapGenMat.SetFloat("_Mode", (int)mode);
                MixtureUtils.SetTextureWithDimension(props, "_PreviousMip", input);
                // Manually generate mips:
                for (int i = 0; i < output.mipmapCount - 1; i++)
                {
                    props.SetFloat("_SourceMip", i);
                    float width  = Mathf.Max(1, input.width >> i);
                    float height = Mathf.Max(1, input.width >> i);
                    float depth  = Mathf.Max(1, TextureUtils.GetSliceCount(input) >> i);
                    props.SetVector("_RcpTextureSize", new Vector4(1.0f / width, 1.0f / height, 1.0f / depth, 0.0f));
                    output.material = mipmapGenMat;

                    if (mode == Mode.Gaussian)
                    {
                        // 2 passes of gaussian blur for 2D and Cubemaps
                        props.SetVector("_GaussianBlurDirection", Vector3.right);
                        CustomTextureManager.UpdateCustomRenderTexture(cmd, output, 1, i + 1, props);
                        TextureUtils.CopyTexture(cmd, output.GetDoubleBufferRenderTexture(), output, i + 1);

                        props.SetFloat("_SourceMip", i + 1);
                        MixtureUtils.SetTextureWithDimension(props, "_PreviousMip", output);
                        props.SetVector("_GaussianBlurDirection", Vector3.up);
                        CustomTextureManager.UpdateCustomRenderTexture(cmd, output, 1, i + 1, props);

                        // And a third pass if we're in 3D
                        if (input.dimension == TextureDimension.Tex3D)
                        {
                            props.SetVector("_GaussianBlurDirection", Vector3.forward);
                            TextureUtils.CopyTexture(cmd, output.GetDoubleBufferRenderTexture(), output, i + 1);
                            CustomTextureManager.UpdateCustomRenderTexture(cmd, output, 1, i + 1, props);
                        }
                    }
                    else
                    {
                        CustomTextureManager.UpdateCustomRenderTexture(cmd, output, 1, i + 1, props);
                    }

                    TextureUtils.CopyTexture(cmd, output.GetDoubleBufferRenderTexture(), output, i + 1);
                    MixtureUtils.SetTextureWithDimension(props, "_PreviousMip", output);
                }
            }
            output.material = null;

            return(true);
        }
Exemple #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);
        }