/// <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);
        }
        protected override void OnEval(FilterContext fc, RenderTexture sourceRenderTexture, RenderTexture destinationRenderTexture)
        {
            if (m_noiseSettings == null)
            {
                m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>();
            }

            m_noiseSettings.useTextureForPositions = m_useHeightmap;

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

            Vector3 brushPosWS = fc.brushPos - m_lastBrushPosition;

            brushPosWS.y        = 0;
            m_lastBrushPosition = fc.brushPos;
            float brushSize     = fc.brushSize;
            float brushRotation = fc.brushRotation - m_lastRotation;

            m_lastRotation = 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);

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

            // compensate for the difference between the size of the rotated brush and the square noise RT
            var brushTransform  = GetBrushTransform(fc);
            var scaleMultiplier = new Vector2(
                1.0f / (fc.brushSize / brushTransform.GetBrushXYBounds().width),
                1.0f / (fc.brushSize / brushTransform.GetBrushXYBounds().height));

            Quaternion rotQ = Quaternion.AngleAxis(-brushRotation, Vector3.up);

            // accumulate transformation delta
            m_noiseToWorld *= Matrix4x4.TRS(brushPosWS, rotQ, Vector3.one);

            mat.SetMatrix(NoiseSettings.ShaderStrings.transform, noiseSettings.trs * m_noiseToWorld * Matrix4x4.Scale(new Vector3(scaleMultiplier.x, 1.0f, scaleMultiplier.y) * brushSize));

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

            var desc = destinationRenderTexture.descriptor;

            desc.graphicsFormat = NoiseUtils.singleChannelFormat;
            desc.sRGB           = false;
            RTHandle rt = RTUtils.GetTempHandle(desc);

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

            Material blendMat = FilterUtility.blendModesMaterial;

            blendMat.SetTexture("_BlendTex", rt);
            Graphics.Blit(sourceRenderTexture, destinationRenderTexture, blendMat, 1);
            RTUtils.Release(rt);
        }
 /// <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();
 }
Пример #4
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));
 }
Пример #5
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);
        }
Пример #6
0
        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);
            }
        }
        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());
        }
        private void ApplyBrushInternal(Terrain terrain, PaintContext ctx, BrushTransform brushXform, Vector3 brushPosWS,
                                        float brushRotation, float brushStrength, float brushSize, Texture brushTexture)
        {
            var prevRT = RenderTexture.active;

            var brushPositionOffset = brushPosWS - m_lastBrushPosition;

            m_lastBrushPosition   = brushPosWS;
            brushPositionOffset.y = 0;

            var rotationDelta = brushRotation - m_lastRotation;

            m_lastRotation = brushRotation;

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

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

            brushSize           = isWorldSpace ? brushSize * previewSize : 1;
            brushPositionOffset = isWorldSpace ? brushPositionOffset * previewSize : Vector3.zero;
            var brushTransform  = NoiseFilter.GetBrushTransform(rotationDelta, brushSize);
            var scaleMultiplier = new Vector2(
                1.0f / (brushSize / brushTransform.GetBrushXYBounds().width),
                1.0f / (brushSize / brushTransform.GetBrushXYBounds().height));

            // // override noise transform
            Quaternion rotQ = Quaternion.AngleAxis(-rotationDelta, Vector3.up);

            // accumulate transformation delta
            m_noiseToWorld *= Matrix4x4.TRS(brushPositionOffset, rotQ, Vector3.one);

            matNoise.SetMatrix(NoiseSettings.ShaderStrings.transform, noiseSettings.trs * m_noiseToWorld * Matrix4x4.Scale(new Vector3(scaleMultiplier.x, 1.0f, scaleMultiplier.y) * brushSize));

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