@@ -30,23 +30,16 @@ public class SpeedTree9Importer : ScriptedImporter
3030 internal static class ImporterSettings
3131 {
3232 internal const string kGameObjectName = "SpeedTree" ;
33- internal const string kHDRPShaderName = "HDRP/Nature/SpeedTree9_HDRP" ;
34- internal const string kURPShaderName = "Universal Render Pipeline/Nature/SpeedTree9_URP" ;
3533 internal const string kLegacyShaderName = "Nature/SpeedTree9" ;
3634 internal const string kWindAssetName = "SpeedTreeWind" ;
37- internal const string kSRPDependencyName = "srp/default-pipeline " ;
35+ internal const string kSRPDependencyName = "SpeedTree9Importer_DefaultShader " ;
3836 internal const string kMaterialSettingsDependencyname = "SpeedTree9Importer_MaterialSettings" ;
39-
40- // In some very specific scenarios, the Shader cannot be found using "Shader.Find" (e.g project upgrade).
41- // Adding an extra-security is necessary to avoid that, by manually forcing the load of the Shader using
42- // "AssetDatabase.LoadAssetAtPath". It only happens for SRPs during project upgrades.
43- internal const string kHDRPShaderPath = "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Nature/SpeedTree9_HDRP.shadergraph" ;
44- internal const string kURPShaderPath = "Packages/com.unity.render-pipelines.universal/Shaders/Nature/SpeedTree9_URP.shadergraph" ;
37+ internal const string kIconName = "UnityEditor/SpeedTree9Importer Icon" ;
4538 }
4639
4740 private static class Styles
4841 {
49- internal static readonly Texture2D kIcon = EditorGUIUtility . FindTexture ( "UnityEditor/SpeedTree9Importer Icon" ) ;
42+ internal static readonly Texture2D kIcon = EditorGUIUtility . FindTexture ( ImporterSettings . kIconName ) ;
5043 }
5144
5245 private struct STMeshGeometry
@@ -118,12 +111,15 @@ public STMeshGeometry(int vertexCount, int UVCount, int indexLod)
118111 [ SerializeField ]
119112 internal SpeedTreeImporterOutputData m_OutputImporterData ;
120113
114+ private static ulong s_DefaultShaderHash ;
115+ private static readonly TimeSpan k_CheckDependencyFrequency = TimeSpan . FromSeconds ( 5 ) ;
116+ private static DateTime s_LastCheck ;
117+
121118 // Cache main objects, created during import process.
122119 private AssetImportContext m_Context ;
123120 private SpeedTree9Reader m_Tree ;
124121 private Shader m_Shader ;
125122 private SpeedTreeWindAsset m_WindAsset ;
126- private STRenderPipeline m_RenderPipeline ;
127123
128124 // Values cached at the begining of the import process.
129125 private bool m_HasFacingData ;
@@ -157,11 +153,9 @@ public override void OnImportAsset(AssetImportContext ctx)
157153
158154 CacheTreeImporterValues ( ctx . assetPath ) ;
159155
160- m_RenderPipeline = GetCurrentRenderPipelineType ( ) ;
161-
162156 ctx . DependsOnCustomDependency ( ImporterSettings . kSRPDependencyName ) ;
163157
164- if ( ! TryGetShaderForCurrentRenderPipeline ( m_RenderPipeline , out m_Shader ) )
158+ if ( ! TryGetShaderForCurrentRenderPipeline ( out m_Shader ) )
165159 {
166160 ctx . LogImportError ( "SpeedTree9 shader is invalid, cannot create Materials for this SpeedTree asset." ) ;
167161 return ;
@@ -273,6 +267,61 @@ internal void RegenerateMaterials()
273267 }
274268 }
275269
270+ [ InitializeOnLoadMethod ]
271+ static void InitializeEditorCallback ( )
272+ {
273+ EditorApplication . update += DirtyCustomDependencies ;
274+ s_DefaultShaderHash = ComputeDefaultShaderHash ( ) ;
275+ AssetDatabase . RegisterCustomDependency ( ImporterSettings . kSRPDependencyName , new Hash128 ( s_DefaultShaderHash , 0 ) ) ;
276+ }
277+
278+
279+ static ulong CombineHash ( ulong h1 , ulong h2 )
280+ {
281+ unchecked
282+ {
283+ return h1 ^ h2 + 0x9e3779b9 + ( h1 << 6 ) + ( h1 >> 2 ) ; // Similar to c++ boost::hash_combine
284+ }
285+ }
286+
287+ static ulong ComputeDefaultShaderHash ( )
288+ {
289+ ulong newDefaultShaderHash = 0UL ;
290+ if ( GraphicsSettings . currentRenderPipeline == null || GraphicsSettings . currentRenderPipeline . defaultSpeedTree9Shader == null )
291+ {
292+ newDefaultShaderHash = 0 ;
293+ }
294+ else
295+ {
296+ if ( AssetDatabase . TryGetGUIDAndLocalFileIdentifier ( GraphicsSettings . currentRenderPipeline . defaultSpeedTree9Shader , out var guid ,
297+ out long fileId ) )
298+ {
299+ newDefaultShaderHash = CombineHash ( ( ulong ) guid . GetHashCode ( ) , ( ulong ) fileId ) ;
300+ }
301+ }
302+
303+ return newDefaultShaderHash ;
304+ }
305+
306+ static void DirtyCustomDependencies ( )
307+ {
308+ DateTime now = DateTime . Now ;
309+ if ( Application . isPlaying || now - s_LastCheck < k_CheckDependencyFrequency )
310+ {
311+ return ;
312+ }
313+
314+ s_LastCheck = now ;
315+
316+ ulong newDefaultShaderHash = ComputeDefaultShaderHash ( ) ;
317+ if ( s_DefaultShaderHash != newDefaultShaderHash )
318+ {
319+ s_DefaultShaderHash = newDefaultShaderHash ;
320+ AssetDatabase . RegisterCustomDependency ( ImporterSettings . kSRPDependencyName , new Hash128 ( s_DefaultShaderHash , 0 ) ) ;
321+ AssetDatabase . Refresh ( ) ;
322+ }
323+ }
324+
276325 #region Mesh Geometry & Renderers
277326 private Mesh CreateMeshAndGeometry ( Lod lod , int lodIndex )
278327 {
@@ -717,9 +766,7 @@ private void RegenerateAndPopulateExternalMaterials(string assetPath)
717766
718767 CacheTreeImporterValues ( assetPath ) ;
719768
720- m_RenderPipeline = GetCurrentRenderPipelineType ( ) ;
721-
722- if ( ! TryGetShaderForCurrentRenderPipeline ( m_RenderPipeline , out m_Shader ) )
769+ if ( ! TryGetShaderForCurrentRenderPipeline ( out m_Shader ) )
723770 {
724771 Debug . LogError ( "SpeedTree9 shader is invalid, cannot create Materials for this SpeedTree asset." ) ;
725772 return ;
@@ -999,22 +1046,24 @@ private void SetMaterialOtherProperties(STMaterial stMaterial, Material mat)
9991046 }
10001047 mat . SetFloat ( MaterialProperties . LeafFacingKwToggleID , m_HasFacingData ? 1.0f : 0.0f ) ;
10011048
1002- if ( m_RenderPipeline == STRenderPipeline . HDRP )
1003- {
1049+ if ( mat . HasFloat ( MaterialProperties . DoubleSidedToggleID ) )
10041050 mat . SetFloat ( MaterialProperties . DoubleSidedToggleID , stMaterial . TwoSided ? 1.0f : 0.0f ) ;
1051+
1052+ if ( mat . HasFloat ( MaterialProperties . DoubleSidedNormalModeID ) )
10051053 mat . SetFloat ( MaterialProperties . DoubleSidedNormalModeID , stMaterial . FlipNormalsOnBackside ? 0.0f : 2.0f ) ;
10061054
1055+ if ( mat . HasVector ( MaterialProperties . DiffusionProfileAssetID ) )
10071056 mat . SetVector ( MaterialProperties . DiffusionProfileAssetID , m_MaterialSettings . diffusionProfileAssetID ) ;
1057+
1058+ if ( mat . HasFloat ( MaterialProperties . DiffusionProfileID ) )
10081059 mat . SetFloat ( MaterialProperties . DiffusionProfileID , m_MaterialSettings . diffusionProfileID ) ;
1009- }
1010- else if ( m_RenderPipeline == STRenderPipeline . URP )
1011- {
1060+
1061+ if ( mat . HasFloat ( MaterialProperties . BackfaceNormalModeID ) )
10121062 mat . SetFloat ( MaterialProperties . BackfaceNormalModeID , stMaterial . FlipNormalsOnBackside ? 0.0f : 2.0f ) ;
1013- }
1014- else // legacy rendering pipeline
1015- {
1063+
1064+ if ( mat . HasFloat ( MaterialProperties . TwoSidedID ) )
10161065 mat . SetFloat ( MaterialProperties . TwoSidedID , stMaterial . TwoSided ? 0.0f : 2.0f ) ; // matches cull mode. 0: no cull
1017- }
1066+
10181067 mat . enableInstancing = true ;
10191068 mat . doubleSidedGI = stMaterial . TwoSided ;
10201069 }
@@ -1108,20 +1157,6 @@ internal string GetMaterialFolderPath()
11081157 return FileUtil . DeleteLastPathNameComponent ( assetPath ) + "/" ;
11091158 }
11101159
1111- internal string GetShaderNameFromPipeline ( STRenderPipeline renderPipeline )
1112- {
1113- switch ( renderPipeline )
1114- {
1115- case STRenderPipeline . HDRP :
1116- return ImporterSettings . kHDRPShaderName ;
1117- case STRenderPipeline . URP :
1118- return ImporterSettings . kURPShaderName ;
1119- case STRenderPipeline . Legacy :
1120- default :
1121- return ImporterSettings . kLegacyShaderName ;
1122- }
1123- }
1124-
11251160 internal void SetMaterialsVersionToCurrent ( )
11261161 {
11271162 m_MaterialVersion = SPEEDTREE_9_MATERIAL_VERSION ;
@@ -1353,27 +1388,17 @@ private bool TreeHasFacingData()
13531388 return false ;
13541389 }
13551390
1356- private bool TryGetShaderForCurrentRenderPipeline ( STRenderPipeline renderPipeline , out Shader shader )
1391+ internal static bool TryGetShaderForCurrentRenderPipeline ( out Shader shader )
13571392 {
1358- switch ( renderPipeline )
1393+ shader = null ;
1394+ if ( GraphicsSettings . currentRenderPipeline != null )
13591395 {
1360- case STRenderPipeline . URP :
1361- shader = Shader . Find ( ImporterSettings . kURPShaderName ) ;
1362- if ( shader == null )
1363- {
1364- shader = m_Context . GetReferenceToAssetMainObject ( ImporterSettings . kURPShaderPath ) as Shader ;
1365- }
1366- break ;
1367- case STRenderPipeline . HDRP :
1368- shader = Shader . Find ( ImporterSettings . kHDRPShaderName ) ;
1369- if ( shader == null )
1370- {
1371- shader = m_Context . GetReferenceToAssetMainObject ( ImporterSettings . kHDRPShaderPath ) as Shader ;
1372- }
1373- break ;
1374- default :
1375- shader = Shader . Find ( ImporterSettings . kLegacyShaderName ) ;
1376- break ;
1396+ shader = GraphicsSettings . currentRenderPipeline . defaultSpeedTree9Shader ;
1397+ }
1398+
1399+ if ( shader == null )
1400+ {
1401+ shader = Shader . Find ( ImporterSettings . kLegacyShaderName ) ;
13771402 }
13781403
13791404 return shader != null ;
0 commit comments