Esempio n. 1
0
        private void DomainSettingsGUI()
        {
            noiseTypeName.stringValue = NoiseLib.NoiseTypePopup(Styles.noiseType, noiseTypeName.stringValue);
            INoiseType noiseType = NoiseLib.GetNoiseTypeInstance(noiseTypeName.stringValue);

            noiseTypeParams.stringValue = noiseType?.DoGUI(noiseTypeParams.stringValue);

            fractalTypeName.stringValue = NoiseLib.FractalTypePopup(Styles.fractalType, fractalTypeName.stringValue);
            IFractalType fractalType = NoiseLib.GetFractalTypeInstance(fractalTypeName.stringValue);

            fractalTypeParams.stringValue = fractalType?.DoGUI(fractalTypeParams.stringValue);
        }
Esempio n. 2
0
        /// <summary>
        /// Sets up the provided Material to be used with this NoiseSettings instance. Some assumptions are made
        /// here as far as definitions and variable declarations in the Material's Shader go.
        /// float4 _NoiseTranslation, float4 _NoiseRotation, float4 _NoiseScale, and float4x4 _NoiseTransform are
        /// assumed to be declared. Sets up the Material using the NoiseType and FractalType SetupMaterial
        /// functions.
        /// </summary>
        /// <param name="mat"> The Material to set up for use with this NoiseSettings instance </param>
        public void SetupMaterial(Material mat)
        {
            INoiseType   noiseType   = NoiseLib.GetNoiseTypeInstance(domainSettings.noiseTypeName);
            IFractalType fractalType = NoiseLib.GetFractalTypeInstance(domainSettings.fractalTypeName);

            // set individual transform info
            mat.SetVector(ShaderStrings.translation, transformSettings.translation);
            mat.SetVector(ShaderStrings.rotation, transformSettings.rotation);
            mat.SetVector(ShaderStrings.scale, transformSettings.scale);

            // set full transform matrix
            mat.SetMatrix(ShaderStrings.transform, trs);

            noiseType?.SetupMaterial(mat, domainSettings.noiseTypeParams);
            fractalType?.SetupMaterial(mat, domainSettings.fractalTypeParams);
        }
Esempio n. 3
0
        /// <summary>
        /// Renders a Popup using EditorGUILayout.Popup for all loaded FractalType implementations
        /// </summary>
        /// <param name="label"> Label prefix for the Popup </param>
        /// <param name="selectedName"> The currently selected FractalType name </param>
        public static string FractalTypePopup(GUIContent label, string selectedName)
        {
            string[] names = NoiseLib.GetFractalNames();
            int      index = NoiseLib.GetFractalIndex(selectedName);

            index = index < 0 ? 0 : index;

            int    newIndex = EditorGUILayout.Popup(label, index, names);
            string newName  = names[newIndex];

            if (newName.CompareTo(selectedName) != 0)
            {
                selectedName = newName;
            }

            return(selectedName);
        }
        public GeneratedShaderInfo(IFractalType fractalType, INoiseType noiseType)
        {
            this.fractalDesc = fractalType.GetDescription();
            this.noiseDesc   = noiseType.GetDescription();

            this.noiseIncludeStr = string.Format("#include \"{0}\"", noiseDesc.sourcePath);

            if (!string.IsNullOrEmpty(fractalDesc.name))
            {
                this.variantName = string.Format("{0}{1}", fractalDesc.name, noiseDesc.name);
            }
            else
            {
                this.variantName = noiseDesc.name;
            }

            // set the path of the generated file. this will be used when writing the file
            // to disk and when adding the include in any generated shaders that use this
            // fractal and noise type variant
            this.generatedIncludePath = string.Format("{0}/{1}/{2}.hlsl", noiseDesc.outputDir,
                                                      fractalDesc.name,
                                                      noiseDesc.name);
            this.outputDir = string.Format("{0}/{1}", noiseDesc.outputDir, fractalDesc.name);

            fractalStructName = string.Format("{0}FractalInput", fractalDesc.name);
            noiseStructName   = string.Format("{0}NoiseInput", noiseDesc.name);
            numFractalInputs  = fractalDesc.inputStructDefinition == null ? 0 : fractalDesc.inputStructDefinition.Count;
            numNoiseInputs    = noiseDesc.inputStructDefinition == null ? 0 : noiseDesc.inputStructDefinition.Count;
            fractalParamStr   = null;
            noiseParamStr     = null;
            functionInputStr  = "";

            // construct include paths string
            additionalIncludePaths = "\n";

            for (int i = 0; i < fractalDesc.additionalIncludePaths.Count; ++i)
            {
                additionalIncludePaths += $"#include \"{ fractalDesc.additionalIncludePaths[ i ] }\"\n";
            }

            additionalIncludePaths += "\n";

            // generate the string for the fractal type structure as it would appear as a parameter
            // in an HLSL function declaration
            if (numFractalInputs > 0)
            {
                fractalParamStr = string.Format("{0} {1}", fractalStructName, "fractalInput");
            }

            // generate the string for the noise type structure as it would appear as a parameter
            // in an HLSL function declaration
            if (numNoiseInputs > 0)
            {
                noiseParamStr = string.Format("{0} {1}", noiseStructName, "noiseInput");
            }

            // generate the argument string for an HLSL function declaration that would be
            // using this combination of noise and fractal type structure definitions
            functionParamStr = "";

            if (fractalParamStr != null)
            {
                functionParamStr += fractalParamStr;
                functionInputStr += "fractalInput";
            }

            if (fractalParamStr != null && noiseParamStr != null)
            {
                functionParamStr += ", ";
                functionInputStr += ", ";
            }

            if (noiseParamStr != null)
            {
                functionParamStr += noiseParamStr;
                functionInputStr += "noiseInput";
            }

            fractalStructDef = "";

            if (numFractalInputs > 0)
            {
                fractalStructDef = NoiseLib.BuildStructString(fractalStructName, fractalDesc.inputStructDefinition);

                string getDefaultFuncStr = NoiseLib.GetDefaultFunctionString(fractalStructName, fractalDesc.inputStructDefinition);
                fractalStructDef += $"\n\n{ getDefaultFuncStr }\n\n";
            }

            noiseStructDef = "";

            if (numNoiseInputs > 0)
            {
                noiseStructDef = NoiseLib.BuildStructString(noiseStructName, noiseDesc.inputStructDefinition);
            }

            // get input str construction
            getInputsStr       = "";
            getFractalInputStr = NoiseLib.GetInputFunctionCallString(fractalStructName);
            getNoiseInputStr   = NoiseLib.GetInputFunctionCallString(fractalStructName);

            if (numFractalInputs > 0)
            {
                getInputsStr += getFractalInputStr;
            }

            if (numFractalInputs > 0 && numNoiseInputs > 0)
            {
                getInputsStr += ", ";
            }

            if (numNoiseInputs > 0)
            {
                getInputsStr += getNoiseInputStr;
            }

            // get default input str construction
            getDefaultInputsStr       = "";
            getDefaultFractalInputStr = NoiseLib.GetDefaultInputFunctionCallString(fractalStructName);
            getDefaultNoiseInputStr   = NoiseLib.GetDefaultInputFunctionCallString(noiseStructName);

            if (numFractalInputs > 0)
            {
                getDefaultInputsStr += getDefaultFractalInputStr;
            }

            if (numFractalInputs > 0 && numNoiseInputs > 0)
            {
                getDefaultInputsStr += ", ";
            }

            if (numNoiseInputs > 0)
            {
                getDefaultInputsStr += getDefaultNoiseInputStr;
            }

            fractalPropertyDefStr = "";

            if (fractalDesc.inputStructDefinition != null &&
                fractalDesc.inputStructDefinition.Count > 0)
            {
                fractalPropertyDefStr  = NoiseLib.GetPropertyDefinitionStr(fractalDesc.name, fractalDesc.inputStructDefinition);
                fractalPropertyDefStr += "\n" + NoiseLib.GetPropertyFunctionStr(fractalStructName, fractalDesc.name, fractalDesc.inputStructDefinition);
            }
        }
        public override void Eval(FilterContext fc)
        {
            if (m_noiseSettings == null)
            {
                m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>();
            }

            m_noiseSettings.useTextureForPositions = m_useHeightmap;

            if (m_useHeightmap)
            {
                m_noiseSettings.positionTexture = fc.renderTextureCollection[FilterContext.Keywords.Heightmap];
            }

            Vector3 brushPosWS    = fc.brushPos;
            float   brushSize     = fc.brushSize;
            float   brushRotation = fc.brushRotation;

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = m_noiseSettings;
            Material      mat           = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(mat);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = false == m_isLocalSpace;

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            Quaternion rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            Matrix4x4  translation  = Matrix4x4.Translate(brushPosWS);
            Matrix4x4  rotation     = Matrix4x4.Rotate(rotQ);
            Matrix4x4  scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            Matrix4x4  noiseToWorld = translation * scale;

            mat.SetMatrix(NoiseSettings.ShaderStrings.transform, noiseSettings.trs * noiseToWorld);

            int pass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            RenderTextureDescriptor desc = new RenderTextureDescriptor(fc.destinationRenderTexture.width, fc.destinationRenderTexture.height, RenderTextureFormat.RFloat);
            RenderTexture           rt   = RenderTexture.GetTemporary(desc);

            Graphics.Blit(fc.sourceRenderTexture, rt, mat, pass);

            Material blendMat = FilterUtility.blendModesMaterial;

            blendMat.SetTexture("_MainTex", fc.sourceRenderTexture);
            blendMat.SetTexture("_BlendTex", rt);

            Graphics.Blit(fc.sourceRenderTexture, fc.destinationRenderTexture, blendMat, 1);

            RenderTexture.ReleaseTemporary(rt);
        }
Esempio n. 6
0
 /// <summary>
 /// Returns a Material reference to the default blit material for the given Type of FractalType.
 /// </summary>
 /// <remarks> Usage is: Material mat = GetDefaultBlitMaterial( typeof(FbmFractalType) ); </remarks>
 /// <returns> A reference to the default blit Material for the specified Type of FractalType </return>
 /// <param name="fractalType"> The Type for a given FractalType </param>
 public static Material GetDefaultBlitMaterial(Type fractalType)
 {
     return(NoiseLib.GetGeneratedMaterial(typeof(NoiseBlitShaderGenerator), fractalType));
 }
Esempio n. 7
0
        /// <summary>
        /// Blits 2D noise defined by the given NoiseSettings instance into the destination RenderTexture
        /// using the provided Material.
        /// </summary>
        /// <param name = "noise"> An instance of NoiseSettings defining the type of noise to render </param>
        /// <param name = "dest"> The destination RenderTexture that the noise will be rendered into. </param>
        /// <param name = "mat"> The Material to be used for rendering the noise </param>
        public static void Blit2D(NoiseSettings noise, RenderTexture dest, Material mat)
        {
            int pass = NoiseLib.GetNoiseIndex(noise.domainSettings.noiseTypeName);

            INTERNAL_Blit2D(noise, dest, mat, pass * kNumBlitPasses + 0);
        }
Esempio n. 8
0
 /// <summary>
 /// Function that is called when an asset with the ".noisehlsltemplate" extension is imported by the AssetDatabase
 /// </summary>
 /// <param name = "ctx"> The context for the imported asset </param>
 public override void OnImportAsset(AssetImportContext ctx)
 {
     NoiseLib.GenerateHeaderFiles();
     NoiseLib.GenerateShaders();
 }
Esempio n. 9
0
        //===================================================================================================
        //
        //      APPLY BRUSH
        //
        //===================================================================================================

        private void ApplyBrushInternal(PaintContext ctx, BrushTransform brushXform, Vector3 brushPosWS,
                                        float brushRotation, float brushStrength, float brushSize, Texture brushTexture)
        {
            brushPosWS.y = 0;

            /*
             *  blit steps
             *  1. blit noise to intermediate RT, this includes all the noise transformations and filters,
             *     using the appropriate noise material. do this with NoiseUtils.Blit2D?
             *  2. use that noise texture and mult it with brushmask to paint height on terrain
             */

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = this.noiseSettings;
            Material      matNoise      = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(matNoise);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = (m_toolSettings.coordSpace == CoordinateSpace.World);

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            Quaternion rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            Matrix4x4  translation  = Matrix4x4.Translate(brushPosWS);
            Matrix4x4  rotation     = Matrix4x4.Rotate(rotQ);
            Matrix4x4  scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            Matrix4x4  noiseToWorld = translation * scale;

            matNoise.SetMatrix(NoiseSettings.ShaderStrings.transform,
                               noiseSettings.trs * noiseToWorld);

            // render the noise field to a texture
            // TODO(wyatt): Handle the 3D case. Would need to blit to Volume Texture
            int rtW = ctx.destinationRenderTexture.width;
            int rtH = ctx.destinationRenderTexture.height;
            RenderTextureFormat     rtF     = RenderTextureFormat.RFloat;
            RenderTextureDescriptor rtDesc  = new RenderTextureDescriptor(rtW, rtH, rtF);
            RenderTexture           noiseRT = RenderTexture.GetTemporary(rtDesc);

            RenderTexture tempRT = RenderTexture.GetTemporary(noiseRT.descriptor);
            RenderTexture prev   = RenderTexture.active;

            RenderTexture.active = tempRT;

            int noisePass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            Graphics.Blit(tempRT, matNoise, noisePass);

            RenderTexture.active = noiseRT;

            // if(noiseSettings.filterSettings.filterStack != null)
            // {
            //     noiseSettings.filterSettings.filterStack.Eval(tempRT, noiseRT);
            // }
            // else
            {
                Graphics.Blit(tempRT, noiseRT);
            }

            RenderTexture.active = prev;

            RenderTexture.ReleaseTemporary(tempRT);

            // then add the result to the heightmap using the noise height tool shader
            Material matFinal = paintMaterial;

            TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushXform, matFinal);
            // set brush params
            Vector4 brushParams = new Vector4(0.01f * brushStrength, 0.0f, brushSize, 1 / brushSize);

            matFinal.SetVector("_BrushParams", brushParams);
            matFinal.SetTexture("_BrushTex", brushTexture);
            matFinal.SetTexture("_NoiseTex", noiseRT);
            matFinal.SetVector("_WorldHeightRemap", m_toolSettings.worldHeightRemap);
            Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, matFinal, 0);

            RenderTexture.ReleaseTemporary(noiseRT);
        }
Esempio n. 10
0
        private TerrainToolsAnalytics.IBrushParameter[] UpdateAnalyticParameters()
        {
            m_AnalyticsData.Clear();

            SerializedProperty transformSettings = noiseSettingsGUI.serializedNoise.FindProperty("transformSettings");
            SerializedProperty domainSettings    = noiseSettingsGUI.serializedNoise.FindProperty("domainSettings");
            SerializedProperty fractalTypeName   = domainSettings.FindPropertyRelative("fractalTypeName");
            SerializedProperty fractalTypeParams = domainSettings.FindPropertyRelative("fractalTypeParams");

            //Add Generic, Transform, and Domain type settings to be sent as analytic data
            m_AnalyticsData.AddRange(new TerrainToolsAnalytics.IBrushParameter[] {
                //Generic Settings
                new TerrainToolsAnalytics.BrushParameter <string> {
                    Name  = Styles.coordSpace.text,
                    Value = m_toolSettings.coordSpace.ToString()
                },

                //Transform Settings
                new TerrainToolsAnalytics.BrushParameter <Vector3> {
                    Name  = "Translation",
                    Value = transformSettings.FindPropertyRelative("translation").vector3Value
                },
                new TerrainToolsAnalytics.BrushParameter <Vector3> {
                    Name  = "Rotation",
                    Value = transformSettings.FindPropertyRelative("rotation").vector3Value
                },
                new TerrainToolsAnalytics.BrushParameter <Vector3> {
                    Name  = "Scale",
                    Value = transformSettings.FindPropertyRelative("scale").vector3Value
                },
                new TerrainToolsAnalytics.BrushParameter <bool> {
                    Name  = NoiseSettingsGUI.Styles.flipScaleX.text,
                    Value = transformSettings.FindPropertyRelative("flipScaleX").boolValue
                },
                new TerrainToolsAnalytics.BrushParameter <bool> {
                    Name  = NoiseSettingsGUI.Styles.flipScaleY.text,
                    Value = transformSettings.FindPropertyRelative("flipScaleY").boolValue
                },
                new TerrainToolsAnalytics.BrushParameter <bool> {
                    Name  = NoiseSettingsGUI.Styles.flipScaleZ.text,
                    Value = transformSettings.FindPropertyRelative("flipScaleZ").boolValue
                },

                //Domain
                new TerrainToolsAnalytics.BrushParameter <string> {
                    Name  = NoiseSettingsGUI.Styles.noiseType.text,
                    Value = domainSettings.FindPropertyRelative("noiseTypeName").stringValue
                },
                new TerrainToolsAnalytics.BrushParameter <string> {
                    Name  = NoiseSettingsGUI.Styles.fractalType.text,
                    Value = domainSettings.FindPropertyRelative("fractalTypeName").stringValue
                }
            }
                                     );

            //Add fractal specific settings to be sent as analytic data
            IFractalType fractalType = NoiseLib.GetFractalTypeInstance(fractalTypeName.stringValue);

            switch (domainSettings.FindPropertyRelative("fractalTypeName").stringValue)
            {
            case "Fbm":
                FbmFractalType.FbmFractalInput fbmFractalSettings = (FbmFractalType.FbmFractalInput)fractalType.FromSerializedString(fractalTypeParams.stringValue);
                m_AnalyticsData.AddRange(new TerrainToolsAnalytics.IBrushParameter[] {
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.octaves.text, Value = fbmFractalSettings.octaves
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.amplitude.text, Value = fbmFractalSettings.amplitude
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.persistence.text, Value = fbmFractalSettings.persistence
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.frequency.text, Value = fbmFractalSettings.frequency
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.lacunarity.text, Value = fbmFractalSettings.lacunarity
                    },
                    new TerrainToolsAnalytics.BrushParameter <bool> {
                        Name = FbmFractalType.Styles.domainWarpSettings.text, Value = fbmFractalSettings.warpEnabled
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.warpIterations.text, Value = fbmFractalSettings.warpIterations
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = FbmFractalType.Styles.warpStrength.text, Value = fbmFractalSettings.warpStrength
                    },
                    new TerrainToolsAnalytics.BrushParameter <Vector4> {
                        Name = FbmFractalType.Styles.warpOffsets.text, Value = fbmFractalSettings.warpOffsets
                    },
                });
                break;

            case "Strata":
                StrataFractalType.StrataFractalInput strataFractalSettings = (StrataFractalType.StrataFractalInput)fractalType.FromSerializedString(fractalTypeParams.stringValue);
                m_AnalyticsData.AddRange(new TerrainToolsAnalytics.IBrushParameter[] {
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.octaves.text, Value = strataFractalSettings.octaves
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.amplitude.text, Value = strataFractalSettings.amplitude
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.persistence.text, Value = strataFractalSettings.persistence
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.frequency.text, Value = strataFractalSettings.frequency
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.lacunarity.text, Value = strataFractalSettings.lacunarity
                    },
                    new TerrainToolsAnalytics.BrushParameter <bool> {
                        Name = StrataFractalType.Styles.domainWarpSettings.text, Value = strataFractalSettings.warpEnabled
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.warpIterations.text, Value = strataFractalSettings.warpIterations
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.warpStrength.text, Value = strataFractalSettings.warpStrength
                    },
                    new TerrainToolsAnalytics.BrushParameter <Vector4> {
                        Name = StrataFractalType.Styles.warpOffsets.text, Value = strataFractalSettings.warpOffsets
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.strataOffset.text, Value = strataFractalSettings.strataOffset
                    },
                    new TerrainToolsAnalytics.BrushParameter <float> {
                        Name = StrataFractalType.Styles.strataScale.text, Value = strataFractalSettings.strataScale
                    },
                });
                break;

            case "None":
            default:
                break;
            }

            return(m_AnalyticsData.ToArray());
        }
Esempio n. 11
0
        //===================================================================================================
        //
        //      APPLY BRUSH
        //
        //===================================================================================================

        private void ApplyBrushInternal(Terrain terrain, PaintContext ctx, BrushTransform brushXform, Vector3 brushPosWS,
                                        float brushRotation, float brushStrength, float brushSize, Texture brushTexture)
        {
            var prevRT = RenderTexture.active;

            brushPosWS.y = 0;

            /*
             *  blit steps
             *  1. blit noise to intermediate RT, this includes all the noise transformations and filters,
             *  using the appropriate noise material. do this with NoiseUtils.Blit2D?
             *  2. use that noise texture and mult it with brushmask to paint height on terrain
             */

            // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow
            float previewSize = 1 / 512f;

            // get proper noise material from current noise settings
            NoiseSettings noiseSettings = this.noiseSettings;
            Material      matNoise      = NoiseUtils.GetDefaultBlitMaterial(noiseSettings);

            // setup the noise material with values in noise settings
            noiseSettings.SetupMaterial(matNoise);

            // convert brushRotation to radians
            brushRotation *= Mathf.PI / 180;

            // change pos and scale so they match the noiseSettings preview
            bool isWorldSpace = (m_toolSettings.coordSpace == CoordinateSpace.World);

            brushSize  = isWorldSpace ? brushSize * previewSize : 1;
            brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero;

            // // override noise transform
            var rotQ         = Quaternion.AngleAxis(-brushRotation, Vector3.up);
            var translation  = Matrix4x4.Translate(brushPosWS);
            var rotation     = Matrix4x4.Rotate(rotQ);
            var scale        = Matrix4x4.Scale(Vector3.one * brushSize);
            var noiseToWorld = translation * scale;

            matNoise.SetMatrix(NoiseSettings.ShaderStrings.transform,
                               noiseSettings.trs * noiseToWorld);

            var noisePass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName);

            // render the noise field to a texture
            // TODO(wyatt): Handle the 3D case. Would need to blit to Volume Texture
            var rtDesc = ctx.destinationRenderTexture.descriptor;

            rtDesc.graphicsFormat = NoiseUtils.singleChannelFormat;
            rtDesc.sRGB           = false;
            var noiseRT = RTUtils.GetTempHandle(rtDesc);

            RenderTexture.active = noiseRT; // keep this
            Graphics.Blit(noiseRT, matNoise, noisePass);

            // then add the result to the heightmap using the noise height tool shader
            Material matFinal  = paintMaterial;
            var      brushMask = RTUtils.GetTempHandle(ctx.sourceRenderTexture.width, ctx.sourceRenderTexture.height, 0, FilterUtility.defaultFormat);

            Utility.SetFilterRT(commonUI, ctx.sourceRenderTexture, brushMask, matFinal);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushXform, matFinal);
            // set brush params
            Vector4 brushParams = new Vector4(0.01f * brushStrength, 0.0f, brushSize, 1 / brushSize);

            matFinal.SetVector("_BrushParams", brushParams);
            matFinal.SetTexture("_BrushTex", brushTexture);
            matFinal.SetTexture("_NoiseTex", noiseRT);
            matFinal.SetVector("_WorldHeightRemap", m_toolSettings.worldHeightRemap);
            Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, matFinal, 0);

            RTUtils.Release(noiseRT);
            RTUtils.Release(brushMask);

            RenderTexture.active = prevRT;
        }