Пример #1
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || input == null)
            {
                return(false);
            }

            HistogramUtility.ComputeLuminanceMinMax(cmd, minMaxBuffer, input);
            TextureUtils.UpdateTextureFromCurve(interpolationCurve, ref curveTexture);

            var mat = tempRenderTexture.material = GetTempMaterial("Hidden/Mixture/Levels");

            mat.SetFloat("_Mode", (int)mode);
            mat.SetFloat("_ManualMin", min);
            mat.SetFloat("_ManualMax", max);
            mat.SetVector("_RcpTextureSize", new Vector4(1.0f / input.width, 1.0f / input.height, 1.0f / TextureUtils.GetSliceCount(input), 0));
            MixtureUtils.SetupDimensionKeyword(mat, tempRenderTexture.dimension);
            MixtureUtils.SetTextureWithDimension(mat, "_Input", input);
            mat.SetBuffer("_Luminance", minMaxBuffer);
            mat.SetTexture("_InterpolationCurve", curveTexture);

            tempRenderTexture.Update();
            CustomTextureManager.UpdateCustomRenderTexture(cmd, tempRenderTexture);

            output = tempRenderTexture;

            return(true);
        }
Пример #2
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || input == null)
            {
                return(false);
            }

            SyncSettings();

            UpdateTempRenderTexture(ref outputR);
            UpdateTempRenderTexture(ref outputG);
            UpdateTempRenderTexture(ref outputB);
            UpdateTempRenderTexture(ref outputA);

            SetMaterialParams(outputRMat, 0);
            SetMaterialParams(outputGMat, 1);
            SetMaterialParams(outputBMat, 2);
            SetMaterialParams(outputAMat, 3);

            void SetMaterialParams(Material m, int component)
            {
                MixtureUtils.SetTextureWithDimension(m, "_Source", input);
                m.SetColor("_NeutralColor", neutralColor);
                m.SetFloat("_Mode", (int)mode);
                m.SetInt("_Component", component);
            }

            return(true);
        }
Пример #3
0
        protected override bool ProcessNode()
        {
            UpdateTempRenderTexture(ref output);

            if (material == null || material.shader == null)
            {
                Debug.LogError($"Can't process {name}, missing material/shader.");
                return(false);
            }

            var outputDimension = rtSettings.GetTextureDimension(graph);

            MixtureUtils.SetupDimensionKeyword(material, outputDimension);

#if UNITY_EDITOR // IsShaderCompiled is editor only
            if (!IsShaderCompiled(material.shader))
            {
                output.material = null;
                Debug.LogError($"Can't process {name}, shader has errors.");
                LogShaderErrors(material.shader);
            }
            else
#endif
            {
                output.material = material;
            }

            return(true);
        }
Пример #4
0
        public IEnumerable <PortData> InputPortType(List <SerializableEdge> edges)
        {
            var data = MixtureUtils.UpdateInputPortType(ref inputType, "Input", edges);

            data.acceptMultipleEdges = true;
            yield return(data);
        }
        public override void OnInteractivePreviewGUI(Rect previewRect, GUIStyle background)
        {
            HandleZoomAndPan(previewRect);

            if (firstLockedPreviewTarget?.previewTexture != null && e.type == EventType.Repaint)
            {
                MixtureUtils.SetupDimensionKeyword(previewMaterial, firstLockedPreviewTarget.previewTexture.dimension);

                // Set texture property based on the dimension
                MixtureUtils.SetTextureWithDimension(previewMaterial, "_MainTex0", firstLockedPreviewTarget.previewTexture);
                MixtureUtils.SetTextureWithDimension(previewMaterial, "_MainTex1", secondLockedPreviewTarget.previewTexture);

                previewMaterial.SetFloat("_ComparisonSlider", compareSlider);
                previewMaterial.SetFloat("_ComparisonEnabled", compareEnabled ? 1 : 0);
                previewMaterial.SetFloat("_CompareMode", (int)compareMode);
                previewMaterial.SetFloat("_PreviewMip", mipLevel);
                previewMaterial.SetFloat("_YRatio", previewRect.height / previewRect.width);
                previewMaterial.SetFloat("_Zoom", zoom);
                previewMaterial.SetVector("_Pan", shaderPos / previewRect.size);
                previewMaterial.SetFloat("_FilterMode", (int)filterMode);
                previewMaterial.SetFloat("_Exp", exposure);
                previewMaterial.SetVector("_TextureSize", new Vector4(firstLockedPreviewTarget.previewTexture.width, firstLockedPreviewTarget.previewTexture.height, 1.0f / firstLockedPreviewTarget.previewTexture.width, 1.0f / firstLockedPreviewTarget.previewTexture.height));
                previewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(channels));
                previewMaterial.SetFloat("_IsSRGB0", firstLockedPreviewTarget is OutputNode o0 && o0.mainOutput.sRGB ? 1 : 0);
                previewMaterial.SetFloat("_IsSRGB1", secondLockedPreviewTarget is OutputNode o1 && o1.mainOutput.sRGB ? 1 : 0);
                EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, previewMaterial);
            }
            else
            {
                EditorGUI.DrawRect(previewRect, new Color(1, 0, 1, 1));
            }
        }
Пример #6
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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        protected void BlitMixtureIcon(Texture preview, RenderTexture target, bool realtime = false)
        {
            var blitMaterial = (realtime) ? MixtureUtils.blitRealtimeIconMaterial : MixtureUtils.blitIconMaterial;

            MixtureUtils.SetupDimensionKeyword(blitMaterial, preview.dimension);

            switch (preview.dimension)
            {
            case TextureDimension.Tex2D:
                blitMaterial.SetTexture("_Texture2D", preview);
                Graphics.Blit(preview, target, blitMaterial, 0);
                break;

            case TextureDimension.Tex2DArray:
                blitMaterial.SetTexture("_Texture2DArray", preview);
                Graphics.Blit(preview, target, blitMaterial, 0);
                break;

            case TextureDimension.Tex3D:
                blitMaterial.SetTexture("_Texture3D", preview);
                Graphics.Blit(preview, target, blitMaterial, 0);
                break;

            case TextureDimension.Cube:
                blitMaterial.SetTexture("_Cubemap", preview);
                Graphics.Blit(preview, target, blitMaterial, 0);
                break;

            default:
                Debug.LogError($"{preview.dimension} is not supported for icon preview");
                break;
            }
        }
Пример #9
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();

            rt.Release();
            rt.enableRandomWrite = true;
            rt.Create();

            MixtureUtils.SetupComputeDimensionKeyword(computeShader, input.dimension);

            cmd.SetComputeTextureParam(computeShader, fillUvKernel, "_Input", input);
            cmd.SetComputeTextureParam(computeShader, fillUvKernel, "_Output", output);
            cmd.SetComputeTextureParam(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);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_Input", output);
                cmd.SetComputeTextureParam(computeShader, jumpFloodingKernel, "_Output", rt);
                cmd.SetComputeIntParam(computeShader, "_DistanceMode", (int)distanceMode);
                DispatchCompute(cmd, jumpFloodingKernel, output.width, output.height, output.volumeDepth);
                cmd.CopyTexture(rt, output);
            }

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

            return(true);
        }
Пример #10
0
 protected override void Enable()
 {
     if (createNewPrefab)
     {
         // Create and save the new prefab
         var defaultPrefab = CreateDefaultPrefab();
         prefab = SavePrefab(defaultPrefab);
         MixtureUtils.DestroyGameObject(defaultPrefab);
         ProjectWindowUtil.ShowCreatedAsset(prefab);
     }
     UpdateRenderTextures();
 }
Пример #11
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (output == null)
            {
                return(false);
            }

            var outputDimension = rtSettings.GetTextureDimension(graph);

            MixtureUtils.SetupDimensionKeyword(material, outputDimension);

            var s = material.shader;

            for (int i = 0; i < s.GetPropertyCount(); i++)
            {
                if (s.GetPropertyType(i) != ShaderPropertyType.Texture)
                {
                    continue;
                }

                int id = s.GetPropertyNameId(i);
                if (material.GetTexture(id) != null)
                {
                    continue;                     // Avoid overriding existing textures
                }
                var dim = s.GetPropertyTextureDimension(i);
                if (dim == TextureDimension.Tex2D)
                {
                    continue;                     // Texture2D don't need this feature
                }
                // default texture names doesn't work with cubemap and 3D textures so we do it ourselves...
                switch (s.GetPropertyTextureDefaultName(i))
                {
                case "black":
                    material.SetTexture(id, TextureUtils.GetBlackTexture(dim));
                    break;

                case "white":
                    material.SetTexture(id, TextureUtils.GetWhiteTexture(dim));
                    break;
                    // TODO: grey and bump
                }
            }

            output.material = material;

            bool useCustomUV = material.HasTextureBound("_UV", rtSettings.GetTextureDimension(graph));

            material.SetKeywordEnabled("USE_CUSTOM_UV", useCustomUV);

            return(true);
        }
Пример #12
0
        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];
                    }
                });
            }
        }
Пример #13
0
        bool UpdateFinalCopyMaterial(OutputTextureSettings targetOutput)
        {
            if (targetOutput.finalCopyMaterial == null)
            {
                targetOutput.finalCopyMaterial = CreateFinalCopyMaterial();
                if (!graph.IsObjectInGraph(targetOutput.finalCopyMaterial))
                {
                    graph.AddObjectToGraph(targetOutput.finalCopyMaterial);
                }
            }

            // Manually reset all texture inputs
            ResetMaterialPropertyToDefault(targetOutput.finalCopyMaterial, "_Source_2D");
            ResetMaterialPropertyToDefault(targetOutput.finalCopyMaterial, "_Source_3D");
            ResetMaterialPropertyToDefault(targetOutput.finalCopyMaterial, "_Source_Cube");

            var input = targetOutput.inputTexture;

            if (input != null)
            {
                if (input.dimension != (TextureDimension)rtSettings.dimension)
                {
                    Debug.LogError("Error: Expected texture type input for the OutputNode is " + graph.mainOutputTexture.dimension + " but " + input?.dimension + " was provided");
                    return(false);
                }

                MixtureUtils.SetupDimensionKeyword(targetOutput.finalCopyMaterial, input.dimension);

                if (input.dimension == TextureDimension.Tex2D)
                {
                    targetOutput.finalCopyMaterial.SetTexture("_Source_2D", input);
                }
                else if (input.dimension == TextureDimension.Tex3D)
                {
                    targetOutput.finalCopyMaterial.SetTexture("_Source_3D", input);
                }
                else
                {
                    targetOutput.finalCopyMaterial.SetTexture("_Source_Cube", input);
                }

                targetOutput.finalCopyMaterial.SetInt("_IsSRGB", targetOutput.sRGB ? 1 : 0);
            }

            if (targetOutput.finalCopyRT != null)
            {
                targetOutput.finalCopyRT.material = targetOutput.finalCopyMaterial;
            }

            return(true);
        }
Пример #14
0
        protected override void Enable()
        {
#if UNITY_EDITOR
            if (createNewPrefab)
            {
                // Create and save the new prefab
                var defaultPrefab = GameObject.Instantiate(LoadDefaultPrefab());
                prefab = SavePrefab(defaultPrefab);
                MixtureUtils.DestroyGameObject(defaultPrefab);
                ProjectWindowUtil.ShowCreatedAsset(prefab);
                EditorGUIUtility.PingObject(prefab);
            }
#endif
        }
Пример #15
0
        void GenerateCustomMipMaps()
        {
#if UNITY_EDITOR
            mipchainCmd.Clear();

            mipchainCmd.name = "Generate Custom MipMaps";

            if (mipMapPropertyBlock == null)
            {
                mipMapPropertyBlock = new MaterialPropertyBlock();
            }

            int slice = 0;
            // TODO: support 3D textures and Cubemaps
            // for (int slice = 0; slice < tempRenderTexture.volumeDepth; slice++)
            {
                for (int i = 0; i < tempRenderTexture.mipmapCount - 1; i++)
                {
                    int mipLevel = i + 1;
                    mipmapRenderTexture.name = "Tmp mipmap";
                    mipchainCmd.SetRenderTarget(mipmapRenderTexture, mipLevel, CubemapFace.Unknown, 0);

                    Vector4 textureSize = new Vector4(tempRenderTexture.width, tempRenderTexture.height, tempRenderTexture.volumeDepth, 0);
                    textureSize /= 1 << (mipLevel);
                    Vector4 textureSizeRcp = new Vector4(1.0f / textureSize.x, 1.0f / textureSize.y, 1.0f / textureSize.z, 0);

                    mipMapPropertyBlock.SetTexture("_InputTexture_2D", tempRenderTexture);
                    mipMapPropertyBlock.SetTexture("_InputTexture_3D", tempRenderTexture);
                    mipMapPropertyBlock.SetFloat("_CurrentMipLevel", mipLevel - 1);
                    mipMapPropertyBlock.SetFloat("_MaxMipLevel", tempRenderTexture.mipmapCount);
                    mipMapPropertyBlock.SetVector("_InputTextureSize", textureSize);
                    mipMapPropertyBlock.SetVector("_InputTextureSizeRcp", textureSizeRcp);
                    mipMapPropertyBlock.SetFloat("_CurrentSlice", slice / (float)tempRenderTexture.width);

                    MixtureUtils.SetupDimensionKeyword(customMipMapMaterial, tempRenderTexture.dimension);
                    mipchainCmd.DrawProcedural(Matrix4x4.identity, customMipMapMaterial, 0, MeshTopology.Triangles, 3, 1, mipMapPropertyBlock);

                    mipchainCmd.CopyTexture(mipmapRenderTexture, slice, mipLevel, tempRenderTexture, slice, mipLevel);
                }
            }

            // Dirty hack to enqueue the command buffer but it's okay because it's the builtin renderer.
            if (GraphicsSettings.renderPipelineAsset == null)
            {
                Camera.main.RemoveCommandBuffer(CameraEvent.BeforeDepthTexture, mipchainCmd);
                Camera.main.AddCommandBuffer(CameraEvent.BeforeDepthTexture, mipchainCmd);
            }
#endif
        }
Пример #16
0
        void GenerateCustomMipMaps(CommandBuffer cmd, OutputTextureSettings targetOutput)
        {
#if UNITY_EDITOR
            if (targetOutput.mipmapTempRT == null || targetOutput.finalCopyRT == null)
            {
                return;
            }

            cmd.BeginSample(generateMipMapSampler);

            if (targetOutput.mipMapPropertyBlock == null)
            {
                targetOutput.mipMapPropertyBlock = new MaterialPropertyBlock();
            }

            int slice = 0;
            // TODO: support 3D textures and Cubemaps
            // for (int slice = 0; slice < targetOutput.finalCopyRT.volumeDepth; slice++)
            {
                for (int i = 0; i < targetOutput.finalCopyRT.mipmapCount - 1; i++)
                {
                    int mipLevel = i + 1;
                    targetOutput.mipmapTempRT.name = "Tmp mipmap";
                    cmd.SetRenderTarget(targetOutput.mipmapTempRT, mipLevel, CubemapFace.Unknown, 0);

                    Vector4 textureSize = new Vector4(targetOutput.finalCopyRT.width, targetOutput.finalCopyRT.height, targetOutput.finalCopyRT.volumeDepth, 0);
                    textureSize /= 1 << (mipLevel);
                    Vector4 textureSizeRcp = new Vector4(1.0f / textureSize.x, 1.0f / textureSize.y, 1.0f / textureSize.z, 0);

                    targetOutput.mipMapPropertyBlock.SetTexture("_InputTexture_2D", targetOutput.finalCopyRT);
                    targetOutput.mipMapPropertyBlock.SetTexture("_InputTexture_3D", targetOutput.finalCopyRT);
                    targetOutput.mipMapPropertyBlock.SetFloat("_CurrentMipLevel", mipLevel - 1);
                    targetOutput.mipMapPropertyBlock.SetFloat("_MaxMipLevel", targetOutput.finalCopyRT.mipmapCount);
                    targetOutput.mipMapPropertyBlock.SetVector("_InputTextureSize", textureSize);
                    targetOutput.mipMapPropertyBlock.SetVector("_InputTextureSizeRcp", textureSizeRcp);
                    targetOutput.mipMapPropertyBlock.SetFloat("_CurrentSlice", slice / (float)targetOutput.finalCopyRT.width);

                    MixtureUtils.SetupDimensionKeyword(targetOutput.customMipMapMaterial, targetOutput.finalCopyRT.dimension);
                    cmd.DrawProcedural(Matrix4x4.identity, targetOutput.customMipMapMaterial, 0, MeshTopology.Triangles, 3, 1, targetOutput.mipMapPropertyBlock);

                    cmd.CopyTexture(targetOutput.mipmapTempRT, slice, mipLevel, targetOutput.finalCopyRT, slice, mipLevel);
                }
            }

            cmd.EndSample(generateMipMapSampler);
#endif
        }
Пример #17
0
        public override void OnInteractivePreviewGUI(Rect previewRect, GUIStyle background)
        {
            HandleZoomAndPan(previewRect);

            if (mixtureInspector.firstLockedPreviewTarget?.previewTexture != null && e.type == EventType.Repaint)
            {
                mixtureInspector.volumeCameraMatrix = Matrix4x4.Rotate(Quaternion.Euler(mixtureInspector.cameraYAxis, mixtureInspector.cameraXAxis, 0));

                MixtureUtils.SetupDimensionKeyword(previewMaterial, mixtureInspector.firstLockedPreviewTarget.previewTexture.dimension);

                // Set texture property based on the dimension
                MixtureUtils.SetTextureWithDimension(previewMaterial, "_MainTex0", mixtureInspector.firstLockedPreviewTarget.previewTexture);
                MixtureUtils.SetTextureWithDimension(previewMaterial, "_MainTex1", mixtureInspector.secondLockedPreviewTarget.previewTexture);

                previewMaterial.SetFloat("_ComparisonSlider", mixtureInspector.compareSlider);
                previewMaterial.SetFloat("_ComparisonSlider3D", mixtureInspector.compareSlider3D);
                previewMaterial.SetVector("_MouseUV", mixtureInspector.mouseUV);
                previewMaterial.SetMatrix("_CameraMatrix", mixtureInspector.volumeCameraMatrix);
                previewMaterial.SetFloat("_CameraZoom", mixtureInspector.cameraZoom);
                previewMaterial.SetFloat("_ComparisonEnabled", mixtureInspector.compareEnabled ? 1 : 0);
                previewMaterial.SetFloat("_CompareMode", (int)mixtureInspector.compareMode);
                previewMaterial.SetFloat("_PreviewMip", mixtureInspector.mipLevel);
                previewMaterial.SetFloat("_YRatio", previewRect.height / previewRect.width);
                previewMaterial.SetFloat("_Zoom", mixtureInspector.zoom);
                previewMaterial.SetVector("_Pan", mixtureInspector.shaderPos / previewRect.size);
                previewMaterial.SetFloat("_FilterMode", (int)mixtureInspector.filterMode);
                previewMaterial.SetFloat("_Exp", mixtureInspector.exposure);
                previewMaterial.SetVector("_TextureSize", new Vector4(mixtureInspector.firstLockedPreviewTarget.previewTexture.width, mixtureInspector.firstLockedPreviewTarget.previewTexture.height, 1.0f / mixtureInspector.firstLockedPreviewTarget.previewTexture.width, 1.0f / mixtureInspector.firstLockedPreviewTarget.previewTexture.height));
                previewMaterial.SetVector("_Channels", MixtureEditorUtils.GetChannelsMask(mixtureInspector.channels));
                previewMaterial.SetFloat("_IsSRGB0", mixtureInspector.firstLockedPreviewTarget is OutputNode o0 && o0.mainOutput.sRGB ? 1 : 0);
                previewMaterial.SetFloat("_IsSRGB1", mixtureInspector.secondLockedPreviewTarget is OutputNode o1 && o1.mainOutput.sRGB ? 1 : 0);
                previewMaterial.SetFloat("_PreserveAspect", mixtureInspector.preserveAspect ? 1 : 0);
                previewMaterial.SetFloat("_Texture3DMode", (int)mixtureInspector.texture3DPreviewMode);
                previewMaterial.SetFloat("_Density", mixtureInspector.texture3DDensity);
                previewMaterial.SetFloat("_SDFOffset", mixtureInspector.texture3DDistanceFieldOffset);
                previewMaterial.SetFloat("_SDFChannel", (int)mixtureInspector.sdfChannel);
                previewMaterial.SetFloat("_ShowCubeBackface", mixtureInspector.showCubeBackface ? 1 : 0);
                previewMaterial.SetFloat("_InvertSurface", mixtureInspector.invertSurface ? 1 : 0);
                previewMaterial.SetFloat("_VolumetricDensityChannel", mixtureInspector.volumetricDensityChannel);
                EditorGUI.DrawPreviewTexture(previewRect, Texture2D.whiteTexture, previewMaterial);
            }
            else
            {
                EditorGUI.DrawRect(previewRect, new Color(1, 0, 1, 1));
            }
        }
Пример #18
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || inputMesh?.mesh == null)
            {
                return(false);
            }

            UpdateTempRenderTexture(ref outputVolume);

            // Clear 3D render texture
            cmd.SetComputeTextureParam(computeShader, 0, "_Output", outputVolume);
            DispatchCompute(cmd, 0, outputVolume.width, outputVolume.height, outputVolume.volumeDepth);

            MixtureUtils.RasterizeMeshToTexture3D(cmd, inputMesh, outputVolume, conservativeRaster);

            return(true);
        }
Пример #19
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || textureAsset == null)
            {
                return(false);
            }

#if UNITY_EDITOR
            var importer = UnityEditor.AssetImporter.GetAtPath(UnityEditor.AssetDatabase.GetAssetPath(textureAsset));
            if (importer is UnityEditor.TextureImporter textureImporter)
            {
                normalMap = textureImporter.textureType == UnityEditor.TextureImporterType.NormalMap;
            }
#endif

            // Compressed normal maps need to be converted from AG to RG format
            if (normalMap)
            {
                if (postProcessedTexture == null)
                {
                    postProcessedTexture = new RenderTexture(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat);
                }

                if (postProcessedTexture.width != textureAsset.width || postProcessedTexture.height != textureAsset.height)
                {
                    postProcessedTexture.Release();
                    postProcessedTexture.width  = textureAsset.width;
                    postProcessedTexture.height = textureAsset.height;
                    postProcessedTexture.Create();
                }

                var blitMaterial = GetTempMaterial("Hidden/Mixture/TextureNode");
                MixtureUtils.SetTextureWithDimension(blitMaterial, "_Source", textureAsset);
                MixtureUtils.Blit(cmd, blitMaterial, textureAsset, postProcessedTexture);

                outputTexture = postProcessedTexture;
            }
            else
            {
                postProcessedTexture?.Release();
                outputTexture = textureAsset;
            }

            return(true);
        }
Пример #20
0
        public sealed override void OnGUI(Rect position, MaterialProperty prop, string label, MaterialEditor editor)
        {
            // In case the material is shown in the inspector, the editor will not be linked to a node
            if (!mixtureDrawerInfos.ContainsKey(editor))
            {
                DrawerGUI(position, prop, label, editor, null, null);
                return;
            }

            var nodeView = GetNodeView(editor);
            var graph    = GetGraph(editor);
            var node     = nodeView.nodeTarget as MixtureNode;

            allowedDimensions = MixtureUtils.GetAllowedDimentions(prop.name);

            if (IsVisible(editor))
            {
                DrawerGUI(position, prop, label, editor, graph, nodeView);
            }
        }
Пример #21
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || input == null)
            {
                return(false);
            }

            UpdateTempRenderTexture(ref outputR);
            UpdateTempRenderTexture(ref outputG);
            UpdateTempRenderTexture(ref outputB);
            UpdateTempRenderTexture(ref outputA);

            MixtureUtils.SetTextureWithDimension(outputRMat, "_Source", input);
            MixtureUtils.SetTextureWithDimension(outputGMat, "_Source", input);
            MixtureUtils.SetTextureWithDimension(outputBMat, "_Source", input);
            MixtureUtils.SetTextureWithDimension(outputAMat, "_Source", input);
            outputRMat.SetInt("_Component", 0);
            outputGMat.SetInt("_Component", 1);
            outputBMat.SetInt("_Component", 2);
            outputAMat.SetInt("_Component", 3);

            return(true);
        }
Пример #22
0
 bool PropertySupportsDimension(MaterialProperty prop, TextureDimension dim)
 {
     return(MixtureUtils.GetAllowedDimentions(prop.name).Contains(dim));
 }
Пример #23
0
        protected override bool ProcessNode()
        {
            if (graph.outputTexture == null)
            {
                Debug.LogError("Output Node can't write to target texture, Graph references a null output texture");
                return(false);
            }

            // Update the renderTexture reference for realtime graph
            if (graph.isRealtime)
            {
                if (tempRenderTexture != graph.outputTexture)
                {
                    onTempRenderTextureUpdated?.Invoke();
                }
                tempRenderTexture = graph.outputTexture as CustomRenderTexture;
            }

            var inputPort = GetPort(nameof(input), nameof(input));

            if (inputPort.GetEdges().Count == 0)
            {
                if (uniqueMessages.Add("OutputNotConnected"))
                {
                    AddMessage("Output node input is not connected", NodeMessageType.Warning);
                }
                input = TextureUtils.GetBlackTexture(rtSettings);
                // TODO: set a black texture of texture dimension as default value
                return(false);
            }
            else
            {
                uniqueMessages.Clear();
                ClearMessages();
            }

            // Update the renderTexture size and format:
            if (UpdateTempRenderTexture(ref tempRenderTexture))
            {
                onTempRenderTextureUpdated?.Invoke();
            }

            if (input.dimension != graph.outputTexture.dimension)
            {
                Debug.LogError("Error: Expected texture type input for the OutputNode is " + graph.outputTexture.dimension + " but " + input?.dimension + " was provided");
                return(false);
            }

            MixtureUtils.SetupDimensionKeyword(finalCopyMaterial, input.dimension);

            // Manually reset all texture inputs
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_2D");
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_3D");
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_Cube");

            if (input.dimension == TextureDimension.Tex2D)
            {
                finalCopyMaterial.SetTexture("_Source_2D", input);
            }
            else if (input.dimension == TextureDimension.Tex3D)
            {
                finalCopyMaterial.SetTexture("_Source_3D", input);
            }
            else
            {
                finalCopyMaterial.SetTexture("_Source_Cube", input);
            }

            tempRenderTexture.material = finalCopyMaterial;

            return(true);
        }
Пример #24
0
 static bool IsCompatibleWithRealtimeGraph(BaseGraph graph) => MixtureUtils.IsRealtimeGraph(graph);
Пример #25
0
 public IEnumerable <PortData> InputPortTypeFalse(List <SerializableEdge> edges)
 {
     yield return(MixtureUtils.UpdateInputPortType(ref inputType, "False", edges));
 }
Пример #26
0
        protected override bool ProcessNode(CommandBuffer cmd)
        {
            if (!base.ProcessNode(cmd) || textureAsset == null)
            {
                return(false);
            }

#if UNITY_EDITOR
            var importer = UnityEditor.AssetImporter.GetAtPath(UnityEditor.AssetDatabase.GetAssetPath(textureAsset));
            if (importer is UnityEditor.TextureImporter textureImporter)
            {
                normalMap = textureImporter.textureType == UnityEditor.TextureImporterType.NormalMap;
            }
#endif

            int  targetWidth     = textureAsset.width;
            int  targetHeight    = textureAsset.height;
            int  targetDepth     = TextureUtils.GetSliceCount(textureAsset);
            bool needsTempTarget = false;
            if (!IsPowerOf2(textureAsset) && POTMode != PowerOf2Mode.None)
            {
                int maxSize = Mathf.Max(Mathf.Max(targetWidth, targetHeight), targetDepth);
                int potSize = 0;

                switch (POTMode)
                {
                case PowerOf2Mode.ScaleToNextPowerOf2:
                    potSize = Mathf.NextPowerOfTwo(maxSize);
                    break;

                default:
                    potSize = Mathf.ClosestPowerOfTwo(maxSize);
                    break;
                }
                targetWidth     = targetHeight = targetDepth = potSize;
                needsTempTarget = true;
            }
            if (normalMap)
            {
                needsTempTarget = true;
            }

            if (needsTempTarget && postProcessedTexture == null)
            {
                postProcessedTexture = new RenderTexture(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, mipCount: textureAsset.mipmapCount)
                {
                    dimension = textureAsset.dimension, enableRandomWrite = true, volumeDepth = 1
                }
            }
            ;
            else if (!needsTempTarget)
            {
                postProcessedTexture?.Release();
                postProcessedTexture = null;
            }

            if (postProcessedTexture != null && (postProcessedTexture.width != targetWidth ||
                                                 postProcessedTexture.height != targetHeight ||
                                                 postProcessedTexture.volumeDepth != targetDepth))
            {
                postProcessedTexture.Release();
                postProcessedTexture.width       = targetWidth;
                postProcessedTexture.height      = targetHeight;
                postProcessedTexture.volumeDepth = targetDepth;
                postProcessedTexture.Create();
            }
            // TODO: same alloc as normal map + scale and crop options

            // Compressed normal maps need to be converted from AG to RG format
            if (normalMap)
            {
                // Transform normal map texture into POT
                var blitMaterial = GetTempMaterial("Hidden/Mixture/TextureNode");
                MixtureUtils.SetTextureWithDimension(blitMaterial, "_Source", textureAsset);
                blitMaterial.SetInt("_POTMode", (int)POTMode);
                MixtureUtils.Blit(cmd, blitMaterial, textureAsset, postProcessedTexture, 0);

                outputTexture = postProcessedTexture;
            }
            else if (needsTempTarget)
            {
                // Transform standard texture into POT
                var blitMaterial = GetTempMaterial("Hidden/Mixture/TextureNode");
                MixtureUtils.SetTextureWithDimension(blitMaterial, "_Source", textureAsset);
                blitMaterial.SetInt("_POTMode", (int)POTMode);
                MixtureUtils.Blit(cmd, blitMaterial, textureAsset, postProcessedTexture, 1);

                outputTexture = postProcessedTexture;
            }
            else
            {
                outputTexture = textureAsset;
            }

            if (outputTexture != null)
            {
                settings.sizeMode = OutputSizeMode.Absolute;
                settings.width    = outputTexture.width;
                settings.height   = outputTexture.height;
                settings.depth    = TextureUtils.GetSliceCount(outputTexture);
            }

            return(true);
        }
Пример #27
0
        protected override bool ProcessNode()
        {
            if (graph.outputTexture == null)
            {
                Debug.LogError("Output Node can't write to target texture, Graph references a null output texture");
                return(false);
            }

            // Update the renderTexture reference for realtime graph
            if (graph.isRealtime)
            {
                if (tempRenderTexture != graph.outputTexture)
                {
                    onTempRenderTextureUpdated?.Invoke();
                }
                tempRenderTexture = graph.outputTexture as CustomRenderTexture;
            }

            var inputPort = GetPort(nameof(input), nameof(input));

            if (inputPort.GetEdges().Count == 0)
            {
                if (uniqueMessages.Add("OutputNotConnected"))
                {
                    AddMessage("Output node input is not connected", NodeMessageType.Warning);
                }
            }
            else
            {
                uniqueMessages.Clear();
                ClearMessages();
            }

            // Update the renderTexture size and format:
            if (UpdateTempRenderTexture(ref tempRenderTexture, hasMips, customMipMapShader == null))
            {
                onTempRenderTextureUpdated?.Invoke();
            }

            // Manually reset all texture inputs
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_2D");
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_3D");
            ResetMaterialPropertyToDefault(finalCopyMaterial, "_Source_Cube");

            if (input != null && inputPort.GetEdges().Count != 0)
            {
                if (input.dimension != graph.outputTexture.dimension)
                {
                    Debug.LogError("Error: Expected texture type input for the OutputNode is " + graph.outputTexture.dimension + " but " + input?.dimension + " was provided");
                    return(false);
                }

                MixtureUtils.SetupDimensionKeyword(finalCopyMaterial, input.dimension);

                if (input.dimension == TextureDimension.Tex2D)
                {
                    finalCopyMaterial.SetTexture("_Source_2D", input);
                }
                else if (input.dimension == TextureDimension.Tex3D)
                {
                    finalCopyMaterial.SetTexture("_Source_3D", input);
                }
                else
                {
                    finalCopyMaterial.SetTexture("_Source_Cube", input);
                }
            }

            tempRenderTexture.material = finalCopyMaterial;

            // The CustomRenderTexture update will be triggered at the begining of the next frame so we wait one frame to generate the mipmaps
            // We need to do this because we can't generate custom mipMaps with CustomRenderTextures
            if (customMipMapShader != null && hasMips)
            {
                UpdateTempRenderTexture(ref mipmapRenderTexture, true, false);
                GenerateCustomMipMaps();
            }
            else
            {
                Camera.main.RemoveCommandBuffers(CameraEvent.BeforeDepthTexture);
            }

            return(true);
        }
Пример #28
0
 protected void ClearBuffer(CommandBuffer cmd, ComputeBuffer buffer, int sizeInByte = -1, int offset = 0)
 => MixtureUtils.ClearBuffer(cmd, buffer, sizeInByte, offset);
Пример #29
0
        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);
        }
Пример #30
0
 bool PropertySupportsDimension(string name, TextureDimension dim)
 {
     return(MixtureUtils.GetAllowedDimentions(name).Contains(dim));
 }