From 190355781375e791c4f3b00fb2464c29086fdad6 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Thu, 25 Feb 2021 20:18:44 -0800 Subject: [PATCH 1/3] Add material upgrader --- .../Crest/Scripts/Editor/MaterialHelper.cs | 113 ++++++++++++++++++ .../Scripts/Editor/MaterialHelper.cs.meta | 11 ++ .../Crest/Scripts/Editor/MaterialUpgrader.cs | 71 +++++++++++ .../Scripts/Editor/MaterialUpgrader.cs.meta | 11 ++ .../Crest/Scripts/Editor/OceanShaderGUI.cs | 18 +++ .../Scripts/Editor/OceanShaderGUI.cs.meta | 11 ++ 6 files changed, 235 insertions(+) create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs.meta create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs.meta create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs create mode 100644 crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs.meta diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs new file mode 100644 index 000000000..5e4ee92c6 --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs @@ -0,0 +1,113 @@ +// Crest Ocean System + +// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) + +namespace Crest.Editor +{ + using System.Collections.Generic; + using UnityEditor; + using UnityEngine; + using System.Linq; + + public static class MaterialHelper + { + internal static readonly Dictionary RenamedKeywords = new Dictionary + { + }; + + internal static void MigrateKeywords(Material material, SerializedObject serializedObject, SerializedProperty floatProperties, SerializedProperty keywordProperties) + { + foreach (var entry in RenamedKeywords) + { + RenameKeyword(entry.Key, entry.Value, floatProperties, keywordProperties); + } + + // Order is important. This is what it takes to save our changes to the material. + serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(material); + } + + internal static void MigrateKeywordsGUI(Material material, SerializedObject serializedObject) + { + var floatProperties = serializedObject.FindProperty("m_SavedProperties.m_Floats"); + var keywordProperties = serializedObject.FindProperty("m_ShaderKeywords"); + + if (ContainsRenamedKeyword(floatProperties) && GUILayout.Button("Migrate")) + { + foreach (var entry in RenamedKeywords) + { + RenameKeyword(entry.Key, entry.Value, floatProperties, keywordProperties); + } + + // Order is important. This is what it takes to save our changes to the material. + serializedObject.ApplyModifiedProperties(); + EditorUtility.SetDirty(material); + AssetDatabase.SaveAssets(); + GUIUtility.ExitGUI(); + } + } + + internal static bool ContainsRenamedKeyword(SerializedProperty floatProperties) + { + if (floatProperties != null && floatProperties.isArray) + { + for (int index = 0; index < floatProperties.arraySize; index++) + { + if (RenamedKeywords.ContainsKey(floatProperties.GetArrayElementAtIndex(index).displayName)) + { + return true; + } + } + } + + return false; + } + + internal static void RenameKeyword(string oldName, string newName, SerializedProperty floatProperties, SerializedProperty keywordProperties) + { + if (floatProperties != null && floatProperties.isArray) + { + for (int i = 0; i < floatProperties.arraySize; i++) + { + var oldProperty = floatProperties.GetArrayElementAtIndex(i); + if (oldProperty.displayName == oldName) + { + for (int ii = 0; ii < floatProperties.arraySize; ii++) + { + SerializedProperty newProperty = floatProperties.GetArrayElementAtIndex(ii); + // Even if the property does not exist in the file, it will exist if it is defined in the shader. + if (newProperty.displayName == newName) + { + // A property is a pair so we need to navigate down a level. + oldProperty.Next(true); + // Skip the first value which is the name. + oldProperty.Next(false); + + // A property is a pair so we need to navigate down a level. + newProperty.Next(true); + // Skip the first value which is the name. + newProperty.Next(false); + + // Copy the value over. + newProperty.floatValue = oldProperty.floatValue; + + var keywords = keywordProperties.stringValue.Split(' ').ToList(); + keywords.Remove($"{oldName.ToUpper()}_ON"); + if (newProperty.floatValue == 1) + { + keywords.Add($"{newName.ToUpper()}_ON"); + } + keywordProperties.stringValue = string.Join(" ", keywords); + } + } + + // Delete the old property. + floatProperties.DeleteArrayElementAtIndex(i); + return; + } + } + } + } + } +} + diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs.meta b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs.meta new file mode 100644 index 000000000..89019b7d5 --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1499b0786694944098c3cc42fd550477 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs new file mode 100644 index 000000000..22e5decf1 --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs @@ -0,0 +1,71 @@ +// Crest Ocean System + +// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) + +namespace Crest.Editor +{ + using UnityEditor; + using UnityEngine; + + public class MaterialUpgrader + { + static bool DisplayMaterialUpgradeDialogue() => EditorUtility.DisplayDialog + ( + "Upgrade Crest Materials?", + "Some property names have changed since the last version of Crest. They will need upgrading.", + "Upgrade Crest Materials", + "Leave Crest Materials Alone" + ); + + [InitializeOnLoadMethod] + static void UpgradeMaterials() + { + if (MaterialHelper.RenamedKeywords.Count == 0) + { + return; + } + + var wasUpgradeChosen = false; + + AssetDatabase.StartAssetEditing(); + try + { + // TODO: Might have to restrict to assets found in user editable locations (like Assets). + // Process all materials. + foreach (var guid in AssetDatabase.FindAssets("t:Material")) + { + var material = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); + if (material.shader.name == "Crest/Ocean") + { + var serializedObject = new SerializedObject(material); + var floatProperties = serializedObject.FindProperty("m_SavedProperties.m_Floats"); + var keywordProperties = serializedObject.FindProperty("m_ShaderKeywords"); + + if (MaterialHelper.ContainsRenamedKeyword(floatProperties)) + { + if (wasUpgradeChosen || DisplayMaterialUpgradeDialogue()) + { + wasUpgradeChosen = true; + MaterialHelper.MigrateKeywords(material, serializedObject, floatProperties, keywordProperties); + } + else + { + return; + } + } + } + } + + if (wasUpgradeChosen) + { + AssetDatabase.SaveAssets(); + } + } + finally + { + AssetDatabase.StopAssetEditing(); + } + } + } +} + diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs.meta b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs.meta new file mode 100644 index 000000000..750cd3863 --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: cb3fd389793a242a689bac93881dd6c8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs b/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs new file mode 100644 index 000000000..886a7c39f --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs @@ -0,0 +1,18 @@ +// Crest Ocean System + +// This file is subject to the MIT License as seen in the root of this folder structure (LICENSE) + +namespace Crest.Editor +{ + using UnityEngine; + using UnityEditor; + + public class OceanShaderGUI : ShaderGUI + { + public override void OnGUI(MaterialEditor editor, MaterialProperty[] properties) + { + base.OnGUI(editor, properties); + MaterialHelper.MigrateKeywordsGUI((Material)editor.target, editor.serializedObject); + } + } +} diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs.meta b/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs.meta new file mode 100644 index 000000000..e02594d92 --- /dev/null +++ b/crest/Assets/Crest/Crest/Scripts/Editor/OceanShaderGUI.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b285be1197f864fc99bea6ec87fc2ee6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 612fb95d475e9a2431f43f97d5f804360b645ec1 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Thu, 25 Feb 2021 20:30:13 -0800 Subject: [PATCH 2/3] Add CREST_ prefixes to some keywords --- .../Crest/Scripts/Editor/MaterialHelper.cs | 4 ++ .../Crest/Scripts/Helpers/UnderwaterEffect.cs | 4 +- .../Crest/Scripts/LodData/LodDataMgrFlow.cs | 2 +- .../Crest/Scripts/LodData/LodDataMgrFoam.cs | 3 +- .../LodData/Shadows/LodDataMgrShadow.cs | 2 +- crest/Assets/Crest/Crest/Shaders/Ocean.shader | 45 ++++++++++--------- .../Crest/Crest/Shaders/OceanEmission.hlsl | 16 +++---- .../Assets/Crest/Crest/Shaders/OceanFoam.hlsl | 4 +- .../Crest/Crest/Shaders/OceanShaderData.hlsl | 12 ++--- .../Underwater/UnderwaterCurtain.shader | 8 ++-- 10 files changed, 52 insertions(+), 48 deletions(-) diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs index 5e4ee92c6..741016210 100644 --- a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs @@ -13,6 +13,10 @@ public static class MaterialHelper { internal static readonly Dictionary RenamedKeywords = new Dictionary { + { "_Foam", "CREST_FOAM" }, + { "_Shadows", "CREST_SHADOWS" }, + { "_Caustics", "CREST_CAUSTICS" }, + { "_Flow", "CREST_FLOW" }, }; internal static void MigrateKeywords(Material material, SerializedObject serializedObject, SerializedProperty floatProperties, SerializedProperty keywordProperties) diff --git a/crest/Assets/Crest/Crest/Scripts/Helpers/UnderwaterEffect.cs b/crest/Assets/Crest/Crest/Scripts/Helpers/UnderwaterEffect.cs index c49115a3a..019ed5cf4 100644 --- a/crest/Assets/Crest/Crest/Scripts/Helpers/UnderwaterEffect.cs +++ b/crest/Assets/Crest/Crest/Scripts/Helpers/UnderwaterEffect.cs @@ -236,8 +236,8 @@ public partial class UnderwaterEffect : IValidated "_SUBSURFACESCATTERING_ON", "_SUBSURFACESHALLOWCOLOUR_ON", "_TRANSPARENCY_ON", - "_CAUSTICS_ON", - "_SHADOWS_ON", + "CREST_CAUSTICS_ON", + "CREST_SHADOWS_ON", }; public bool Validate(OceanRenderer ocean, ValidatedHelper.ShowMessage showMessage) diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFlow.cs b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFlow.cs index 27528455e..d6f741739 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFlow.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFlow.cs @@ -19,7 +19,7 @@ public class LodDataMgrFlow : LodDataMgr protected override GraphicsFormat RequestedTextureFormat => GraphicsFormat.R16G16_SFloat; protected override bool NeedToReadWriteTextureData { get { return false; } } - internal const string MATERIAL_KEYWORD = "_FLOW_ON"; + internal const string MATERIAL_KEYWORD = "CREST_FLOW_ON"; internal const string ERROR_MATERIAL_KEYWORD_MISSING = "Flow must be enabled on the ocean material. Tick the Enable option in the Flow parameter section on the material currently assigned to the OceanRenderer component."; internal const string ERROR_MATERIAL_KEYWORD_ON_FEATURE_OFF = "The Flow feature is disabled on the this but is enabled on the ocean material. If this is not intentional, either enable the Create Flow Data option on this component to turn it on, or disable the Flow feature on the ocean material to save performance."; bool _targetsClear = false; diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFoam.cs b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFoam.cs index 0c96f8c33..bc2f3c29a 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFoam.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/LodDataMgrFoam.cs @@ -18,8 +18,7 @@ public class LodDataMgrFoam : LodDataMgrPersistent protected override int krnl_ShaderSim { get { return _shader.FindKernel(ShaderSim); } } public override string SimName { get { return "Foam"; } } protected override GraphicsFormat RequestedTextureFormat => Settings._renderTextureGraphicsFormat; - - internal const string MATERIAL_KEYWORD = "_FOAM_ON"; + internal const string MATERIAL_KEYWORD = "CREST_FOAM_ON"; internal const string ERROR_MATERIAL_KEYWORD_MISSING = "Foam must be enabled on the ocean material. Tick the Enable option in the Foam parameter section on the material currently assigned to the OceanRenderer component."; internal const string ERROR_MATERIAL_KEYWORD_ON_FEATURE_OFF = "The Foam feature is disabled on this component but is enabled on the ocean material. If this is not intentional, either enable the Create Foam Sim option on this component to turn it on, or disable the Foam feature on the ocean material to save performance."; diff --git a/crest/Assets/Crest/Crest/Scripts/LodData/Shadows/LodDataMgrShadow.cs b/crest/Assets/Crest/Crest/Scripts/LodData/Shadows/LodDataMgrShadow.cs index 3cd3fbd75..969d522e6 100644 --- a/crest/Assets/Crest/Crest/Scripts/LodData/Shadows/LodDataMgrShadow.cs +++ b/crest/Assets/Crest/Crest/Scripts/LodData/Shadows/LodDataMgrShadow.cs @@ -22,7 +22,7 @@ public class LodDataMgrShadow : LodDataMgr protected override GraphicsFormat RequestedTextureFormat => GraphicsFormat.R8G8_UNorm; protected override bool NeedToReadWriteTextureData { get { return true; } } - internal const string MATERIAL_KEYWORD = "_SHADOWS_ON"; + internal const string MATERIAL_KEYWORD = "CREST_SHADOWS_ON"; internal const string ERROR_MATERIAL_KEYWORD_MISSING = "Shadowing must be enabled on the ocean material. Tick the Shadowing option in the Scattering parameter section on the material currently assigned to the OceanRenderer component."; internal const string ERROR_MATERIAL_KEYWORD_ON_FEATURE_OFF = "The shadow feature is disabled on this component but is enabled on the ocean material. If this is not intentional, either enable the Create Shadow Data option on this component to turn it on, or disable the Shadowing feature on the ocean material to save performance."; diff --git a/crest/Assets/Crest/Crest/Shaders/Ocean.shader b/crest/Assets/Crest/Crest/Shaders/Ocean.shader index dd708f2b6..606ec1e30 100644 --- a/crest/Assets/Crest/Crest/Shaders/Ocean.shader +++ b/crest/Assets/Crest/Crest/Shaders/Ocean.shader @@ -23,7 +23,7 @@ Shader "Crest/Ocean" // Base colour when looking into water at shallow/grazing angle _DiffuseGrazing("Diffuse Grazing", Color) = (0.184, 0.393, 0.519, 1) // Changes colour in shadow. Requires 'Create Shadow Data' enabled on OceanRenderer script. - [Toggle] _Shadows("Shadowing", Float) = 0 + [Toggle] CREST_SHADOWS("Shadowing", Float) = 0 // Base colour in shadow _DiffuseShadow("Diffuse (Shadow)", Color) = (0.0, 0.356, 0.565, 1.0) @@ -97,7 +97,7 @@ Shader "Crest/Ocean" [Header(Foam)] // Enable foam layer on ocean surface - [Toggle] _Foam("Enable", Float) = 1 + [Toggle] CREST_FOAM("Enable", Float) = 1 // Foam texture [NoScaleOffset] _FoamTexture("Texture", 2D) = "white" {} // Foam texture scale @@ -137,7 +137,7 @@ Shader "Crest/Ocean" [Header(Caustics)] // Approximate rays being focused/defocused on underwater surfaces - [Toggle] _Caustics("Enable", Float) = 1 + [Toggle] CREST_CAUSTICS("Enable", Float) = 1 // Caustics texture [NoScaleOffset] _CausticsTexture("Caustics", 2D) = "black" {} // Caustics texture scale @@ -166,7 +166,7 @@ Shader "Crest/Ocean" [Header(Flow)] // Flow is horizontal motion in water as demonstrated in the 'whirlpool' example scene. 'Create Flow Sim' must be // enabled on the OceanRenderer to generate flow data. - [Toggle] _Flow("Enable", Float) = 0 + [Toggle] CREST_FLOW("Enable", Float) = 0 [Header(Clip Surface)] // Discards ocean surface pixels. Requires 'Create Clip Surface Data' enabled on OceanRenderer script. @@ -227,16 +227,16 @@ Shader "Crest/Ocean" #pragma shader_feature_local _SUBSURFACESCATTERING_ON #pragma shader_feature_local _SUBSURFACESHALLOWCOLOUR_ON #pragma shader_feature_local _TRANSPARENCY_ON - #pragma shader_feature_local _CAUSTICS_ON - #pragma shader_feature_local _FOAM_ON + #pragma shader_feature_local CREST_CAUSTICS_ON + #pragma shader_feature_local CREST_FOAM_ON #pragma shader_feature_local _FOAM3DLIGHTING_ON #pragma shader_feature_local _PLANARREFLECTIONS_ON #pragma shader_feature_local _OVERRIDEREFLECTIONCUBEMAP_ON #pragma shader_feature_local _PROCEDURALSKY_ON #pragma shader_feature_local _UNDERWATER_ON - #pragma shader_feature_local _FLOW_ON - #pragma shader_feature_local _SHADOWS_ON + #pragma shader_feature_local CREST_FLOW_ON + #pragma shader_feature_local CREST_SHADOWS_ON #pragma shader_feature_local _CLIPSURFACE_ON #pragma shader_feature_local _CLIPUNDERTERRAIN_ON @@ -344,11 +344,11 @@ Shader "Crest/Ocean" SampleDisplacements(_LD_TexArray_AnimatedWaves, uv_slice_smallerLod, wt_smallerLod, o.worldPos); #endif - #if _FOAM_ON + #if CREST_FOAM_ON SampleFoam(_LD_TexArray_Foam, uv_slice_smallerLod, wt_smallerLod, o.foam_screenPosXYW.x); #endif - #if _FLOW_ON + #if CREST_FLOW_ON SampleFlow(_LD_TexArray_Flow, uv_slice_smallerLod, wt_smallerLod, o.flow_shadow.xy); #endif } @@ -360,11 +360,11 @@ Shader "Crest/Ocean" SampleDisplacements(_LD_TexArray_AnimatedWaves, uv_slice_biggerLod, wt_biggerLod, o.worldPos); #endif - #if _FOAM_ON + #if CREST_FOAM_ON SampleFoam(_LD_TexArray_Foam, uv_slice_biggerLod, wt_biggerLod, o.foam_screenPosXYW.x); #endif - #if _FLOW_ON + #if CREST_FLOW_ON SampleFlow(_LD_TexArray_Flow, uv_slice_biggerLod, wt_biggerLod, o.flow_shadow.xy); #endif } @@ -379,7 +379,7 @@ Shader "Crest/Ocean" SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_smallerLodDisp, wt_smallerLod, o.lodAlpha_worldXZUndisplaced_oceanDepth.w); #endif - #if _SHADOWS_ON + #if CREST_SHADOWS_ON if (wt_smallerLod > 0.001) { SampleShadow(_LD_TexArray_Shadow, uv_slice_smallerLodDisp, wt_smallerLod, o.flow_shadow.zw); @@ -395,7 +395,7 @@ Shader "Crest/Ocean" SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_slice_biggerLodDisp, wt_biggerLod, o.lodAlpha_worldXZUndisplaced_oceanDepth.w); #endif - #if _SHADOWS_ON + #if CREST_SHADOWS_ON if (wt_biggerLod > 0.001) { SampleShadow(_LD_TexArray_Shadow, uv_slice_biggerLodDisp, wt_biggerLod, o.flow_shadow.zw); @@ -495,7 +495,7 @@ Shader "Crest/Ocean" float3 lightDir = WorldSpaceLightDir(input.worldPos); // Soft shadow, hard shadow fixed2 shadow = (fixed2)1.0 - #if _SHADOWS_ON + #if CREST_SHADOWS_ON - input.flow_shadow.zw #endif ; @@ -519,7 +519,7 @@ Shader "Crest/Ocean" half3 n_pixel = n_geom; #if _APPLYNORMALMAPPING_ON - #if _FLOW_ON + #if CREST_FLOW_ON ApplyNormalMapsWithFlow(input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.flow_shadow.xy, lodAlpha, cascadeData0, instanceData, n_pixel); #else n_pixel.xz += SampleNormalMaps(input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, lodAlpha, cascadeData0, instanceData); @@ -531,14 +531,14 @@ Shader "Crest/Ocean" // Foam - underwater bubbles and whitefoam half3 bubbleCol = (half3)0.; - #if _FOAM_ON + #if CREST_FOAM_ON half4 whiteFoamCol; - #if !_FLOW_ON + #if !CREST_FLOW_ON ComputeFoam(input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol, cascadeData0, cascadeData1); #else ComputeFoamWithFlow(input.flow_shadow.xy, input.foam_screenPosXYW.x, input.lodAlpha_worldXZUndisplaced_oceanDepth.yz, input.worldPos.xz, n_pixel, pixelZ, sceneZ, view, lightDir, shadow.y, lodAlpha, bubbleCol, whiteFoamCol, cascadeData0, cascadeData1); - #endif // _FLOW_ON - #endif // _FOAM_ON + #endif // CREST_FLOW_ON + #endif // CREST_FOAM_ON // Compute color of ocean - in-scattered light + refracted scene const float baseCascadeScale = _CrestCascadeData[0]._scale; @@ -569,7 +569,7 @@ Shader "Crest/Ocean" } // Override final result with white foam - bubbles on surface - #if _FOAM_ON + #if CREST_FOAM_ON col = lerp(col, whiteFoamCol.rgb, whiteFoamCol.a); #endif @@ -589,7 +589,7 @@ Shader "Crest/Ocean" col = lerp(col.rgb, input.debugtint, 0.5); #endif #if _DEBUGVISUALISEFLOW_ON - #if _FLOW_ON + #if CREST_FLOW_ON col.rg = lerp(col.rg, input.flow_shadow.xy, 0.5); #endif #endif @@ -603,4 +603,5 @@ Shader "Crest/Ocean" // If the above doesn't work then error. FallBack "Hidden/InternalErrorShader" + CustomEditor "Crest.Editor.OceanShaderGUI" } diff --git a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl index 2be71085b..a4d81ed83 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanEmission.hlsl @@ -26,7 +26,7 @@ half3 ScatterColour( depth = CREST_OCEAN_DEPTH_BASELINE; SampleSeaDepth(_LD_TexArray_SeaFloorDepth, uv_smallerLod, 1.0, depth); -#if _SHADOWS_ON +#if CREST_SHADOWS_ON const float2 samplePoint = i_cameraPos.xz; // Pick lower res data for shadowing, helps to smooth out artifacts slightly @@ -58,7 +58,7 @@ half3 ScatterColour( float v = abs(i_view.y); half3 col = lerp(_Diffuse, _DiffuseGrazing, 1. - pow(v, 1.0)); -#if _SHADOWS_ON +#if CREST_SHADOWS_ON col = lerp(_DiffuseShadow, col, shadow); #endif @@ -67,7 +67,7 @@ half3 ScatterColour( #if _SUBSURFACESHALLOWCOLOUR_ON float shallowness = pow(1. - saturate(depth / _SubSurfaceDepthMax), _SubSurfaceDepthPower); half3 shallowCol = _SubSurfaceShallowCol; -#if _SHADOWS_ON +#if CREST_SHADOWS_ON shallowCol = lerp(_SubSurfaceShallowColShadow, shallowCol, shadow); #endif col = lerp(col, shallowCol, shallowness); @@ -90,7 +90,7 @@ half3 ScatterColour( } -#if _CAUSTICS_ON +#if CREST_CAUSTICS_ON void ApplyCaustics(in const half3 i_view, in const half3 i_lightDir, in const float i_sceneZ, in sampler2D i_normals, in const bool i_underwater, inout half3 io_sceneColour, in const CascadeParams cascadeData0, in const CascadeParams cascadeData1) { @@ -122,7 +122,7 @@ void ApplyCaustics(in const half3 i_view, in const half3 i_lightDir, in const fl half causticsStrength = _CausticsStrength; -#if _SHADOWS_ON +#if CREST_SHADOWS_ON { // Calculate projected position again as we do not want the fudge factor. If we include the fudge factor, the // caustics will not be aligned with shadows. @@ -143,12 +143,12 @@ void ApplyCaustics(in const half3 i_view, in const half3 i_lightDir, in const fl } causticsStrength *= 1.0 - causticShadow.y; } -#endif // _SHADOWS_ON +#endif // CREST_SHADOWS_ON io_sceneColour.xyz *= 1.0 + causticsStrength * (0.5*tex2Dlod(_CausticsTexture, cuv1).xyz + 0.5*tex2Dlod(_CausticsTexture, cuv2).xyz - _CausticsTextureAverage); } -#endif // _CAUSTICS_ON +#endif // CREST_CAUSTICS_ON half3 OceanEmission(in const half3 i_view, in const half3 i_n_pixel, in const float3 i_lightDir, @@ -195,7 +195,7 @@ half3 OceanEmission(in const half3 i_view, in const half3 i_n_pixel, in const fl } sceneColour = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_BackgroundTexture, uvBackgroundRefract).rgb; -#if _CAUSTICS_ON +#if CREST_CAUSTICS_ON ApplyCaustics(i_view, i_lightDir, i_sceneZ, i_normals, i_underwater, sceneColour, cascadeData0, cascadeData1); #endif alpha = 1.0 - exp(-_DepthFogDensity.xyz * depthFogDistance); diff --git a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl index 997b0fcd6..f266b5e8a 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanFoam.hlsl @@ -10,7 +10,7 @@ half3 AmbientLight() return half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); } -#if _FOAM_ON +#if CREST_FOAM_ON half WhiteFoamTexture(half i_foam, float2 i_worldXZUndisplaced, half lodVal, in const CascadeParams cascadeData0, in const CascadeParams cascadeData1) { @@ -101,6 +101,6 @@ void ComputeFoamWithFlow(half2 flow, half i_foam, float2 i_worldXZUndisplaced, f o_whiteFoamCol = (sample1_weight * o_whiteFoamCol1) + (sample2_weight * o_whiteFoamCol2); } -#endif // _FOAM_ON +#endif // CREST_FOAM_ON #endif // CREST_OCEAN_FOAM_INCLUDED diff --git a/crest/Assets/Crest/Crest/Shaders/OceanShaderData.hlsl b/crest/Assets/Crest/Crest/Shaders/OceanShaderData.hlsl index fb251eb72..83990b0aa 100644 --- a/crest/Assets/Crest/Crest/Shaders/OceanShaderData.hlsl +++ b/crest/Assets/Crest/Crest/Shaders/OceanShaderData.hlsl @@ -19,10 +19,10 @@ sampler2D _ReflectionTex; #if _OVERRIDEREFLECTIONCUBEMAP_ON samplerCUBE _ReflectionCubemapOverride; #endif -#if _FOAM_ON +#if CREST_FOAM_ON sampler2D _FoamTexture; #endif -#if _CAUSTICS_ON +#if CREST_CAUSTICS_ON sampler2D _CausticsTexture; #endif @@ -37,7 +37,7 @@ CBUFFER_START(CrestInputsPerMaterial) half3 _Diffuse; half3 _DiffuseGrazing; -#if _SHADOWS_ON +#if CREST_SHADOWS_ON half3 _DiffuseShadow; #endif @@ -74,7 +74,7 @@ half _SubSurfaceSunFallOff; half _SubSurfaceDepthMax; half _SubSurfaceDepthPower; half3 _SubSurfaceShallowCol; -#if _SHADOWS_ON +#if CREST_SHADOWS_ON half3 _SubSurfaceShallowColShadow; #endif #endif @@ -114,7 +114,7 @@ half _SkyDirectionality; // Foam // ---------------------------------------------------------------------------- -#if _FOAM_ON +#if CREST_FOAM_ON half _FoamScale; half4 _FoamWhiteColor; half _WaveFoamFeather; @@ -136,7 +136,7 @@ half _WaveFoamBubblesCoverage; // Caustics // ---------------------------------------------------------------------------- -#if _CAUSTICS_ON +#if CREST_CAUSTICS_ON half _CausticsTextureScale; half _CausticsTextureAverage; half _CausticsStrength; diff --git a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader index 467cd34ff..b20328b11 100644 --- a/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader +++ b/crest/Assets/Crest/Crest/Shaders/Underwater/UnderwaterCurtain.shader @@ -44,8 +44,8 @@ Shader "Crest/Underwater Curtain" #pragma multi_compile_local __ _SUBSURFACESCATTERING_ON #pragma multi_compile_local __ _SUBSURFACESHALLOWCOLOUR_ON #pragma multi_compile_local __ _TRANSPARENCY_ON - #pragma multi_compile_local __ _CAUSTICS_ON - #pragma multi_compile_local __ _SHADOWS_ON + #pragma multi_compile_local __ CREST_CAUSTICS_ON + #pragma multi_compile_local __ CREST_SHADOWS_ON #pragma multi_compile_local __ _COMPILESHADERWITHDEBUGINFO_ON #if _COMPILESHADERWITHDEBUGINFO_ON @@ -207,12 +207,12 @@ Shader "Crest/Underwater Curtain" half3 sceneColour = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_BackgroundTexture, input.grabPos.xy / input.grabPos.w).rgb; -#if _CAUSTICS_ON +#if CREST_CAUSTICS_ON if (sceneZ01 != 0.0) { ApplyCaustics(view, lightDir, sceneZ, _Normals, true, sceneColour, cascadeData0, cascadeData1); } -#endif // _CAUSTICS_ON +#endif // CREST_CAUSTICS_ON half3 col = lerp(sceneColour, scatterCol, 1.0 - exp(-_DepthFogDensity.xyz * sceneZ)); From 182b3f8dceb806e525c57cca7df932c54e7bd447 Mon Sep 17 00:00:00 2001 From: Dale Eidd Date: Thu, 25 Feb 2021 22:55:44 -0800 Subject: [PATCH 3/3] Fix material upgrade not working with not yet loaded materials --- .../Crest/Scripts/Editor/MaterialHelper.cs | 105 +++++++++++------- .../Crest/Scripts/Editor/MaterialUpgrader.cs | 2 + 2 files changed, 68 insertions(+), 39 deletions(-) diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs index 741016210..5c5c98998 100644 --- a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialHelper.cs @@ -19,7 +19,8 @@ public static class MaterialHelper { "_Flow", "CREST_FLOW" }, }; - internal static void MigrateKeywords(Material material, SerializedObject serializedObject, SerializedProperty floatProperties, SerializedProperty keywordProperties) + internal static void MigrateKeywords(Material material, SerializedObject serializedObject, + SerializedProperty floatProperties, SerializedProperty keywordProperties) { foreach (var entry in RenamedKeywords) { @@ -36,7 +37,7 @@ internal static void MigrateKeywordsGUI(Material material, SerializedObject seri var floatProperties = serializedObject.FindProperty("m_SavedProperties.m_Floats"); var keywordProperties = serializedObject.FindProperty("m_ShaderKeywords"); - if (ContainsRenamedKeyword(floatProperties) && GUILayout.Button("Migrate")) + if (ContainsRenamedKeyword(floatProperties) && GUILayout.Button("Upgrade Material")) { foreach (var entry in RenamedKeywords) { @@ -67,50 +68,76 @@ internal static bool ContainsRenamedKeyword(SerializedProperty floatProperties) return false; } - internal static void RenameKeyword(string oldName, string newName, SerializedProperty floatProperties, SerializedProperty keywordProperties) + internal static void RenameKeyword(string oldName, string newName, SerializedProperty floatProperties, + SerializedProperty keywordProperties) { - if (floatProperties != null && floatProperties.isArray) + if (floatProperties == null || !floatProperties.isArray || keywordProperties == null) { - for (int i = 0; i < floatProperties.arraySize; i++) + // TODO: Error + return; + } + + for (int i = 0; i < floatProperties.arraySize; i++) + { + var oldProperty = floatProperties.GetArrayElementAtIndex(i); + if (oldProperty.displayName != oldName) { - var oldProperty = floatProperties.GetArrayElementAtIndex(i); - if (oldProperty.displayName == oldName) + continue; + } + + // If the material/shader has been loaded, it will already have created the new properties. + var isFound = false; + for (int ii = 0; ii < floatProperties.arraySize; ii++) + { + SerializedProperty newProperty = floatProperties.GetArrayElementAtIndex(ii); + + if (newProperty.displayName == newName) { - for (int ii = 0; ii < floatProperties.arraySize; ii++) - { - SerializedProperty newProperty = floatProperties.GetArrayElementAtIndex(ii); - // Even if the property does not exist in the file, it will exist if it is defined in the shader. - if (newProperty.displayName == newName) - { - // A property is a pair so we need to navigate down a level. - oldProperty.Next(true); - // Skip the first value which is the name. - oldProperty.Next(false); - - // A property is a pair so we need to navigate down a level. - newProperty.Next(true); - // Skip the first value which is the name. - newProperty.Next(false); - - // Copy the value over. - newProperty.floatValue = oldProperty.floatValue; - - var keywords = keywordProperties.stringValue.Split(' ').ToList(); - keywords.Remove($"{oldName.ToUpper()}_ON"); - if (newProperty.floatValue == 1) - { - keywords.Add($"{newName.ToUpper()}_ON"); - } - keywordProperties.stringValue = string.Join(" ", keywords); - } - } - - // Delete the old property. - floatProperties.DeleteArrayElementAtIndex(i); - return; + RenameKeyword(oldName, newName, oldProperty, newProperty, keywordProperties); + isFound = true; + break; } } + + if (!isFound) + { + // Insert at the end of the array. + floatProperties.InsertArrayElementAtIndex(floatProperties.arraySize); + // Fetch newly inserted property. arraySize dynamically increases on insertion. + SerializedProperty newProperty = floatProperties.GetArrayElementAtIndex(floatProperties.arraySize - 1); + RenameKeyword(oldName, newName, oldProperty, newProperty, keywordProperties); + } + + // Delete the old property. + floatProperties.DeleteArrayElementAtIndex(i); + return; + } + } + + internal static void RenameKeyword(string oldName, string newName, SerializedProperty oldProperty, + SerializedProperty newProperty, SerializedProperty keywordProperties) + { + // A property is a pair so we need to navigate down a level. + oldProperty.Next(true); + // Skip the first value which is the label. + oldProperty.Next(false); + + // Navigate to the label. + newProperty.Next(true); + // Set the label just in case this is newly inserted. + newProperty.stringValue = newName; + // Navigate to the value. + newProperty.Next(false); + // Copy the value over. + newProperty.floatValue = oldProperty.floatValue; + + var keywords = keywordProperties.stringValue.Split(' ').ToList(); + keywords.Remove($"{oldName.ToUpper()}_ON"); + if (newProperty.floatValue == 1) + { + keywords.Add($"{newName.ToUpper()}_ON"); } + keywordProperties.stringValue = string.Join(" ", keywords); } } } diff --git a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs index 22e5decf1..63683a2ec 100644 --- a/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs +++ b/crest/Assets/Crest/Crest/Scripts/Editor/MaterialUpgrader.cs @@ -17,6 +17,7 @@ static bool DisplayMaterialUpgradeDialogue() => EditorUtility.DisplayDialog "Leave Crest Materials Alone" ); + [MenuItem("Edit/Crest/Upgrade Materials")] [InitializeOnLoadMethod] static void UpgradeMaterials() { @@ -37,6 +38,7 @@ static void UpgradeMaterials() var material = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid)); if (material.shader.name == "Crest/Ocean") { + // Get all of the properties to query and manipulate. var serializedObject = new SerializedObject(material); var floatProperties = serializedObject.FindProperty("m_SavedProperties.m_Floats"); var keywordProperties = serializedObject.FindProperty("m_ShaderKeywords");