public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { if (m_HardnessNoiseSettings == null) { m_HardnessNoiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); m_HardnessNoiseSettings.Reset(); } Erosion.HydraulicErosionSettings erosionSettings = ((Erosion.HydraulicEroder)m_Eroder).m_ErosionSettings; EditorGUI.BeginChangeCheck(); commonUI.OnInspectorGUI(terrain, editContext); m_Eroder.OnInspectorGUI(terrain, editContext); commonUI.validationMessage = ValidateAndGenerateUserMessage(terrain); if (EditorGUI.EndChangeCheck()) { Save(true); } }
/// <summary> /// Sets up this instance of NoiseSettingsGUI with the specified SerializedObject containing an object reference /// to a NoiseSettings instance. GUI will be drawn for this serialized NoiseSettings instance. /// </summary> /// <param name="serializedNoise"> A SerializedObject instance containing an object reference to a NoiseSettings object </param> public void Init(SerializedObject serializedNoise) { this.serializedNoise = serializedNoise; target = this.serializedNoise.targetObject as NoiseSettings; // transform settings transformSettings = this.serializedNoise.FindProperty("transformSettings"); translation = transformSettings.FindPropertyRelative("translation"); rotation = transformSettings.FindPropertyRelative("rotation"); scale = transformSettings.FindPropertyRelative("scale"); flipScaleX = transformSettings.FindPropertyRelative("flipScaleX"); flipScaleY = transformSettings.FindPropertyRelative("flipScaleY"); flipScaleZ = transformSettings.FindPropertyRelative("flipScaleZ"); // domain settings domainSettings = this.serializedNoise.FindProperty("domainSettings"); noiseTypeName = domainSettings.FindPropertyRelative("noiseTypeName"); noiseTypeParams = domainSettings.FindPropertyRelative("noiseTypeParams"); fractalTypeName = domainSettings.FindPropertyRelative("fractalTypeName"); fractalTypeParams = domainSettings.FindPropertyRelative("fractalTypeParams"); // filter settings // filterSettings = serializedNoise.FindProperty( "filterSettings" ); // m_filterStack = filterSettings.FindPropertyRelative( "filterStack" ).objectReferenceValue as FilterStack; // m_serializedFilterStack = new SerializedObject( m_filterStack ); // m_filterStackView = new FilterStackView( new GUIContent( "Filters" ), m_serializedFilterStack, m_serializedFilterStack.targetObject as FilterStack ); }
private static void INTERNAL_Blit2D(NoiseSettings noise, RenderTexture dest, Material mat, int pass) { noise.SetupMaterial(mat); RenderTexture tempRT = RenderTexture.GetTemporary(dest.descriptor); RenderTexture prev = RenderTexture.active; RenderTexture.active = tempRT; Graphics.Blit(tempRT, mat, pass); RenderTexture.active = dest; // if(noise.filterSettings.filterStack != null) // { // noise.filterSettings.filterStack.Eval(tempRT, dest); // } // else { Graphics.Blit(tempRT, dest); } RenderTexture.active = prev; RenderTexture.ReleaseTemporary(tempRT); }
private void UpdateTexture() { // create preview RT here and keep until the next Repaint if (m_previewRT != null) { RenderTexture.ReleaseTemporary(m_previewRT); } NoiseSettings noiseSettings = m_serializedNoise.targetObject as NoiseSettings; m_previewRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.ARGB32); RenderTexture tempRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.RFloat); RenderTexture prevActive = RenderTexture.active; NoiseUtils.Blit2D(noiseSettings, tempRT); NoiseUtils.BlitPreview2D(tempRT, m_previewRT); RenderTexture.active = prevActive; RenderTexture.ReleaseTemporary(tempRT); m_image.image = m_previewRT; }
/// <summary> /// Copies the runtime information from a provided NoiseSettings instance. /// </summary> /// <param name="noiseSettings"> The NoiseSettings instance to copy from </param> public void Copy(NoiseSettings noiseSettings) { transformSettings = noiseSettings.transformSettings; domainSettings = noiseSettings.domainSettings; // // TODO(wyatt): copy Filter Stack // Debug.LogError("TODO(wyatt): copy filter stack"); }
/// <summary> /// Bakes 3D noise defined by the given NoiseSettings instance into a Texture3D instance and returns /// a reference to it. /// </summary> /// <param name = "noise"> An instance of NoiseSettings defining the type of noise to bake </param> /// <param name = "width"> The width of the baked Texture3D </param> /// <param name = "height"> The height of the baked Texture3D </param> /// <param name = "depth"> The depth of the baked Texture3D </param> /// <param name = "format"> The GraphicsFormat for the baked Texture3D. In most cases, you will want to use GraphicsFormat.R16_UNorm </param> /// <param name = "flags"> TextureCreation flags for the baked Texture3D. </param> /// <returns> A reference to the baked Texture3D instance </returns> /// <remarks> /// Be careful when specifying TextureCreation flags. If you specify that mipmaps should be generated for /// a Texture3D, that will use a lot more memory than if you were generating mipmaps for a Texture2D. /// </remarks> public static Texture3D BakeToTexture3D(NoiseSettings noise, int width, int height, int depth, GraphicsFormat format = GraphicsFormat.R16_UNorm, TextureCreationFlags flags = TextureCreationFlags.None) { Material mat = GetDefaultBlitMaterial(noise); if (mat == null) { return(null); } RenderTexture sliceRT = RenderTexture.GetTemporary(width, height, 0, GraphicsFormat.R16_UNorm); Texture2D slice2D = new Texture2D(width, height, format, flags); Color[] colors = new Color[width * height * depth]; noise.SetupMaterial(mat); int pass = NoiseLib.GetNoiseIndex(noise); RenderTexture.active = sliceRT; List <Color[]> sliceColors = new List <Color[]>(depth); for (int i = 0; i < depth; ++i) { float uvy = ((float)i + 0.5f) / depth; mat.SetFloat("_UVY", uvy); Graphics.Blit(null, sliceRT, mat, pass * kNumBlitPasses + 1); slice2D.ReadPixels(new Rect(0, 0, width, height), 0, 0); sliceColors.Add(slice2D.GetPixels(0, 0, width, height)); } int pixPerSlice = width * height; for (int sliceID = 0; sliceID < sliceColors.Count; ++sliceID) { for (int pixelID = 0; pixelID < sliceColors[sliceID].Length; ++pixelID) { int pixel = (pixPerSlice * sliceID) + pixelID; colors[pixel] = sliceColors[sliceID][pixelID]; } } bool mipChain = ((int)flags & (int)TextureCreationFlags.MipChain) != 0; Texture3D texture = new Texture3D(width, height, depth, format, flags); texture.SetPixels(colors); texture.Apply(mipChain); RenderTexture.active = null; RenderTexture.ReleaseTemporary(sliceRT); return(texture); }
public static void ShowWindow(NoiseSettings noise) { var wnd = GetWindow <ExportNoiseWindow>(Styles.title.text, true); wnd.Init(noise); wnd.minSize = new Vector2(400f, 160f); wnd.maxSize = new Vector2(400f, 160f); wnd.Show(); }
/*========================================================================= * * Blit raw noise data into texture * * =========================================================================*/ /// <summary> /// Blits 2D noise defined by the given NoiseSettings instance into the destination RenderTexture. /// </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> public static void Blit2D(NoiseSettings noise, RenderTexture dest) { Material mat = GetDefaultBlitMaterial(noise); if (mat == null) { return; } Blit2D(noise, dest, mat); }
/// <summary> /// Returns a Material reference to the default blit material for the given NoiseSettings object. /// </summary> /// <remarks> /// Internally, this uses noise.domainSettings.fractalTypeName to get it's FractalType /// </remarks> /// <returns> A reference to the default blit Material for the specified NoiseSettings instance </returns> public static Material GetDefaultBlitMaterial(NoiseSettings noise) { IFractalType fractal = NoiseLib.GetFractalTypeInstance(noise.domainSettings.fractalTypeName); if (fractal == null) { return(null); } return(GetDefaultBlitMaterial(fractal.GetType())); }
public static void ShowWindow(NoiseSettings noise) { var wnd = ScriptableObject.CreateInstance <ExportNoiseWindow>(); wnd.titleContent = Styles.title; wnd.Init(noise); wnd.minSize = new Vector2(400f, 160f); wnd.maxSize = new Vector2(400f, 160f); wnd.Show(); }
/// <summary> /// Creates a new NoiseSettings Asset at the specified Asset path /// </summary> /// <param name="assetPath"> The path in the AssetDatabase where the new NoiseSettings Asset should be saved </param> /// <returns> A reference to the newly created NoiseSettings Asset </returns> public static NoiseSettings CreateAsset(string assetPath) { NoiseSettings noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); assetPath = AssetDatabase.GenerateUniqueAssetPath(assetPath); AssetDatabase.CreateAsset(noiseSettings, assetPath); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(noiseSettings); return(noiseSettings); }
private void INTERNAL_OnSourceProfileChanged(NoiseSettings sourceProfile) { if (sourceProfile == null) { revertButton.text = Styles.reset; revertButton.tooltip = Styles.resetTooltip; filePanelContainer.Clear(); filePanelContainer.Add(revertButton); filePanelContainer.Add(saveAsButton); revertButton.RemoveFromClassList(Styles.flexThird); saveAsButton.RemoveFromClassList(Styles.flexThird); revertButton.AddToClassList(Styles.flexHalf); saveAsButton.AddToClassList(Styles.flexHalf); } else { revertButton.text = Styles.revert; revertButton.tooltip = Styles.revertTooltip; filePanelContainer.Clear(); filePanelContainer.Add(revertButton); filePanelContainer.Add(applyButton); filePanelContainer.Add(saveAsButton); revertButton.RemoveFromClassList(Styles.flexHalf); saveAsButton.RemoveFromClassList(Styles.flexHalf); revertButton.AddToClassList(Styles.flexThird); saveAsButton.AddToClassList(Styles.flexThird); } // Undo.RegisterCompleteObjectUndo( this, "NoiseSettings object changed" ); if (sourceProfile != null && m_noiseSourceAsset != sourceProfile) { m_noiseUpdateTarget.Copy(sourceProfile); } else { // should revert to the NULL asset settings } objectField.value = sourceProfile; INTERNAL_OnSettingsChanged(); onSourceAssetChanged?.Invoke(sourceProfile); m_noiseSourceAsset = sourceProfile; }
/// <summary> /// Copies the serialized information from a provided NoiseSettings instance /// </summary> /// <param name="noiseSettings"> The NoiseSettings instance to copy from </param> public void CopySerialized(NoiseSettings noiseSettings) { SerializedObject copy = new SerializedObject(noiseSettings); SerializedObject _this = new SerializedObject(this); copy.Update(); _this.Update(); _this.CopyFromSerializedProperty(copy.FindProperty("transformSettings")); _this.CopyFromSerializedProperty(copy.FindProperty("domainSettings")); // _this.CopyFromSerializedProperty(copy.FindProperty("m_filterSettings")); _this.ApplyModifiedProperties(); }
private static void INTERNAL_Blit2D(NoiseSettings noise, RenderTexture dest, Material mat, int pass) { noise.SetupMaterial(mat); var tempRT = RenderTexture.GetTemporary(dest.descriptor); var prev = RenderTexture.active; RenderTexture.active = tempRT; // keep this Graphics.Blit(tempRT, mat, pass); Graphics.Blit(tempRT, dest); RenderTexture.active = prev; RenderTexture.ReleaseTemporary(tempRT); }
public void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { if (m_noiseSettings == null) { m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); m_noiseSettings.Reset(); } if (m_noiseSettingsGUI == null) { m_noiseSettingsGUI = new NoiseSettingsGUI(); m_noiseSettingsGUI.Init(m_noiseSettings); } m_noiseSettingsGUI.OnGUI(NoiseSettingsGUIFlags.Settings); }
private void LoadSettings() { NoiseToolSettings defaultSettings = new NoiseToolSettings(); defaultSettings.Reset(); string settingsStr = EditorPrefs.GetString(kToolSettingsName, JsonUtility.ToJson(defaultSettings)); m_toolSettings = JsonUtility.FromJson <NoiseToolSettings>(settingsStr); string assetPath = AssetDatabase.GUIDToAssetPath(m_toolSettings.noiseAssetGUID); if (!string.IsNullOrEmpty(assetPath)) { m_activeNoiseSettingsProfile = AssetDatabase.LoadAssetAtPath <NoiseSettings>(assetPath); } }
/// <summary> /// Creates a new NoiseSettings Asset at the specified Asset path /// </summary> /// <param name="assetPath"> The path in the AssetDatabase where the new NoiseSettings Asset should be saved </param> /// <returns> A reference to the newly created NoiseSettings Asset </returns> public static NoiseSettings CreateAsset(string assetPath) { NoiseSettings noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); // FilterStack filterStack = ScriptableObject.CreateInstance<FilterStack>(); // filterStack.hideFlags = HideFlags.HideInInspector | HideFlags.HideInHierarchy | HideFlags.NotEditable; // noiseSettings.filterSettings.filterStack = filterStack; AssetDatabase.CreateAsset(noiseSettings, assetPath); // AssetDatabase.AddObjectToAsset(filterStack, noiseSettings); // AssetDatabase.ImportAsset( AssetDatabase.GetAssetPath( filterStack ) ); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(noiseSettings); return(noiseSettings); }
/// <summary> /// Bakes 2D noise defined by the given NoiseSettings instance into a Texture2D instance and returns /// a reference to it. /// </summary> /// <param name = "noise"> An instance of NoiseSettings defining the type of noise to bake </param> /// <param name = "width"> The width of the baked Texture2D </param> /// <param name = "height"> The height of the baked Texture2D </param> /// <param name = "format"> The GraphicsFormat for the baked Texture2D. In most cases, you will want to use GraphicsFormat.R16_UNorm </param> /// <param name = "flags"> TextureCreation flags for the baked Texture2D </param> /// <returns> A reference to the baked Texture2D instance </returns> public static Texture2D BakeToTexture2D(NoiseSettings noise, int width, int height, GraphicsFormat format = GraphicsFormat.R16_UNorm, TextureCreationFlags flags = TextureCreationFlags.None) { RenderTexture rt = RenderTexture.GetTemporary(width, height, 0, GraphicsFormat.R16_UNorm); Texture2D texture = new Texture2D(width, height, format, flags); Blit2D(noise, rt); RenderTexture.active = rt; bool mipChain = ((int)flags & (int)TextureCreationFlags.MipChain) != 0; texture.ReadPixels(new Rect(0, 0, width, height), 0, 0, mipChain); RenderTexture.active = null; RenderTexture.ReleaseTemporary(rt); return(texture); }
/// <summary> /// Create a NoiseWindow that applies changes to a provided NoiseAsset and loads from a provided source Asset /// </summary> public static NoiseWindow Create(NoiseSettings noise, NoiseSettings sourceAsset = null) { NoiseWindow wnd = null; // check to see if a window with the same context exists already foreach (var w in s_openNoiseWindows) { if (w.noiseEditorView != null && w.noiseEditorView.noiseUpdateTarget == noise) { wnd = w; break; } } if (null == wnd) { wnd = ScriptableObject.CreateInstance <NoiseWindow>(); wnd.titleContent = EditorGUIUtility.TrTextContent("Noise Editor"); var view = new NoiseEditorView(noise, sourceAsset); wnd.rootVisualElement.Clear(); wnd.rootVisualElement.Add(view); wnd.noiseEditorView = view; wnd.m_noiseAsset = noise; wnd.minSize = new Vector2(550, 300); wnd.rootVisualElement.Bind(new SerializedObject(wnd.m_noiseAsset)); wnd.rootVisualElement.viewDataKey = "NoiseWindow"; } wnd.Show(); wnd.Focus(); return(wnd); }
/// <summary> /// Blits 3D noise defined by the given NoiseSettings instance into the destination RenderTexture. /// </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> public static void Blit3D(NoiseSettings noise, RenderTexture dest) { throw new NotImplementedException("NoiseUtils::Blit3D: Function not implemented yet"); // Debug.Assert(dest.dimension == UnityEngine.Rendering.TextureDimension.Tex3D, // "NoiseUtils::Blit3D: Provided RenderTexture is not a 3D texture. You have to manually create it as a volume"); // Material mat = GetDefaultBlitMaterial(noise); // if(mat == null) // { // return; // } // int pass = NoiseLib.GetNoiseIndex(noise.domainSettings.noiseTypeName); // RenderTexture prev = RenderTexture.active; // Graphics.SetRenderTarget(dest, 0, CubemapFace.Unknown, kAllSlices); // // Graphics.Blit( dest, mat, ) // RenderTexture.active = prev; }
/// <summary> /// Initializes the ExportNoiseWindow instance with the given NoiseSettings instance. /// </summary> /// <param name = "noise"> The NoiseSettings instance to be used with this ExportNoiseWindow instance </param> public void Init(NoiseSettings noise) { m_noise = noise; }
/// <summary> /// Initializes the ExportNoiseWindow instance with the given NoiseSettings instance. /// </summary> /// <param name = "noise"> The NoiseSettings instance to be used with this ExportNoiseWindow instance </param> public ExportNoiseGUI(NoiseSettings noise) { m_noise = noise; }
public static NoiseWindow Create() { NoiseSettings noise = ScriptableObject.CreateInstance <NoiseSettings>(); return(Create(noise)); }
/// <summary> /// Sets up this instance of NoiseSettingsGUI with the specified NoiseSettings object. /// GUI will be drawn for this NoiseSettings instance. /// </summary> /// <param name="noiseSettings"> The NoiseSettings instance for which GUI will be drawn </param> public void Init(NoiseSettings noiseSettings) { Init(new SerializedObject(noiseSettings)); }
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); }
public override void DoGUI(Rect rect) { if (m_noiseSettings == null) { m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); } GUIContent localLabel = NoiseFilter.localLabel; GUIContent worldLabel = NoiseFilter.worldLabel; GUIContent heightmapLabel = NoiseFilter.heightmapLabel; GUIContent editLabel = NoiseFilter.editLabel; float editWith = GUI.skin.label.CalcSize(editLabel).x + 20f; Rect editRect = new Rect(rect.xMax - editWith, rect.y, editWith, rect.height); Rect labelRect = rect; labelRect.width = GUI.skin.label.CalcSize(coordinateLabel).x; Rect worldRect = labelRect; worldRect.x = labelRect.xMax; worldRect.width = GUI.skin.button.CalcSize(worldLabel).x + 10f; Rect localRect = worldRect; localRect.x = worldRect.xMax; localRect.width = GUI.skin.button.CalcSize(localLabel).x + 10f; Rect heightmapRect = localRect; heightmapRect.x = localRect.xMax + 10f; heightmapRect.width = GUI.skin.button.CalcSize(heightmapLabel).x + 10f; if (editRect.xMin < heightmapRect.xMax + 10f) { worldRect.x -= labelRect.width; localRect.x -= labelRect.width; heightmapRect.x -= labelRect.width; labelRect.width = 0; } editRect.x = Mathf.Max(editRect.x, heightmapRect.xMax + 4f); if (editRect.xMax > rect.xMax) { worldLabel = NoiseFilter.worldShortLabel; localLabel = NoiseFilter.localShortLabel; heightmapLabel = NoiseFilter.heightmapShortLabel; worldRect.width = GUI.skin.label.CalcSize(worldLabel).x + 10f; localRect.width = GUI.skin.label.CalcSize(localLabel).x + 10f; heightmapRect.width = GUI.skin.label.CalcSize(heightmapLabel).x + 10f; localRect.x = worldRect.xMax; heightmapRect.x = localRect.xMax + 10f; editRect.x = rect.xMax - editWith; } editRect.x = Mathf.Max(heightmapRect.xMax + 4f, editRect.x); if (editRect.xMax > rect.xMax) { editLabel = editShortLabel; editRect.width = GUI.skin.label.CalcSize(editLabel).x + 10f; } GUI.Label(labelRect, coordinateLabel); if (TerrainToolGUIHelper.ToggleButton(worldRect, worldLabel, !m_isLocalSpace)) { m_isLocalSpace = false; } if (TerrainToolGUIHelper.ToggleButton(localRect, localLabel, m_isLocalSpace)) { m_isLocalSpace = true; } m_useHeightmap = TerrainToolGUIHelper.ToggleButton(heightmapRect, heightmapLabel, m_useHeightmap); m_noiseSettings.useTextureForPositions = m_useHeightmap; if (GUI.Button(editRect, editLabel)) { NoiseWindow wnd = NoiseWindow.Create(m_noiseSettings, m_noiseSource); wnd.noiseEditorView.onSettingsChanged += (noise) => { m_noiseSettings.Copy(noise); }; wnd.noiseEditorView.onSourceAssetChanged += (noise) => { m_noiseSource = noise; }; wnd.onDisableCallback += () => { m_window = null; }; m_window = wnd; } }
private void DoNoiseSettingsObjectField() { bool profileInUse = m_activeNoiseSettingsProfile != null; float buttonWidth = 60; float indentOffset = EditorGUI.indentLevel * 15f; Rect lineRect = GUILayoutUtility.GetRect(1, EditorGUIUtility.singleLineHeight); Rect labelRect = new Rect(lineRect.x, lineRect.y, EditorGUIUtility.labelWidth - indentOffset, lineRect.height); Rect fieldRect = new Rect(labelRect.xMax, lineRect.y, lineRect.width - labelRect.width - buttonWidth * (profileInUse ? 3 : 2), lineRect.height); Rect resetButtonRect = new Rect(fieldRect.xMax, lineRect.y, buttonWidth, lineRect.height); Rect saveButtonRect = new Rect(resetButtonRect.xMax, lineRect.y, buttonWidth, lineRect.height); Rect saveAsButtonRect = new Rect(profileInUse ? saveButtonRect.xMax : resetButtonRect.xMax, lineRect.y, buttonWidth, lineRect.height); EditorGUI.PrefixLabel(labelRect, Styles.noiseSettingsProfile); NoiseSettings settingsProfile = m_activeNoiseSettingsProfile; settingsProfile = (NoiseSettings)EditorGUI.ObjectField(fieldRect, settingsProfile, typeof(NoiseSettings), false); if (m_activeNoiseSettingsProfile != null) { if (GUI.Button(resetButtonRect, Styles.revert)) { Undo.RecordObject(noiseSettings, "Noise Settings - Revert"); noiseSettings.Copy(m_activeNoiseSettingsProfile); } } else { if (GUI.Button(resetButtonRect, Styles.reset)) { Undo.RecordObject(noiseSettings, "Noise Settings - Reset"); noiseSettings.Reset(); } } if (profileInUse && GUI.Button(saveButtonRect, Styles.apply)) { m_activeNoiseSettingsProfile.CopySerialized(noiseSettings); } if (GUI.Button(saveAsButtonRect, Styles.saveAs)) { string path = EditorUtility.SaveFilePanel("Save Noise Settings", Application.dataPath, "New Noise Settings.asset", "asset"); // saving to project's asset folder if (path.StartsWith(Application.dataPath)) { // TODO(wyatt): need to check if this works with different locales/languages. folder might not be // called "Assets" in non-English Editor builds string assetPath = path.Substring(Application.dataPath.Length - 6); // settingsProfile = NoiseSettings.CreateAsset(assetPath, noiseSettings); settingsProfile = NoiseSettingsFactory.CreateAsset(assetPath); settingsProfile.CopySerialized(noiseSettings); } // saving asset somewhere else. why? dunno! else if (!string.IsNullOrEmpty(path)) { Debug.LogError("Invalid path specified for creation of new Noise Settings asset. Must be a valid path within the current Unity project's Assets folder/data path."); } } // check if the profile in the object field changed bool changed = settingsProfile != m_activeNoiseSettingsProfile; if (changed) { if (settingsProfile == null) { noiseSettings.Copy(noiseSettingsIfNull); } else { if (m_activeNoiseSettingsProfile == null) { noiseSettingsIfNull.Copy(noiseSettings); } noiseSettings.Copy(settingsProfile); } noiseSettingsGUI.Init(noiseSettings); m_activeNoiseSettingsProfile = settingsProfile; } GUILayout.Space(12); }
//=================================================================================================== // // 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); }
/// <summary> /// Renders an interactive Noise Preview along with tooltip icons and an optional Export button that opens a new ExportNoiseWindow. /// A background image is also rendered behind the preview that takes up the entire width of the EditorWindow currently being drawn. /// </summary> /// <param name = "minSize"> Minimum size for the Preview </param> /// <param name = "showExportButton"> Whether or not to render the Export button </param> public void DrawPreviewTexture(float minSize, bool showExportButton = true) { // Draw label with tooltip GUILayout.Label(Styles.noisePreview); float padding = 4f; float iconWidth = 40f; int size = (int)Mathf.Min(minSize, EditorGUIUtility.currentViewWidth); Rect totalRect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, size + padding * 2); // extra pixels for highlight border Color prev = GUI.color; GUI.color = new Color(.1f, .1f, .1f, 1f); GUI.DrawTexture(totalRect, Texture2D.whiteTexture, ScaleMode.StretchToFill, false); GUI.color = Color.white; // draw info icon // if(totalRect.Contains(Event.current.mousePosition)) { Rect infoIconRect = new Rect(totalRect.x + padding, totalRect.y + padding, iconWidth, iconWidth); GUI.Label(infoIconRect, Styles.infoIcon); // GUI.Label( infoIconRect, Styles.noiseTooltip ); } // draw export button float buttonWidth = GUI.skin.button.CalcSize(Styles.export).x; float buttonHeight = EditorGUIUtility.singleLineHeight; Rect exportRect = new Rect(totalRect.xMax - buttonWidth - padding, totalRect.yMax - buttonHeight - padding, buttonWidth, buttonHeight); if (GUI.Button(exportRect, Styles.export)) { serializedNoise.ApplyModifiedProperties(); serializedNoise.Update(); ExportNoiseWindow.ShowWindow(serializedNoise.targetObject as NoiseSettings); } float safeSpace = Mathf.Max(iconWidth * 2, buttonWidth * 2) + padding * 4; float minWidth = Mathf.Min(size, totalRect.width - safeSpace); Rect previewRect = new Rect(totalRect.x + totalRect.width / 2 - minWidth / 2, totalRect.y + totalRect.height / 2 - minWidth / 2, minWidth, minWidth); EditorGUIUtility.AddCursorRect(previewRect, MouseCursor.Pan); if (previewRect.Contains(Event.current.mousePosition)) { serializedNoise.Update(); HandlePreviewTextureInput(previewRect); serializedNoise.ApplyModifiedProperties(); } if (Event.current.type == EventType.Repaint) { // create preview RT here and keep until the next Repaint if (m_previewRT != null) { RenderTexture.ReleaseTemporary(m_previewRT); } NoiseSettings noiseSettings = serializedNoise.targetObject as NoiseSettings; m_previewRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.ARGB32); RenderTexture tempRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.RFloat); RenderTexture prevActive = RenderTexture.active; NoiseUtils.Blit2D(noiseSettings, tempRT); NoiseUtils.BlitPreview2D(tempRT, m_previewRT); RenderTexture.active = prevActive; GUI.DrawTexture(previewRect, m_previewRT, ScaleMode.ScaleToFit, false); RenderTexture.ReleaseTemporary(tempRT); } GUI.color = prev; }
/// <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); }