public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (triplanarMode != TriplanarMode.None) { if (MicroSplatUtilities.DrawRollup("Triplanar") && mat.HasProperty("_TriplanarContrast")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_TriplanarContrast", props), CTriplanarContrast); if (mat.HasProperty("_TriplanarUVScale")) { EditorGUI.BeginChangeCheck(); Vector4 uvScale = shaderGUI.FindProp("_TriplanarUVScale", props).vectorValue; Vector2 scl = new Vector2(uvScale.x, uvScale.y); Vector2 offset = new Vector2(uvScale.z, uvScale.w); scl = EditorGUILayout.Vector2Field("Triplanar UV Scale", scl); offset = EditorGUILayout.Vector2Field("Triplanar UV Offset", offset); if (EditorGUI.EndChangeCheck()) { uvScale.x = scl.x; uvScale.y = scl.y; uvScale.z = offset.x; uvScale.w = offset.y; shaderGUI.FindProp("_TriplanarUVScale", props).vectorValue = uvScale; EditorUtility.SetDirty(mat); } } } } }
//GUIContent CShadowMap = new GUIContent("Shadow Map", "Shadow Map for distant terrain"); public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if ((grassMap || shadowMap) && MicroSplatUtilities.DrawRollup("Vegetation Studio")) { if (grassMap && mat.HasProperty("_VSTint")) { EditorGUI.BeginChangeCheck(); var c = mat.GetColor("_VSTint"); c = EditorGUILayout.ColorField(CShaderTint, c); if (EditorGUI.EndChangeCheck()) { mat.SetColor("_VSTint", c); EditorUtility.SetDirty(mat); } } if (shadowMap && mat.HasProperty("_VSShadowMap")) { var offsetProp = shaderGUI.FindProp("_VSShadowMapOffsetStrength", props); Vector4 v = offsetProp.vectorValue; EditorGUI.BeginChangeCheck(); //v.x = EditorGUILayout.FloatField("Offset", v.x); v.y = EditorGUILayout.Slider("Min Tree Height", v.y, 0, 1.0f); v.z = EditorGUILayout.Slider("Shadow Strength", v.z, 0, 1.0f); v.w = EditorGUILayout.Slider("Shadow Ambient", v.w, 0, 1.0f); if (EditorGUI.EndChangeCheck()) { offsetProp.vectorValue = v; } } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (alphaHole != AlphaHoleMode.None || alphaBelowHeight) { if (MicroSplatUtilities.DrawRollup("Alpha")) { if (mat.HasProperty("_AlphaData") && alphaHole == AlphaHoleMode.SplatIndex || alphaBelowHeight) { Vector4 vals = shaderGUI.FindProp("_AlphaData", props).vectorValue; Vector4 newVals = vals; if (alphaHole == AlphaHoleMode.SplatIndex) { newVals.x = (int)EditorGUILayout.IntSlider(CTextureIndex, (int)vals.x, 0, 16); } if (alphaBelowHeight) { newVals.y = EditorGUILayout.FloatField(CWaterLevel, vals.y); } if (newVals != vals) { shaderGUI.FindProp("_AlphaData", props).vectorValue = newVals; } } else if (mat.HasProperty("_AlphaHoleTexture")) { materialEditor.TexturePropertySingleLine(CAlphaTexture, shaderGUI.FindProp("_AlphaHoleTexture", props)); } } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (alphaHole || alphaBelowHeight) { if (MicroSplatUtilities.DrawRollup("Alpha")) { if (mat.HasProperty("_AlphaData")) { Vector4 vals = shaderGUI.FindProp("_AlphaData", props).vectorValue; Vector4 newVals = vals; if (alphaHole) { newVals.x = (int)EditorGUILayout.IntSlider(CTextureIndex, (int)vals.x, 0, 16); } if (alphaBelowHeight) { newVals.y = EditorGUILayout.FloatField(CWaterLevel, vals.y); } if (newVals != vals) { shaderGUI.FindProp("_AlphaData", props).vectorValue = newVals; } } } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (MicroSplatUtilities.DrawRollup("Splats")) { var albedoMap = shaderGUI.FindProp("_Diffuse", props); var normalMap = shaderGUI.FindProp("_NormalSAO", props); materialEditor.TexturePropertySingleLine(CAlbedoTex, albedoMap); if (!disableNormals) { if (packMode == TextureArrayConfig.PackingMode.Fastest) { materialEditor.TexturePropertySingleLine(CNormalSpec, normalMap); } else { materialEditor.TexturePropertySingleLine(CNormal, normalMap); } } if (emissiveArray && mat.HasProperty("_EmissiveMetal")) { var emisMap = shaderGUI.FindProp("_EmissiveMetal", props); materialEditor.TexturePropertySingleLine(CEmisMetal, emisMap); } if (packMode == TextureArrayConfig.PackingMode.Quality && mat.HasProperty("_SmoothAO")) { var smoothAO = shaderGUI.FindProp("_SmoothAO", props); materialEditor.TexturePropertySingleLine(CSmoothAO, smoothAO); } if (!disableHeightBlend) { var contrastProp = shaderGUI.FindProp("_Contrast", props); contrastProp.floatValue = EditorGUILayout.Slider(CInterpContrast, contrastProp.floatValue, 1.0f, 0.0001f); } if (!keywords.IsKeywordEnabled("_TRIPLANAR")) { EditorGUI.BeginChangeCheck(); Vector4 uvScale = shaderGUI.FindProp("_UVScale", props).vectorValue; Vector2 scl = new Vector2(uvScale.x, uvScale.y); Vector2 offset = new Vector2(uvScale.z, uvScale.w); scl = EditorGUILayout.Vector2Field("Global UV Scale", scl); offset = EditorGUILayout.Vector2Field("Global UV Offset", offset); if (EditorGUI.EndChangeCheck()) { uvScale.x = scl.x; uvScale.y = scl.y; uvScale.z = offset.x; uvScale.w = offset.y; shaderGUI.FindProp("_UVScale", props).vectorValue = uvScale; EditorUtility.SetDirty(mat); } } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (isTessellated && mat.HasProperty("_TessData1") && MicroSplatUtilities.DrawRollup("Tessellation")) { var td1 = shaderGUI.FindProp("_TessData1", props); var td2 = shaderGUI.FindProp("_TessData2", props); EditorGUI.BeginChangeCheck(); var td1v = td1.vectorValue; var td2v = td2.vectorValue; td1v.y = EditorGUILayout.Slider(CTessDisplacement, td1v.y, 0, 3); td1v.z = (float)EditorGUILayout.IntSlider(CTessMipBias, (int)td1v.z, 0, 6); td2v.z = 1.0f - (float)EditorGUILayout.Slider(CTessShaping, 1.0f - td2v.z, 0.0f, 0.999f); if (!perTexUpBias) { td2v.w = (float)EditorGUILayout.Slider(CTessUpBias, td2v.w, 0.0f, 1); } td1v.x = EditorGUILayout.Slider(CTessTessellation, td1v.x, 1, 32); td2v.x = EditorGUILayout.FloatField(CTessMinDistance, td2v.x); td2v.y = EditorGUILayout.FloatField(CTessMaxDistance, td2v.y); if (EditorGUI.EndChangeCheck()) { td1.vectorValue = td1v; td2.vectorValue = td2v; } } if (parallax && MicroSplatUtilities.DrawRollup("Parallax") && mat.HasProperty("_ParallaxParams")) { EditorGUI.BeginChangeCheck(); var parprop = shaderGUI.FindProp("_ParallaxParams", props); Vector4 vec = parprop.vectorValue; vec.x = EditorGUILayout.Slider("Parallax Height", vec.x, 0.0f, 0.12f); vec.y = EditorGUILayout.FloatField("Parallax Fade Start", vec.y); vec.z = EditorGUILayout.FloatField("Parallax Fade Distance", vec.z); if (EditorGUI.EndChangeCheck()) { parprop.vectorValue = vec; } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (specularFade) { if (MicroSplatUtilities.DrawRollup("Specular Height Fade") && mat.HasProperty("_SpecularFades")) { Vector4 sf = mat.GetVector("_SpecularFades"); EditorGUI.BeginChangeCheck(); Vector2 vals = new Vector2(sf.x, sf.y); vals = EditorGUILayout.Vector2Field(CSpecularHeights, vals); sf.x = vals.x; sf.y = vals.y; if (EditorGUI.EndChangeCheck()) { mat.SetVector("_SpecularFades", sf); EditorUtility.SetDirty(mat); } } } if (wetness || puddles || streams || lava) { if (MicroSplatUtilities.DrawRollup("Streams & Lava")) { if (mat.HasProperty("_GlobalPorosity") && !mat.IsKeywordEnabled("_PERTEXPOROSITY")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_GlobalPorosity", props), "Default Porosity"); } if (wetness && mat.HasProperty("_WetnessParams")) { Vector4 wet = mat.GetVector("_WetnessParams"); EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); var oldEnabled = GUI.enabled; if (globalWetness) { GUI.enabled = false; } EditorGUILayout.MinMaxSlider(CMinMaxWetness, ref wet.x, ref wet.y, 0, 1); GUI.enabled = oldEnabled; globalWetness = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALWETNESS), mat); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_WetnessParams", wet); EditorUtility.SetDirty(mat); } } if (heightWetness && mat.HasProperty("_HeightWetness")) { Vector4 wet = mat.GetVector("_HeightWetness"); EditorGUI.BeginChangeCheck(); wet.x = EditorGUILayout.FloatField(CHeightWetnessHeight, wet.x); wet.y = EditorGUILayout.FloatField(CHeightWetnessContrast, wet.y); wet.z = EditorGUILayout.FloatField(CHeightWetnessFrequency, wet.z); wet.w = EditorGUILayout.FloatField(CHeightWetnessAmplitude, wet.w); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_HeightWetness", wet); EditorUtility.SetDirty(mat); } } // PUDDLES if (puddles && mat.HasProperty("_PuddleParams") && MicroSplatUtilities.DrawRollup("Puddles", true, true)) { Vector4 pudV = mat.GetVector("_PuddleParams"); EditorGUI.BeginChangeCheck(); pudV.x = EditorGUILayout.Slider(CPuddleBlend, pudV.x, 0.01f, 60.0f); EditorGUILayout.BeginHorizontal(); var oldEnabled = GUI.enabled; if (globalPuddles) { GUI.enabled = false; } pudV.y = EditorGUILayout.Slider(CPuddleMax, pudV.y, 0.01f, 1.0f); GUI.enabled = oldEnabled; globalPuddles = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALPUDDLES), mat); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_PuddleParams", pudV); EditorUtility.SetDirty(mat); } } if (rainDrops && mat.HasProperty("_RainDropTexture") && MicroSplatUtilities.DrawRollup("Rain Drops", true, true)) { MicroSplatUtilities.EnforceDefaultTexture(shaderGUI.FindProp("_RainDropTexture", props), "microsplat_def_raindrops"); EditorGUI.BeginChangeCheck(); var rainParams = shaderGUI.FindProp("_RainIntensityScale", props); Vector4 v = rainParams.vectorValue; EditorGUILayout.BeginHorizontal(); var oldEnabled = GUI.enabled; if (globalRain) { GUI.enabled = false; } v.x = EditorGUILayout.Slider(CRainIntensity, v.x, 0, 1); GUI.enabled = oldEnabled; globalRain = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALRAIN), mat); EditorGUILayout.EndHorizontal(); v.y = EditorGUILayout.FloatField(CRainUVScales, v.y); if (EditorGUI.EndChangeCheck()) { rainParams.vectorValue = v; } } // Streams if (streams && mat.HasProperty("_StreamBlend") && MicroSplatUtilities.DrawRollup("Streams", true, true)) { materialEditor.TexturePropertySingleLine(CStreamFoamTex, shaderGUI.FindProp("_StreamNormal", props)); MicroSplatUtilities.EnforceDefaultTexture(shaderGUI.FindProp("_StreamNormal", props), "microsplat_def_streamfoam"); materialEditor.ShaderProperty(shaderGUI.FindProp("_StreamBlend", props), CStreamBlend); EditorGUILayout.BeginHorizontal(); var oldEnabled = GUI.enabled; if (globalStreams) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_StreamMax", props), CMaxStream); GUI.enabled = oldEnabled; globalStreams = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALSTREAMS), mat); EditorGUILayout.EndHorizontal(); Vector4 pudNF = mat.GetVector("_StreamNormalFoam"); EditorGUI.BeginChangeCheck(); pudNF.x = EditorGUILayout.Slider(CStreamNormalBlend, pudNF.x, 0, 1.0f); pudNF.y = EditorGUILayout.Slider(CStreamFoamStr, pudNF.y, 0.0f, 35.0f); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_StreamNormalFoam", pudNF); EditorUtility.SetDirty(mat); } if (mat.HasProperty("_StreamFlowParams")) { EditorGUI.BeginChangeCheck(); Vector4 pudp = mat.GetVector("_StreamFlowParams"); Vector4 pudUV = mat.GetVector("_StreamUVScales"); Vector2 puv = new Vector2(pudUV.x, pudUV.y); puv = EditorGUILayout.Vector2Field(CStreamUVScale, puv); pudp.x = EditorGUILayout.Slider(CStreamRefractionStrength, pudp.x, 0.0f, 0.5f); pudp.w = EditorGUILayout.Slider(CStreamDepthDampen, pudp.w, 0.0f, 1.0f); pudp.y = EditorGUILayout.FloatField(CStreamFlowSpeed, pudp.y); pudp.z = EditorGUILayout.FloatField(CStreamFlowCycle, pudp.z); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_StreamFlowParams", pudp); mat.SetVector("_StreamUVScales", new Vector4(puv.x, puv.y, 0, 0)); EditorUtility.SetDirty(mat); } } if (heightDampStreams && mat.HasProperty("_StreamFades")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_StreamFades", props), CHeightDamp); } } if (lava && mat.HasProperty("_LavaParams2") && MicroSplatUtilities.DrawRollup("Lava", true, true)) { materialEditor.TexturePropertySingleLine(CLavaDiffuse, shaderGUI.FindProp("_LavaDiffuse", props)); MicroSplatUtilities.EnforceDefaultTexture(shaderGUI.FindProp("_LavaDiffuse", props), "microsplat_def_lava_01"); EditorGUI.BeginChangeCheck(); Vector4 lavaUVs = mat.GetVector("_LavaUVScale"); Vector2 luv = new Vector2(lavaUVs.x, lavaUVs.y); luv = EditorGUILayout.Vector2Field(CLavaUVScale, luv); lavaUVs.x = luv.x; lavaUVs.y = luv.y; Vector4 lavaParams = mat.GetVector("_LavaParams"); lavaParams.x = EditorGUILayout.Slider(CLavaBlend, lavaParams.x, 2.0f, 40.0f); lavaParams.y = EditorGUILayout.Slider(CLavaMax, lavaParams.y, 0.0f, 1.0f); lavaParams.z = EditorGUILayout.FloatField(CLavaSpeed, lavaParams.z); lavaParams.w = EditorGUILayout.FloatField(CLavaIntensity, lavaParams.w); Vector4 lavaParams2 = mat.GetVector("_LavaParams2"); lavaParams2.w = EditorGUILayout.Slider(CLavaDarkening, lavaParams2.w, 0.0f, 6.0f); lavaParams2.x = EditorGUILayout.Slider(CLavaDistSize, lavaParams2.x, 0.0f, 0.3f); lavaParams2.y = EditorGUILayout.Slider(CLavaDistRate, lavaParams2.y, 0.0f, 0.08f); lavaParams2.z = EditorGUILayout.Slider(CLavaDistScale, lavaParams2.z, 0.02f, 1.0f); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_LavaParams", lavaParams); mat.SetVector("_LavaParams2", lavaParams2); mat.SetVector("_LavaUVScale", lavaUVs); EditorUtility.SetDirty(mat); } materialEditor.ShaderProperty(shaderGUI.FindProp("_LavaColorLow", props), CLavaColor); materialEditor.ShaderProperty(shaderGUI.FindProp("_LavaColorHighlight", props), CLavaHighlightColor); materialEditor.ShaderProperty(shaderGUI.FindProp("_LavaEdgeColor", props), CLavaEdgeColor); if (mat.IsKeywordEnabled("_TESSDISTANCE") && mat.HasProperty("_LavaDislacementScale")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_LavaDislacementScale", props), CLavaDisplacementScale); } if (heightDampLava && mat.HasProperty("_LavaFades")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_LavaFades", props), CHeightDamp); } } } } }
/// <summary> /// Draw the editor for the shaders options /// </summary> /// <param name="shaderGUI">Shader GU.</param> /// <param name="mat">Mat.</param> /// <param name="materialEditor">Material editor.</param> /// <param name="props">Properties.</param> public abstract void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props);
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (windParticulate != ParticulateMode.None || snowParticulate != ParticulateMode.None || glitter || snowGlitter) { if (MicroSplatUtilities.DrawRollup("Wind Particulate and Glitter") && mat.HasProperty("_GlitterWind")) { var texProp = shaderGUI.FindProp("_GlitterWind", props); MicroSplatUtilities.WarnLinear(texProp.textureValue as Texture2D); materialEditor.TexturePropertySingleLine(CGlitterWind, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_windglitter"); if ((windParticulate != ParticulateMode.None || snowParticulate != ParticulateMode.None) && mat.HasProperty("_WindParticulateRotation")) { EditorGUILayout.BeginHorizontal(); var oldEnabled = GUI.enabled; if (globalWindRotation) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateRotation", props), CWindRotation); GUI.enabled = oldEnabled; globalWindRotation = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALPARTICULATEROTATION), keywords); EditorGUILayout.EndHorizontal(); if (windParticulate != ParticulateMode.None && MicroSplatUtilities.DrawRollup("Wind", true, true) && mat.HasProperty("_WindParticulateColor")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateColor", props), CWindColor); EditorGUILayout.BeginHorizontal(); oldEnabled = GUI.enabled; if (globalWindStrength) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateStrength", props), CWindStrength); GUI.enabled = oldEnabled; globalWindStrength = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALWINDPARTICULATESTRENGTH), keywords); EditorGUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); Vector4 speedPow = shaderGUI.FindProp("_WindParticulateParams", props).vectorValue; speedPow.w = EditorGUILayout.FloatField(CWindScale, speedPow.w); speedPow.x = EditorGUILayout.FloatField(CWindSpeed, speedPow.x); speedPow.y = EditorGUILayout.Slider(CWindContrast, speedPow.y, 0.4f, 4.0f); speedPow.z = EditorGUILayout.FloatField(CWindStretch, speedPow.z); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_WindParticulateParams", props).vectorValue = speedPow; } if (windParticulate == ParticulateMode.ParticulateWithShadows) { EditorGUI.BeginChangeCheck(); Vector4 shadow = shaderGUI.FindProp("_WindParticulateShadow", props).vectorValue; Color shadowColor = shaderGUI.FindProp("_WindParticulateShadowColor", props).colorValue; shadowColor = EditorGUILayout.ColorField(CWindShadowColor, shadowColor); shadow.x = EditorGUILayout.Slider(CWindShadowOffset, shadow.x, 0, 0.1f); shadow.y = EditorGUILayout.Slider(CWindShadowStrength, shadow.y, 0, 2.0f); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_WindParticulateShadow", props).vectorValue = shadow; shaderGUI.FindProp("_WindParticulateShadowColor", props).colorValue = shadowColor; } } if (mat.HasProperty("_WindParticulateHeightMask")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateHeightMask", props), CWindHeightMask); materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateAngleMask", props), CWindAngleMask); if (mat.HasProperty("_WindParticulateUpMask")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_WindParticulateUpMask", props), CUpFilterRange); } } if (mat.HasProperty("_WindEmissive")) { Vector4 windEmis = shaderGUI.FindProp("_WindEmissive", props).vectorValue; EditorGUI.BeginChangeCheck(); windEmis.x = EditorGUILayout.Slider(CWindEmissive, windEmis.x, 0, 1); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_WindEmissive", props).vectorValue = windEmis; } } if (mat.HasProperty("_WindParticulateOcclusionStrength")) { EditorGUI.BeginChangeCheck(); float ao = mat.GetFloat("_WindParticulateOcclusionStrength"); ao = EditorGUILayout.Slider(COcclusionStrength, ao, 0, 1); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_WindParticulateOcclusionStrength", props).floatValue = ao; } } } if (snowParticulate != ParticulateMode.None && MicroSplatUtilities.DrawRollup("Snow Particulate Settings", true, true) && mat.HasProperty("_SnowParticulateColor")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowParticulateColor", props), CWindColor); EditorGUILayout.BeginHorizontal(); oldEnabled = GUI.enabled; if (globalSnowStrength) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowParticulateStrength", props), CWindStrength); GUI.enabled = oldEnabled; globalSnowStrength = DrawGlobalToggle(GetFeatureName(DefineFeature._GLOBALSNOWPARTICULATESTRENGTH), keywords); EditorGUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); Vector4 speedPow = shaderGUI.FindProp("_SnowParticulateParams", props).vectorValue; speedPow.w = EditorGUILayout.FloatField(CWindScale, speedPow.w); speedPow.x = EditorGUILayout.FloatField(CWindSpeed, speedPow.x); speedPow.y = EditorGUILayout.Slider(CWindContrast, speedPow.y, 0.4f, 4.0f); speedPow.z = EditorGUILayout.FloatField(CWindStretch, speedPow.z); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowParticulateParams", props).vectorValue = speedPow; } if (snowParticulate == ParticulateMode.ParticulateWithShadows) { EditorGUI.BeginChangeCheck(); Vector4 shadow = shaderGUI.FindProp("_SnowParticulateShadow", props).vectorValue; Color shadowColor = shaderGUI.FindProp("_SnowParticulateShadowColor", props).colorValue; shadowColor = EditorGUILayout.ColorField(CWindShadowColor, shadowColor); shadow.x = EditorGUILayout.Slider(CWindShadowOffset, shadow.x, 0, 0.1f); shadow.y = EditorGUILayout.Slider(CWindShadowStrength, shadow.y, 0, 2.0f); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowParticulateShadow", props).vectorValue = shadow; shaderGUI.FindProp("_SnowParticulateShadowColor", props).colorValue = shadowColor; } } if (mat.HasProperty("_SnowParticulateHeightMask")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowParticulateHeightMask", props), CWindHeightMask); materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowParticulateAngleMask", props), CWindAngleMask); if (mat.HasProperty("_SnowParticulateUpMask")) { materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowParticulateUpMask", props), CUpFilterRange); } } if (mat.HasProperty("_WindEmissive")) { Vector4 windEmis = shaderGUI.FindProp("_WindEmissive", props).vectorValue; EditorGUI.BeginChangeCheck(); windEmis.y = EditorGUILayout.Slider(CWindEmissive, windEmis.y, 0, 1); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_WindEmissive", props).vectorValue = windEmis; } } if (mat.HasProperty("_SnowParticulateOcclusionStrength")) { EditorGUI.BeginChangeCheck(); float ao = mat.GetFloat("_SnowParticulateOcclusionStrength"); ao = EditorGUILayout.Slider(COcclusionStrength, ao, 0, 1); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowParticulateOcclusionStrength", props).floatValue = ao; } } } } if ((glitter || snowGlitter)) { if (glitter && mat.HasProperty("_GlitterUVScale")) { if (MicroSplatUtilities.DrawRollup("Glitter", true, true)) { var scale = shaderGUI.FindProp("_GlitterUVScale", props); Vector2 scl = scale.vectorValue; EditorGUI.BeginChangeCheck(); scl = EditorGUILayout.Vector2Field(CGlitterUVScale, scl); if (EditorGUI.EndChangeCheck()) { scale.vectorValue = scl; } materialEditor.ShaderProperty(shaderGUI.FindProp("_GlitterGraininess", props), CGlitterGraininess); materialEditor.ShaderProperty(shaderGUI.FindProp("_GlitterShininess", props), CGlitterShininess); materialEditor.ShaderProperty(shaderGUI.FindProp("_GlitterViewDep", props), CGlitterViewDep); materialEditor.ShaderProperty(shaderGUI.FindProp("_GlitterStrength", props), CGlitterStrength); materialEditor.ShaderProperty(shaderGUI.FindProp("_GlitterThreshold", props), CGlitterThreshold); if (mat.HasProperty("_GlitterDistFade")) { Vector4 fade = mat.GetVector("_GlitterDistFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlitterDistFade", fade); EditorUtility.SetDirty(mat); } } } } if (snowGlitter && mat.HasProperty("_SnowGlitterUVScale")) { if (MicroSplatUtilities.DrawRollup("Snow Glitter", true, true)) { var scale = shaderGUI.FindProp("_SnowGlitterUVScale", props); Vector2 scl = scale.vectorValue; EditorGUI.BeginChangeCheck(); scl = EditorGUILayout.Vector2Field(CGlitterUVScale, scl); if (EditorGUI.EndChangeCheck()) { scale.vectorValue = scl; } materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowGlitterGraininess", props), CGlitterGraininess); materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowGlitterShininess", props), CGlitterShininess); materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowGlitterViewDep", props), CGlitterViewDep); materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowGlitterStrength", props), CGlitterStrength); materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowGlitterThreshold", props), CGlitterThreshold); if (mat.HasProperty("_SnowGlitterDistFade")) { Vector4 fade = mat.GetVector("_SnowGlitterDistFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_SnowGlitterDistFade", fade); EditorUtility.SetDirty(mat); } } } } } } } }
public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUI.BeginChangeCheck(); if (DoConvertGUI(t)) { return; } if (t.templateMaterial == null) { return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); EditorUtility.SetDirty(t); MicroSplatObject.SyncAll(); } if (t.keywordSO == null) { t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); EditorUtility.SetDirty(t); } EditorGUI.BeginChangeCheck(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled("_PROCEDURALTEXTURE") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTGRADIENT") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTHSV")) { var old = t.procTexCfg; t.procTexCfg = MicroSplatProceduralTexture.FindOrCreateProceduralConfig(t.templateMaterial); if (old != t.procTexCfg) { EditorUtility.SetDirty(t); MicroSplatObject.SyncAll(); } } #endif #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif DoPerPixelNormalGUI(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCCAVITY)) || t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCFLOW))) { DoCavityMapGUI(); } #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, CCustomSplat0, ref t.customControl0, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat1, ref t.customControl1, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat2, ref t.customControl2, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat3, ref t.customControl3, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat4, ref t.customControl4, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat5, ref t.customControl5, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat6, ref t.customControl6, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat7, ref t.customControl7, "_CUSTOMSPLATTEXTURES"); // perpixel normal MicroSplatUtilities.DrawTextureField(t, perPixelNormal, ref t.perPixelNormal, "_PERPIXELNORMAL"); // global texture overrides #if __MICROSPLAT_GLOBALTEXTURE__ MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); MicroSplatUtilities.DrawTextureField(t, geoSAOMOverride, ref t.globalSAOMOverride, "_GLOBALSMOOTHAOMETAL"); MicroSplatUtilities.DrawTextureField(t, geoEmisOverride, ref t.globalEmisOverride, "_GLOBALEMIS"); #endif #if __MICROSPLAT_SNOW__ MicroSplatUtilities.DrawTextureField(t, snowMaskOverride, ref t.snowMaskOverride, "_SNOWMASK"); #endif #if __MICROSPLAT_ALPHAHOLE__ // alpha hole override MicroSplatUtilities.DrawTextureField(t, clipMapOverride, ref t.clipMap, "_ALPHAHOLETEXTURE"); #endif #if (VEGETATION_STUDIO || VEGETATION_STUDIO_PRO) // vsstudio overrides MicroSplatUtilities.DrawTextureField(t, CVSGrassMap, ref t.vsGrassMap, "_VSGRASSMAP"); MicroSplatUtilities.DrawTextureField(t, CVSShadowMap, ref t.vsShadowMap, "_VSSHADOWMAP"); #endif #if __MICROSPLAT_PROCTEX__ MicroSplatUtilities.DrawTextureField(t, biomeOverride, ref t.procBiomeMask, "_PROCEDURALTEXTURE"); #endif #if __MICROSPLAT_STREAMS__ MicroSplatUtilities.DrawTextureField(t, streamOverride, ref t.streamTexture, "_WETNESS", "_PUDDLES", "_STREAMS", "_LAVA", false); #endif #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailGUI(t); #endif if (t.propData == null && t.templateMaterial != null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); if (t.propData == null) { // this should really never happen, but users seem to have issues with unassigned propData's a lot. I think // this is from external tools like MapMagic not creating it, but the above call should create it. EditorGUILayout.HelpBox("PropData is null, please assign", MessageType.Error); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; } } if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); ImportExportGUI(); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailTooset(t); #endif if (MicroSplatUtilities.DrawRollup("Debug", false, true)) { EditorGUI.indentLevel += 2; EditorGUILayout.HelpBox("These should not need to be edited unless something funky has happened. They are automatically managed by MicroSplat.", MessageType.Info); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; #if __MICROSPLAT_PROCTEX__ t.procTexCfg = EditorGUILayout.ObjectField("Procedural Config", t.procTexCfg, typeof(MicroSplatProceduralTextureConfig), false) as MicroSplatProceduralTextureConfig; #endif t.keywordSO = EditorGUILayout.ObjectField("Keywords", t.keywordSO, typeof(MicroSplatKeywords), false) as MicroSplatKeywords; t.blendMat = EditorGUILayout.ObjectField(CBlendMat, t.blendMat, typeof(Material), false) as Material; t.addPass = EditorGUILayout.ObjectField("Add Pass", t.addPass, typeof(Shader), false) as Shader; EditorGUI.indentLevel -= 2; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } }
public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; if (t.templateMaterial == null) { if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain>(); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs[i].GetComponent <Terrain>(); if (ter != null) { terrains.Add(ter); } Terrain[] trs = objs[i].GetComponentsInChildren <Terrain>(); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs[x])) { terrains.Add(trs[x]); } } } // setup this terrain Terrain terrain = t.GetComponent <Terrain>(); t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); #if UNITY_2018_3_OR_NEWER if (terrain.terrainData.terrainLayers.Length > 0) { var uvScale = terrain.terrainData.terrainLayers[0].tileSize; var uvOffset = terrain.terrainData.terrainLayers[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #else if (terrain.terrainData.splatPrototypes.Length > 0) { var uvScale = terrain.terrainData.splatPrototypes[0].tileSize; var uvOffset = terrain.terrainData.splatPrototypes[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #endif // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains[i]; var mgr = nt.GetComponent <MicroSplatTerrain>(); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain>(); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); } MicroSplatTerrain.SyncAll(); return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); EditorUtility.SetDirty(t); } if (t.keywordSO == null) { t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); EditorUtility.SetDirty(t); } EditorGUI.BeginChangeCheck(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled("_PROCEDURALTEXTURE") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTGRADIENT") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTHSV")) { var old = t.procTexCfg; t.procTexCfg = MicroSplatProceduralTexture.FindOrCreateProceduralConfig(t.templateMaterial); if (old != t.procTexCfg) { EditorUtility.SetDirty(t); } } #endif #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif DoPerPixelNormalGUI(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCCAVITY)) || t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCFLOW))) { DoCavityMapGUI(); } #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, CCustomSplat0, ref t.customControl0, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat1, ref t.customControl1, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat2, ref t.customControl2, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat3, ref t.customControl3, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat4, ref t.customControl4, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat5, ref t.customControl5, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat6, ref t.customControl6, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat7, ref t.customControl7, "_CUSTOMSPLATTEXTURES"); // perpixel normal MicroSplatUtilities.DrawTextureField(t, perPixelNormal, ref t.perPixelNormal, "_PERPIXELNORMAL"); // global texture overrides #if __MICROSPLAT_GLOBALTEXTURE__ MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); MicroSplatUtilities.DrawTextureField(t, geoSAOMOverride, ref t.globalSAOMOverride, "_GLOBALSMOOTHAOMETAL"); MicroSplatUtilities.DrawTextureField(t, geoEmisOverride, ref t.globalEmisOverride, "_GLOBALEMIS"); #endif #if __MICROSPLAT_ALPHAHOLE__ // alpha hole override MicroSplatUtilities.DrawTextureField(t, clipMapOverride, ref t.clipMap, "_ALPHAHOLETEXTURE"); #endif #if (VEGETATION_STUDIO || VEGETATION_STUDIO_PRO) // vsstudio overrides MicroSplatUtilities.DrawTextureField(t, CVSGrassMap, ref t.vsGrassMap, "_VSGRASSMAP"); MicroSplatUtilities.DrawTextureField(t, CVSShadowMap, ref t.vsShadowMap, "_VSSHADOWMAP"); #endif #if __MICROSPLAT_PROCTEX__ MicroSplatUtilities.DrawTextureField(t, biomeOverride, ref t.procBiomeMask, "_PROCEDURALTEXTURE"); #endif #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailGUI(t); #endif if (t.propData == null && t.templateMaterial != null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); if (t.propData == null) { // this should really never happen, but users seem to have issues with unassigned propData's a lot. I think // this is from external tools like MapMagic not creating it, but the above call should create it. EditorGUILayout.HelpBox("PropData is null, please assign", MessageType.Error); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; } } if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); ImportExportGUI(); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailTooset(t); #endif if (MicroSplatUtilities.DrawRollup("Debug", false, true)) { EditorGUI.indentLevel += 2; EditorGUILayout.HelpBox("These should not need to be edited unless something funky has happened. They are automatically managed by MicroSplat.", MessageType.Info); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; #if __MICROSPLAT_PROCTEX__ t.procTexCfg = EditorGUILayout.ObjectField("Procedural Config", t.procTexCfg, typeof(MicroSplatProceduralTextureConfig), false) as MicroSplatProceduralTextureConfig; #endif t.keywordSO = EditorGUILayout.ObjectField("Keywords", t.keywordSO, typeof(MicroSplatKeywords), false) as MicroSplatKeywords; t.blendMat = EditorGUILayout.ObjectField(CBlendMat, t.blendMat, typeof(Material), false) as Material; t.terrainDesc = EditorGUILayout.ObjectField("Terrain Descriptor", t.terrainDesc, typeof(Texture2D), false) as Texture2D; t.perPixelNormal = EditorGUILayout.ObjectField("Normal Data", t.perPixelNormal, typeof(Texture2D), false) as Texture2D; t.addPass = EditorGUILayout.ObjectField("Add Pass", t.addPass, typeof(Shader), false) as Shader; EditorGUI.indentLevel -= 2; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (detailNoise) { if (MicroSplatUtilities.DrawRollup("Detail Noise")) { if (mat.HasProperty("_DetailNoise")) { var texProp = shaderGUI.FindProp("_DetailNoise", props); MicroSplatUtilities.WarnLinear(texProp.textureValue as Texture2D); materialEditor.TexturePropertySingleLine(CDetailNoiseTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_detail_noise"); Vector4 scaleStr = shaderGUI.FindProp("_DetailNoiseScaleStrengthFade", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Strength", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Fade Distance", scaleStr.z); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_DetailNoiseScaleStrengthFade", props).vectorValue = newScaleStr; } } } } if (distanceNoise) { if (MicroSplatUtilities.DrawRollup("Distance Noise")) { if (mat.HasProperty("_DistanceNoise")) { var texProp = shaderGUI.FindProp("_DistanceNoise", props); MicroSplatUtilities.WarnLinear(texProp.textureValue as Texture2D); materialEditor.TexturePropertySingleLine(CDistanceNoiseTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_detail_noise"); Vector4 scaleStr = shaderGUI.FindProp("_DistanceNoiseScaleStrengthFade", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Strength", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Fade Start", scaleStr.z); newScaleStr.w = EditorGUILayout.FloatField("Fade End", scaleStr.w); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_DistanceNoiseScaleStrengthFade", props).vectorValue = newScaleStr; } } } } if (distanceResample != DistanceResampleMode.None && mat.HasProperty("_ResampleDistanceParams")) { if (MicroSplatUtilities.DrawRollup("Distance Resample")) { if (distanceResampleFade == DistanceResampleFade.CrossFade && mat.HasProperty("_ResampleDistanceParams")) { EditorGUI.BeginChangeCheck(); Vector4 vec = mat.GetVector("_ResampleDistanceParams"); vec.x = EditorGUILayout.FloatField("Resample UV Scale", vec.x); Vector2 xy = EditorGUILayout.Vector2Field("Resample Begin/End", new Vector2(vec.y, vec.z)); if (EditorGUI.EndChangeCheck()) { vec.y = xy.x; vec.z = xy.y; mat.SetVector("_ResampleDistanceParams", vec); EditorUtility.SetDirty(mat); } } else { EditorGUI.BeginChangeCheck(); Vector4 vec = mat.GetVector("_ResampleDistanceParams"); vec.x = EditorGUILayout.FloatField("Resample UV Scale", vec.x); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_ResampleDistanceParams", vec); EditorUtility.SetDirty(mat); } } if (distanceResampleFade == DistanceResampleFade.Constant || distanceResampleFade == DistanceResampleFade.Noise) { var prop = shaderGUI.FindProp("_DistanceResampleConstant", props); materialEditor.RangeProperty(prop, "Distance Resample Constant"); } if (distanceResampleFade == DistanceResampleFade.Noise) { var prop = shaderGUI.FindProp("_DistanceResampleNoiseParams", props); Vector2 vals = new Vector2(prop.vectorValue.x, prop.vectorValue.y); EditorGUI.BeginChangeCheck(); vals = EditorGUILayout.Vector2Field("Noise Freq and Amp", vals); if (EditorGUI.EndChangeCheck()) { prop.vectorValue = new Vector4(vals.x, vals.y, 0, 0); } } } } if (noiseChannelCount != NormalNoiseChannels.Off && mat.HasProperty("_NormalNoiseScaleStrength")) { if (MicroSplatUtilities.DrawRollup("Normal Noise")) { { var texProp = shaderGUI.FindProp("_NormalNoise", props); materialEditor.TexturePropertySingleLine(CNormalNoiseTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_detail_normal_01"); Vector4 scaleStr = shaderGUI.FindProp("_NormalNoiseScaleStrength", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_NormalNoiseScaleStrength", props).vectorValue = newScaleStr; } } if (noiseChannelCount == NormalNoiseChannels.Two || noiseChannelCount == NormalNoiseChannels.Three) { if (mat.HasProperty("_NormalNoiseScaleStrength2")) { var texProp = shaderGUI.FindProp("_NormalNoise2", props); materialEditor.TexturePropertySingleLine(CNormalNoiseTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_detail_normal_02"); Vector4 scaleStr = shaderGUI.FindProp("_NormalNoiseScaleStrength2", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_NormalNoiseScaleStrength2", props).vectorValue = newScaleStr; } } } if (noiseChannelCount == NormalNoiseChannels.Three) { if (mat.HasProperty("_NormalNoiseScaleStrength3")) { var texProp = shaderGUI.FindProp("_NormalNoise3", props); materialEditor.TexturePropertySingleLine(CNormalNoiseTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_detail_normal_03"); Vector4 scaleStr = shaderGUI.FindProp("_NormalNoiseScaleStrength3", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_NormalNoiseScaleStrength3", props).vectorValue = newScaleStr; } } } } } if (antiTileOptions != 0) { if (MicroSplatUtilities.DrawRollup("Anti Tile Array") && mat.HasProperty("_AntiTileArray")) { var array = shaderGUI.FindProp("_AntiTileArray", props); materialEditor.TexturePropertySingleLine(CAntiTileArray, array); if (mat.HasProperty("_AntiTileNormalNoiseScaleStr") && (((int)antiTileOptions & (int)AntiTileOptions.NoiseNormal) != 0)) { Vector4 scaleStr = shaderGUI.FindProp("_AntiTileNormalNoiseScaleStr", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Normal Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Normal Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_AntiTileNormalNoiseScaleStr", props).vectorValue = newScaleStr; } EditorGUILayout.Space(); } if (mat.HasProperty("_AntiTileDetailNoiseScaleFadeStr") && (((int)antiTileOptions & (int)AntiTileOptions.DetailNoise) != 0)) { Vector4 scaleStr = shaderGUI.FindProp("_AntiTileDetailNoiseScaleFadeStr", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Detail Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Detail Fade Distance", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Detail Strength", scaleStr.z); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_AntiTileDetailNoiseScaleFadeStr", props).vectorValue = newScaleStr; } EditorGUILayout.Space(); } if (mat.HasProperty("_AntiTileDistanceNoiseScaleFadeStr") && (((int)antiTileOptions & (int)AntiTileOptions.DistanceNoise) != 0)) { Vector4 scaleStr = shaderGUI.FindProp("_AntiTileDistanceNoiseScaleFadeStr", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Distance Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Distance Fade Start", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Distance Fade End", scaleStr.z); newScaleStr.w = EditorGUILayout.FloatField("Distance Strength", scaleStr.w); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_AntiTileDistanceNoiseScaleFadeStr", props).vectorValue = newScaleStr; } } } } }
bool DoConvertGUI(MicroSplatTerrain t) { if (t.templateMaterial == null) { InitConvertConfigs(); using (new GUILayout.VerticalScope(GUI.skin.box)) { EditorGUILayout.LabelField("Select any integrations you want to add:"); // integrations for (int i = 0; i < integrationConfigs.Count; ++i) { var ic = integrationConfigs [i]; if (!ic.assetInstalled) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(ic.name, GUILayout.Width(120)); EditorGUILayout.LabelField("Not Installed", GUILayout.Width(120)); if (GUILayout.Button("Link", GUILayout.Width(120))) { Application.OpenURL(ic.assetLink); } EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.BeginHorizontal(); ic.include = EditorGUILayout.Toggle(ic.include, GUILayout.Width(20)); EditorGUILayout.LabelField(ic.name); EditorGUILayout.EndHorizontal(); if (ic.include && ic.missingModules.Count > 0) { using (new GUILayout.VerticalScope(GUI.skin.box)) { EditorGUILayout.HelpBox("Some MicroSplat modules requested by this module are not installed. Some or all features of the integration will not be active.", MessageType.Warning); for (int j = 0; j < ic.missingModules.Count; ++j) { var m = ic.missingModules [j]; DrawMissingModule(m); } } } } } if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain> (); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs [i].GetComponent <Terrain> (); if (ter != null) { terrains.Add(ter); } Terrain [] trs = objs [i].GetComponentsInChildren <Terrain> (); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs [x])) { terrains.Add(trs [x]); } } } Terrain terrain = t.GetComponent <Terrain> (); int texcount = terrain.terrainData.terrainLayers.Length; List <string> keywords = new List <string> (defaultKeywords); // set initial render pipleine var pipeline = MicroSplatUtilities.DetectPipeline(); if (pipeline == MicroSplatUtilities.PipelineType.HDPipeline) { keywords.Add("_MSRENDERLOOP_UNITYHD"); } else if (pipeline == MicroSplatUtilities.PipelineType.UniversalPipeline) { keywords.Add("_MSRENDERLOOP_UNITYLD"); } // Because new users won't read the manual or read settings before they act, we don't clamp the texture count // down for maximum performance. Way to many support requests complaining of black terrain after adding textures because // they didn't realize they needed to up the max texture count. So now, 16 minimum. This is why we can't have nice things. /* * if (texcount <= 4) * { * keywords.Add ("_MAX4TEXTURES"); * } * else if (texcount <= 8) * { * keywords.Add ("_MAX8TEXTURES"); * } * else if (texcount <= 12) * { * keywords.Add ("_MAX12TEXTURES"); * } */ if (texcount > 16 && texcount <= 20) { keywords.Add("_MAX20TEXTURES"); } else if (texcount <= 24) { keywords.Add("_MAX24TEXTURES"); } else if (texcount <= 28) { keywords.Add("_MAX28TEXTURES"); } else if (texcount > 28) { keywords.Add("_MAX32TEXTURES"); } for (int i = 0; i < integrationConfigs.Count; ++i) { var ic = integrationConfigs [i]; if (ic.include) { keywords.AddRange(ic.keywords); } } // setup this terrain t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain, keywords.ToArray()); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); EditorUtility.SetDirty(t); if (terrain.terrainData.terrainLayers != null) { if (terrain.terrainData.terrainLayers.Length > 0) { Vector2 min = new Vector2(99999, 99999); Vector2 max = Vector2.zero; for (int x = 0; x < terrain.terrainData.terrainLayers.Length; ++x) { var uv = terrain.terrainData.terrainLayers [x].tileSize; if (min.x > uv.x) { min.x = uv.x; } if (min.y > uv.y) { min.y = uv.y; } if (max.x < uv.x) { max.x = uv.x; } if (max.y < uv.y) { max.y = uv.y; } } Vector2 average = Vector2.Lerp(min, max, 0.5f); // use per texture UVs instead.. float diff = Vector2.Distance(min, max); if (diff > 0.1) { keywords.Add("_PERTEXUVSCALEOFFSET"); // if the user has widely different UVs, use the LOD sampler. This is because the gradient mode blends between mip levels, // which looks bad with hugely different UVs. I still don't understand why people do this kind of crap though, ideally // your UVs should not differ per texture, and if so, not by much.. if (diff > 10) { Debug.LogWarning("Terrain has wildly varing UV scales, it's best to keep consistent texture resolution. "); } if (!keywords.Contains("_USEGRADMIP")) { keywords.Add("_USEGRADMIP"); } Vector4 scaleOffset = new Vector4(1, 1, 0, 0); t.templateMaterial.SetVector("_UVScale", scaleOffset); var propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); for (int x = 0; x < terrain.terrainData.terrainLayers.Length; ++x) { var uvScale = terrain.terrainData.terrainLayers [x].tileSize; var uvOffset = terrain.terrainData.terrainLayers [x].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvScale.x = Mathf.RoundToInt(uvScale.x); uvScale.y = Mathf.RoundToInt(uvScale.y); propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVScale, uvScale); propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVOffset, Vector2.zero); } for (int x = terrain.terrainData.terrainLayers.Length; x < 32; ++x) { propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVScale, average); propData.SetValue(x, MicroSplatPropData.PerTexVector2.SplatUVOffset, Vector2.zero); } // must init the data, or the editor will write over it. propData.SetValue(0, 15, Color.white); EditorUtility.SetDirty(propData); t.templateMaterial.SetVector("_TriplanarUVScale", new Vector4( 10.0f / t.terrain.terrainData.size.x, 10.0f / t.terrain.terrainData.size.x, 0, 0)); } else { var uvScale = terrain.terrainData.terrainLayers [0].tileSize; var uvOffset = terrain.terrainData.terrainLayers [0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); t.templateMaterial.SetVector("_TriplanarUVScale", new Vector4( 10.0f / t.terrain.terrainData.size.x, 10.0f / t.terrain.terrainData.size.x, 0, 0)); } } } // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains [i]; var mgr = nt.GetComponent <MicroSplatTerrain> (); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain> (); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); t.keywordSO.keywords.Clear(); t.keywordSO.keywords = new List <string> (keywords); // force recompile, so that basemap shader name gets reset correctly.. MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler(); comp.Compile(t.templateMaterial); // for some reason, often when people create terrains with Gaia but this is unconfirmed, // if instancing is set, the terrain will not draw until a shader feature is toggled. // So for now, turn off instancing when doing conversion. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains [i]; nt.drawInstanced = false; } MicroSplatTerrain.SyncAll(); /* * // turn on draw instanced if enabled and tessellation is disabled, unless render loop is LWRP/URP in which case it does work.. * if (t.keywordSO != null && (!t.keywordSO.IsKeywordEnabled("_TESSDISTANCE") || t.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD"))) * { * for (int i = 0; i < terrains.Count; ++i) * { * var nt = terrains [i]; * var mgr = nt.GetComponent<MicroSplatTerrain> (); * if (mgr != null && mgr.keywordSO != null && !mgr.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD")) * { * nt.drawInstanced = true; * } * } * } */ return(true); } } } return(false); }
bool DoConvertGUI(MicroSplatTerrain t) { if (t.templateMaterial == null) { InitConvertConfigs(); using (new GUILayout.VerticalScope(GUI.skin.box)) { EditorGUILayout.LabelField("Select a Template:"); EditorGUILayout.BeginHorizontal(); for (int i = 0; i < convertConfigs.Count; ++i) { var c = convertConfigs [i]; if (DrawConvertButton(c, i == selectedConvertConfig)) { selectedConvertConfig = i; } } EditorGUILayout.EndHorizontal(); var selectedConfig = convertConfigs [selectedConvertConfig]; if (selectedConfig.missingModules.Count > 0) { EditorGUILayout.HelpBox("You are missing some MicroSplat modules needed by this template. The preset may still be used but some features will not be enabled. Missing modules are listed below:", MessageType.Warning); for (int i = 0; i < selectedConfig.missingModules.Count; ++i) { var m = selectedConfig.missingModules [i]; DrawMissingModule(m); } } EditorGUILayout.LabelField("Select any integrations you want to add:"); // integrations for (int i = 0; i < integrationConfigs.Count; ++i) { var ic = integrationConfigs [i]; if (!ic.assetInstalled) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField(ic.name, GUILayout.Width(120)); EditorGUILayout.LabelField("Not Installed", GUILayout.Width(120)); if (GUILayout.Button("Link", GUILayout.Width(120))) { Application.OpenURL(ic.assetLink); } EditorGUILayout.EndHorizontal(); } else { EditorGUILayout.BeginHorizontal(); ic.include = EditorGUILayout.Toggle(ic.include, GUILayout.Width(20)); EditorGUILayout.LabelField(ic.name); EditorGUILayout.EndHorizontal(); if (ic.include && ic.missingModules.Count > 0) { using (new GUILayout.VerticalScope(GUI.skin.box)) { EditorGUILayout.HelpBox("Some MicroSplat modules requested by this module are not installed. Some or all features of the integration will not be active.", MessageType.Warning); for (int j = 0; j < ic.missingModules.Count; ++j) { var m = ic.missingModules [j]; DrawMissingModule(m); } } } } } if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain> (); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs [i].GetComponent <Terrain> (); if (ter != null) { terrains.Add(ter); } Terrain [] trs = objs [i].GetComponentsInChildren <Terrain> (); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs [x])) { terrains.Add(trs [x]); } } } Terrain terrain = t.GetComponent <Terrain> (); int texcount = 16; #if UNITY_2018_3_OR_NEWER texcount = terrain.terrainData.terrainLayers.Length; #else texcount = terrain.terrainData.splatPrototypes.Length; #endif List <string> keywords = new List <string> (selectedConfig.keywords); if (texcount <= 4) { keywords.Add("_MAX4TEXTURES"); } else if (texcount <= 8) { keywords.Add("_MAX8TEXTURES"); } else if (texcount <= 12) { keywords.Add("_MAX12TEXTURES"); } else if (texcount <= 20) { keywords.Add("_MAX20TEXTURES"); } else if (texcount <= 24) { keywords.Add("_MAX24TEXTURES"); } else if (texcount <= 28) { keywords.Add("_MAX28TEXTURES"); } else if (texcount > 28) { keywords.Add("_MAX32TEXTURES"); } for (int i = 0; i < integrationConfigs.Count; ++i) { var ic = integrationConfigs [i]; if (ic.include) { keywords.AddRange(ic.keywords); } } // setup this terrain t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain, keywords.ToArray()); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); #if UNITY_2018_3_OR_NEWER if (terrain.terrainData.terrainLayers.Length > 0) { var uvScale = terrain.terrainData.terrainLayers[0].tileSize; var uvOffset = terrain.terrainData.terrainLayers[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #else if (terrain.terrainData.splatPrototypes.Length > 0) { var uvScale = terrain.terrainData.splatPrototypes [0].tileSize; var uvOffset = terrain.terrainData.splatPrototypes [0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #endif // we need to set a few things on the material if certain features are enabled. // Test for property existence as module might not be installed and feature was culled. if (System.Array.Exists(selectedConfig.keywords, x => x == "_TRIPLANAR")) { if (t.templateMaterial.HasProperty("_TriplanarUVScale")) { t.templateMaterial.SetVector("_TriplanarUVScale", new Vector4(0.25f, 0.25f, 0, 0)); } } if (System.Array.Exists(selectedConfig.keywords, x => x == "_NORMALNOISE")) { if (t.templateMaterial.HasProperty("_NormalNoise")) { t.templateMaterial.SetTexture("_NormalNoise", MicroSplatUtilities.GetAutoTexture("microsplat_def_detail_normal_01")); } } // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains [i]; var mgr = nt.GetComponent <MicroSplatTerrain> (); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain> (); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); t.keywordSO.keywords.Clear(); t.keywordSO.keywords = new List <string> (keywords); // force recompile, so that basemap shader name gets reset correctly.. MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler(); comp.Compile(t.templateMaterial); MicroSplatTerrain.SyncAll(); // trun on draw instanced if enabled and tessellation is disabled, unless render loop is LWRP/URP in which case it does work.. #if UNITY_2018_3_OR_NEWER if (t.keywordSO != null && (!t.keywordSO.IsKeywordEnabled("_TESSDISTANCE") || t.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD"))) { for (int i = 0; i < terrains.Count; ++i) { var nt = terrains [i]; var mgr = nt.GetComponent <MicroSplatTerrain> (); if (mgr != null && mgr.keywordSO != null && !mgr.keywordSO.IsKeywordEnabled("_MSRENDERLOOP_UNITYLD")) { nt.drawInstanced = true; } } } #endif return(true); } } } return(false); }
public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } if (t.templateMaterial == null) { if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain>(); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs[i].GetComponent <Terrain>(); if (ter != null) { terrains.Add(ter); } Terrain[] trs = objs[i].GetComponentsInChildren <Terrain>(); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs[x])) { terrains.Add(trs[x]); } } } // setup this terrain Terrain terrain = t.GetComponent <Terrain>(); t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); bool perTexScaleOffset = false; if (terrain.terrainData.splatPrototypes.Length > 0) { var uvScale = terrain.terrainData.splatPrototypes[0].tileSize; var uvOffset = terrain.terrainData.splatPrototypes[0].tileOffset; for (int i = 1; i < terrain.terrainData.splatPrototypes.Length; ++i) { if (uvScale != terrain.terrainData.splatPrototypes[0].tileSize || uvOffset != terrain.terrainData.splatPrototypes[0].tileOffset) { perTexScaleOffset = true; } } if (!perTexScaleOffset) { uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } } if (perTexScaleOffset) { t.templateMaterial.SetVector("_UVScale", new Vector4(1, 1, 0, 0)); t.templateMaterial.EnableKeyword("_PERTEXUVSCALE"); t.templateMaterial.EnableKeyword("_PERTEXUVOFFSET"); var propTex = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); // set per tex props for each texture for (int i = 0; i < terrain.terrainData.splatPrototypes.Length; ++i) { var uvScale = terrain.terrainData.splatPrototypes[i].tileSize; var uvOffset = terrain.terrainData.splatPrototypes[i].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Color c = new Color(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); propTex.SetValue(i, 0, c); } } // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains[i]; var mgr = nt.GetComponent <MicroSplatTerrain>(); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain>(); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); } MicroSplatTerrain.SyncAll(); return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); } #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); MicroSplatUtilities.DrawTextureField(t, AdvDetailControl, ref t.advDetailControl, "_ADVANCED_DETAIL"); if (t.templateMaterial.IsKeywordEnabled("_VSGRASSMAP")) { EditorGUI.BeginChangeCheck(); t.vsGrassMap = EditorGUILayout.ObjectField(CVSGrassMap, t.vsGrassMap, typeof(Texture2D), false) as Texture2D; if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } } if (t.templateMaterial.IsKeywordEnabled("_VSSHADOWMAP")) { EditorGUI.BeginChangeCheck(); t.vsShadowMap = EditorGUILayout.ObjectField(CVSShadowMap, t.vsShadowMap, typeof(Texture2D), false) as Texture2D; if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (snow && mat.HasProperty("_SnowParams") && MicroSplatUtilities.DrawRollup("Snow")) { var snowDiff = shaderGUI.FindProp("_SnowDiff", props); var snowNorm = shaderGUI.FindProp("_SnowNormal", props); materialEditor.TexturePropertySingleLine(CDiffTex, snowDiff); materialEditor.TexturePropertySingleLine(CNormTex, snowNorm); MicroSplatUtilities.EnforceDefaultTexture(snowDiff, "microsplat_def_snow_diff"); MicroSplatUtilities.EnforceDefaultTexture(snowNorm, "microsplat_def_snow_normsao"); if (mat.HasProperty("_SnowUVScales")) { Vector4 snowUV = shaderGUI.FindProp("_SnowUVScales", props).vectorValue; EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("UV Scale"); snowUV.x = EditorGUILayout.FloatField(snowUV.x); snowUV.y = EditorGUILayout.FloatField(snowUV.y); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowUVScales", props).vectorValue = snowUV; EditorUtility.SetDirty(mat); } } if (snowFootsteps && mat.HasProperty("_SnowTrackDiff")) { var trackDiff = shaderGUI.FindProp("_SnowTrackDiff", props); var trackNorm = shaderGUI.FindProp("_SnowTrackNSAO", props); materialEditor.TexturePropertySingleLine(CFootstepDiffTex, trackDiff); materialEditor.TexturePropertySingleLine(CFootstepNormTex, trackNorm); MicroSplatUtilities.EnforceDefaultTexture(trackDiff, "microsplat_def_snow_footstep_diff"); MicroSplatUtilities.EnforceDefaultTexture(trackNorm, "microsplat_def_snow_footstep_normsao"); Vector4 snowUV = shaderGUI.FindProp("_SnowFootstepUVScales", props).vectorValue; EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("Footstep UV Scale"); snowUV.x = EditorGUILayout.FloatField(snowUV.x); snowUV.y = EditorGUILayout.FloatField(snowUV.y); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowFootstepUVScales", props).vectorValue = snowUV; EditorUtility.SetDirty(mat); } } // influence, erosion, crystal, melt Vector4 p1 = shaderGUI.FindProp("_SnowParams", props).vectorValue; Vector4 hr = shaderGUI.FindProp("_SnowHeightAngleRange", props).vectorValue; EditorGUILayout.BeginHorizontal(); bool oldEnabled = GUI.enabled; if (globalLevel) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowAmount", props), "Amount"); GUI.enabled = oldEnabled; globalLevel = DrawGlobalToggle(GetFeatureName(SnowDefineFeature._USEGLOBALSNOWLEVEL), mat); EditorGUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); p1.x = EditorGUILayout.Slider(CHeightClear, p1.x, 0, 1); p1.y = EditorGUILayout.Slider(CErosionClearing, p1.y, 0, 1); EditorGUILayout.BeginHorizontal(); oldEnabled = GUI.enabled; if (globalHeight) { GUI.enabled = false; } EditorGUILayout.PrefixLabel(CHeightRange); hr.x = EditorGUILayout.FloatField(hr.x); hr.y = EditorGUILayout.FloatField(hr.y); GUI.enabled = oldEnabled; globalHeight = DrawGlobalToggle(GetFeatureName(SnowDefineFeature._USEGLOBALSNOWHEIGHT), mat); EditorGUILayout.EndHorizontal(); hr.z = 1.0f - hr.z; hr.w = 1.0f - hr.w; EditorGUILayout.MinMaxSlider(CAngleRange, ref hr.w, ref hr.z, 0.0f, 1.0f); hr.z = 1.0f - hr.z; hr.w = 1.0f - hr.w; p1.z = EditorGUILayout.FloatField(CCrystals, p1.z); p1.w = EditorGUILayout.Slider(CMelt, p1.w, 0, 0.6f); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowParams", props).vectorValue = p1; shaderGUI.FindProp("_SnowHeightAngleRange", props).vectorValue = hr; } Vector4 up = mat.GetVector("_SnowUpVector"); EditorGUI.BeginChangeCheck(); Vector3 newUp = EditorGUILayout.Vector3Field(CUpVector, new Vector3(up.x, up.y, up.z)); if (EditorGUI.EndChangeCheck()) { newUp.Normalize(); mat.SetVector("_SnowUpVector", new Vector4(newUp.x, newUp.y, newUp.z, 0)); EditorUtility.SetDirty(mat); } if (snowNormalNoise) { if (mat.HasProperty("_SnowNormalNoise")) { var texProp = shaderGUI.FindProp("_SnowNormalNoise", props); materialEditor.TexturePropertySingleLine(CDistanceNoise, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_snow_normalnoise"); Vector4 scaleStr = shaderGUI.FindProp("_SnowNormalNoiseScaleStrength", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Noise UV Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Noise Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_SnowNormalNoiseScaleStrength", props).vectorValue = newScaleStr; } } } if (snowDistanceResample) { if (mat.HasProperty("_SnowDistanceResampleScaleStrengthFade")) { Vector4 scaleStr = shaderGUI.FindProp("_SnowDistanceResampleScaleStrengthFade", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Resample UV Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Resample Strength", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Resample Fade Start", scaleStr.z); newScaleStr.w = EditorGUILayout.FloatField("Resample Fade End", scaleStr.w); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_SnowDistanceResampleScaleStrengthFade", props).vectorValue = newScaleStr; } } } } }
//static GUIContent AdvDetailControl = new GUIContent("Advanced Detail Control", "Control map for Advanced Details"); public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; if (t.templateMaterial == null) { if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain>(); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs[i].GetComponent <Terrain>(); if (ter != null) { terrains.Add(ter); } Terrain[] trs = objs[i].GetComponentsInChildren <Terrain>(); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs[x])) { terrains.Add(trs[x]); } } } // setup this terrain Terrain terrain = t.GetComponent <Terrain>(); t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); if (terrain.terrainData.splatPrototypes.Length > 0) { var uvScale = terrain.terrainData.splatPrototypes[0].tileSize; var uvOffset = terrain.terrainData.splatPrototypes[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains[i]; var mgr = nt.GetComponent <MicroSplatTerrain>(); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain>(); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); } MicroSplatTerrain.SyncAll(); return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); } #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailGUI(t); #endif if (t.templateMaterial.IsKeywordEnabled("_VSGRASSMAP")) { EditorGUI.BeginChangeCheck(); t.vsGrassMap = EditorGUILayout.ObjectField(CVSGrassMap, t.vsGrassMap, typeof(Texture2D), false) as Texture2D; if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } } if (t.templateMaterial.IsKeywordEnabled("_VSSHADOWMAP")) { EditorGUI.BeginChangeCheck(); t.vsShadowMap = EditorGUILayout.ObjectField(CVSShadowMap, t.vsShadowMap, typeof(Texture2D), false) as Texture2D; if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailTooset(t); #endif if (MicroSplatUtilities.DrawRollup("Debug", false, true)) { EditorGUI.indentLevel += 2; EditorGUILayout.HelpBox("These should not need to be edited unless something funky has happened. They are automatically managed by MicroSplat.", MessageType.Info); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; t.blendMat = EditorGUILayout.ObjectField(CBlendMat, t.blendMat, typeof(Material), false) as Material; t.terrainDesc = EditorGUILayout.ObjectField("Terrain Descriptor", t.terrainDesc, typeof(Texture2D), false) as Texture2D; t.addPass = EditorGUILayout.ObjectField("Add Pass", t.addPass, typeof(Shader), false) as Shader; EditorGUI.indentLevel -= 2; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (snow != SnowMode.None && mat.HasProperty("_SnowParams") && MicroSplatUtilities.DrawRollup("Snow")) { var snowDiff = shaderGUI.FindProp("_SnowDiff", props); var snowNorm = shaderGUI.FindProp("_SnowNormal", props); materialEditor.TexturePropertySingleLine(CDiffTex, snowDiff); materialEditor.TexturePropertySingleLine(CNormTex, snowNorm); MicroSplatUtilities.EnforceDefaultTexture(snowDiff, "microsplat_def_snow_diff"); MicroSplatUtilities.EnforceDefaultTexture(snowNorm, "microsplat_def_snow_normsao"); if (mat.HasProperty("_SnowTint")) { materialEditor.ColorProperty(shaderGUI.FindProp("_SnowTint", props), "Snow Tint"); } if (mat.HasProperty("_SnowMask")) { var maskTex = shaderGUI.FindProp("_SnowMask", props); materialEditor.TexturePropertySingleLine(CSnowTex, maskTex); } if (mat.HasProperty("_SnowUVScales")) { Vector4 snowUV = shaderGUI.FindProp("_SnowUVScales", props).vectorValue; EditorGUI.BeginChangeCheck(); EditorGUILayout.BeginHorizontal(); EditorGUILayout.PrefixLabel("UV Scale"); snowUV.x = EditorGUILayout.FloatField(snowUV.x); snowUV.y = EditorGUILayout.FloatField(snowUV.y); EditorGUILayout.EndHorizontal(); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowUVScales", props).vectorValue = snowUV; EditorUtility.SetDirty(mat); } } if (mat.HasProperty("_SnowSSSTint")) { var prop = shaderGUI.FindProp("_SnowSSSTint", props); EditorGUI.BeginChangeCheck(); Color c = prop.colorValue; c = EditorGUILayout.ColorField(CSSSTint, c); c.a = EditorGUILayout.Slider(CSSSThickness, c.a, 0, 1); if (EditorGUI.EndChangeCheck()) { prop.colorValue = c; EditorUtility.SetDirty(mat); } } // influence, erosion, crystal, melt Vector4 p1 = shaderGUI.FindProp("_SnowParams", props).vectorValue; Vector4 hr = shaderGUI.FindProp("_SnowHeightAngleRange", props).vectorValue; EditorGUILayout.BeginHorizontal(); bool oldEnabled = GUI.enabled; if (globalLevel) { GUI.enabled = false; } materialEditor.ShaderProperty(shaderGUI.FindProp("_SnowAmount", props), "Amount"); GUI.enabled = oldEnabled; globalLevel = DrawGlobalToggle(GetFeatureName(SnowDefineFeature._USEGLOBALSNOWLEVEL), keywords); EditorGUILayout.EndHorizontal(); EditorGUI.BeginChangeCheck(); if (snow == SnowMode.Rich) { p1.x = EditorGUILayout.Slider(CHeightClear, p1.x, 0, 1); } p1.y = EditorGUILayout.Slider(CErosionClearing, p1.y, 0, 1); EditorGUILayout.BeginHorizontal(); oldEnabled = GUI.enabled; if (globalHeight) { GUI.enabled = false; } EditorGUILayout.PrefixLabel(CHeightRange); hr.x = EditorGUILayout.FloatField(hr.x); hr.y = EditorGUILayout.FloatField(hr.y); GUI.enabled = oldEnabled; globalHeight = DrawGlobalToggle(GetFeatureName(SnowDefineFeature._USEGLOBALSNOWHEIGHT), keywords); EditorGUILayout.EndHorizontal(); hr.z = 1.0f - hr.z; hr.w = 1.0f - hr.w; EditorGUILayout.MinMaxSlider(CAngleRange, ref hr.w, ref hr.z, 0.0f, 1.0f); hr.z = 1.0f - hr.z; hr.w = 1.0f - hr.w; p1.z = EditorGUILayout.FloatField(CCrystals, p1.z); p1.w = EditorGUILayout.Slider(CMelt, p1.w, 0, 0.6f); if (EditorGUI.EndChangeCheck()) { shaderGUI.FindProp("_SnowParams", props).vectorValue = p1; shaderGUI.FindProp("_SnowHeightAngleRange", props).vectorValue = hr; } Vector4 up = mat.GetVector("_SnowUpVector"); EditorGUI.BeginChangeCheck(); Vector3 newUp = EditorGUILayout.Vector3Field(CUpVector, new Vector3(up.x, up.y, up.z)); if (EditorGUI.EndChangeCheck()) { newUp.Normalize(); mat.SetVector("_SnowUpVector", new Vector4(newUp.x, newUp.y, newUp.z, 0)); EditorUtility.SetDirty(mat); } if (snowRim && mat.HasProperty("_SnowRimPower")) { materialEditor.ColorProperty(shaderGUI.FindProp("_SnowRimColor", props), "Rim Light Color"); materialEditor.RangeProperty(shaderGUI.FindProp("_SnowRimPower", props), "Rim Light Power"); } if (snowSparkle && mat.HasProperty("_SnowSparkleNoise")) { var texProp = shaderGUI.FindProp("_SnowSparkleNoise", props); materialEditor.TexturePropertySingleLine(CSparkleNoise, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_perlin4"); materialEditor.ColorProperty(shaderGUI.FindProp("_SnowSparkleTint", props), "Sparkle Tint"); materialEditor.RangeProperty(shaderGUI.FindProp("_SnowSparkleStrength", props), "Sparkle Strength"); materialEditor.RangeProperty(shaderGUI.FindProp("_SnowSparkleEmission", props), "Sparkle Emission Strength"); materialEditor.FloatProperty(shaderGUI.FindProp("_SnowSparkleSize", props), "Sparkle Size"); materialEditor.FloatProperty(shaderGUI.FindProp("_SnowSparkleDensity", props), "Sparkle Density"); materialEditor.FloatProperty(shaderGUI.FindProp("_SnowSparkleViewDependency", props), "Sparkle View Dependency"); materialEditor.FloatProperty(shaderGUI.FindProp("_SnowSparkleNoiseDensity", props), "Sparkle Noise Density"); materialEditor.FloatProperty(shaderGUI.FindProp("_SnowSparkleNoiseAmplitude", props), "Sparkle Noise Amplitude"); } if (snowNormalNoise) { if (mat.HasProperty("_SnowNormalNoise")) { var texProp = shaderGUI.FindProp("_SnowNormalNoise", props); materialEditor.TexturePropertySingleLine(CDistanceNoise, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_snow_normalnoise"); Vector4 scaleStr = shaderGUI.FindProp("_SnowNormalNoiseScaleStrength", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Noise UV Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Noise Strength", scaleStr.y); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_SnowNormalNoiseScaleStrength", props).vectorValue = newScaleStr; } } } if (snowDistanceResample) { if (mat.HasProperty("_SnowDistanceResampleScaleStrengthFade")) { Vector4 scaleStr = shaderGUI.FindProp("_SnowDistanceResampleScaleStrengthFade", props).vectorValue; Vector4 newScaleStr = scaleStr; newScaleStr.x = EditorGUILayout.FloatField("Resample UV Scale", scaleStr.x); newScaleStr.y = EditorGUILayout.FloatField("Resample Strength", scaleStr.y); newScaleStr.z = EditorGUILayout.FloatField("Resample Fade Start", scaleStr.z); newScaleStr.w = EditorGUILayout.FloatField("Resample Fade End", scaleStr.w); if (newScaleStr != scaleStr) { shaderGUI.FindProp("_SnowDistanceResampleScaleStrengthFade", props).vectorValue = newScaleStr; } } } #if __MICROSPLAT_TEXTURECLUSTERS__ if (snowStochastic) { if (mat.HasProperty("_SnowStochasticScale")) { materialEditor.RangeProperty(shaderGUI.FindProp("_SnowStochasticScale", props), "Stochastic Scale"); materialEditor.RangeProperty(shaderGUI.FindProp("_SnowStochasticContrast", props), "Stochastic Contrast"); } } #endif if (mat.HasProperty("_TessDisplaceSnowMultiplier")) { materialEditor.RangeProperty(shaderGUI.FindProp("_TessDisplaceSnowMultiplier", props), "Displacement Multiplier"); } } }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { }
public static Material NewShaderAndMaterial(string path, string name, string[] keywords = null) { // if no branch sampling is specified, go straight to aggressive. Usually defaults are not done this way, but this seems // to make the most sense.. if (!keywords.Contains("_BRANCHSAMPLES")) { System.Array.Resize(ref keywords, keywords.Length + 2); keywords [keywords.Length - 2] = "_BRANCHSAMPLES"; keywords [keywords.Length - 1] = "_BRANCHSAMPLESARG"; } string shaderPath = AssetDatabase.GenerateUniqueAssetPath(path + "/MicroSplat.shader"); string shaderBasePath = shaderPath.Replace(".shader", "_Base.shader"); string matPath = AssetDatabase.GenerateUniqueAssetPath(path + "/MicroSplat.mat"); shaderPath = shaderPath.Replace("//", "/"); shaderBasePath = shaderBasePath.Replace("//", "/"); matPath = matPath.Replace("//", "/"); MicroSplatCompiler compiler = new MicroSplatCompiler(); compiler.Init(); if (keywords == null) { keywords = new string[0]; } var pipeline = MicroSplatUtilities.DetectPipeline(); if (pipeline == MicroSplatUtilities.PipelineType.HDPipeline) { System.Array.Resize(ref keywords, keywords.Length + 1); keywords [keywords.Length - 1] = "_MSRENDERLOOP_UNITYHD"; } else if (pipeline == MicroSplatUtilities.PipelineType.UniversalPipeline) { System.Array.Resize(ref keywords, keywords.Length + 1); keywords [keywords.Length - 1] = "_MSRENDERLOOP_UNITYLD"; } string baseName = "Hidden/MicroSplat/" + name + "_Base"; string baseShader = compiler.Compile(keywords, baseName); string regularShader = compiler.Compile(keywords, name, baseName); System.IO.File.WriteAllText(shaderPath, regularShader); System.IO.File.WriteAllText(shaderBasePath, baseShader); compiler.GenerateAuxShaders(name, shaderPath, new List <string>(keywords)); AssetDatabase.Refresh(); Shader s = AssetDatabase.LoadAssetAtPath <Shader> (shaderPath); if (s == null) { Debug.LogError("Shader not found at path " + shaderPath); } Material m = new Material(s); AssetDatabase.CreateAsset(m, matPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); var kwds = MicroSplatUtilities.FindOrCreateKeywords(m); kwds.keywords = new List <string> (keywords); EditorUtility.SetDirty(kwds); var propData = MicroSplatShaderGUI.FindOrCreatePropTex(m); if (propData != null) { EditorUtility.SetDirty(propData); } AssetDatabase.SaveAssets(); return(AssetDatabase.LoadAssetAtPath <Material> (matPath)); }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (geoTexture && MicroSplatUtilities.DrawRollup("Geo Texture")) { if (mat.HasProperty("_GeoTex")) { var texProp = shaderGUI.FindProp("_GeoTex", props); materialEditor.TexturePropertySingleLine(CGeoTex, texProp); MicroSplatUtilities.EnforceDefaultTexture(texProp, "microsplat_def_geomap_01"); Vector4 parms = mat.GetVector("_GeoParams"); EditorGUI.BeginChangeCheck(); parms.x = EditorGUILayout.Slider("Blend", parms.x, 0, 1); parms.y = 1.0f / Mathf.Max(parms.y, 0.00001f); parms.y = EditorGUILayout.FloatField("World Scale", parms.y); parms.y = 1.0f / Mathf.Max(parms.y, 0.00001f); parms.z = EditorGUILayout.FloatField("World Offset", parms.z); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GeoParams", parms); EditorUtility.SetDirty(mat); } if (geoRange && mat.HasProperty("_GeoRange")) { Vector4 rangeParams = mat.GetVector("_GeoRange"); EditorGUI.BeginChangeCheck(); rangeParams = EditorGUILayout.Vector4Field(CGeoRange, rangeParams); if (EditorGUI.EndChangeCheck()) { if (rangeParams.z < rangeParams.x || rangeParams.z < rangeParams.y) { rangeParams.z = rangeParams.y; } if (rangeParams.y < rangeParams.x) { rangeParams.y = rangeParams.x; } if (rangeParams.w < rangeParams.z) { rangeParams.z = rangeParams.w; } mat.SetVector("_GeoRange", rangeParams); EditorUtility.SetDirty(mat); } } if (geoCurve && mat.HasProperty("_GeoCurveParams")) { var propData = MicroSplatShaderGUI.FindOrCreatePropTex(mat); EditorGUI.BeginChangeCheck(); if (propData != null) { propData.geoCurve = EditorGUILayout.CurveField(CGeoCurve, propData.geoCurve); } Vector4 curveParams = mat.GetVector("_GeoCurveParams"); curveParams.x = EditorGUILayout.FloatField("Scale", curveParams.x); curveParams.y = EditorGUILayout.FloatField("Offset", curveParams.y); curveParams.z = EditorGUILayout.FloatField("Rotation", curveParams.z); if (EditorGUI.EndChangeCheck()) { AnimationCurve c = propData.geoCurve; for (int i = 0; i < c.length; ++i) { c.keys[i].time = Mathf.Clamp01(c.keys[i].time); } mat.SetVector("_GeoCurveParams", curveParams); EditorUtility.SetDirty(mat); EditorUtility.SetDirty(propData); MicroSplatTerrain.SyncAll(); } } } } if ((tintBlendMode != BlendMode.Off || normalBlendMode != NormalBlendMode.Off || SAOMBlend != SAOMBlendMode.Off || emisBlend != SAOMBlendMode.Off) && MicroSplatUtilities.DrawRollup("Global Texture")) { if (tintBlendMode != BlendMode.Off && mat.HasProperty("_GlobalTintTex")) { materialEditor.TexturePropertySingleLine(new GUIContent("Tint Texture", "Albedo Tint Texture"), shaderGUI.FindProp("_GlobalTintTex", props)); Vector4 parms = mat.GetVector("_GlobalTextureParams"); EditorGUI.BeginChangeCheck(); parms.x = EditorGUILayout.Slider("Blend", parms.x, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalTextureParams", parms); EditorUtility.SetDirty(mat); } if (mat.HasProperty("_GlobalTintFade")) { Vector4 fade = mat.GetVector("_GlobalTintFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalTintFade", fade); EditorUtility.SetDirty(mat); } } if (mat.HasProperty("_GlobalTintUVScale")) { Vector4 uv = mat.GetVector("_GlobalTintUVScale"); Vector2 scale = new Vector2(uv.x, uv.y); Vector2 offset = new Vector2(uv.z, uv.w); EditorGUI.BeginChangeCheck(); scale = EditorGUILayout.Vector2Field(CUVScale, scale); offset = EditorGUILayout.Vector2Field(CUVOffset, offset); if (EditorGUI.EndChangeCheck()) { uv = new Vector4(scale.x, scale.y, offset.x, offset.y); mat.SetVector("_GlobalTintUVScale", uv); EditorUtility.SetDirty(mat); } } } if (normalBlendMode != NormalBlendMode.Off && mat.HasProperty("_GlobalNormalTex")) { materialEditor.TexturePropertySingleLine(new GUIContent("Normal Texture", "Global Normal Texture"), shaderGUI.FindProp("_GlobalNormalTex", props)); Vector4 parms = mat.GetVector("_GlobalTextureParams"); EditorGUI.BeginChangeCheck(); parms.y = EditorGUILayout.Slider("Blend", parms.y, 0, 3); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalTextureParams", parms); EditorUtility.SetDirty(mat); } if (mat.HasProperty("_GlobalNormalFade")) { Vector4 fade = mat.GetVector("_GlobalNormalFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalNormalFade", fade); EditorUtility.SetDirty(mat); } } if (mat.HasProperty("_GlobalNormalUVScale")) { Vector4 uv = mat.GetVector("_GlobalNormalUVScale"); Vector2 scale = new Vector2(uv.x, uv.y); Vector2 offset = new Vector2(uv.z, uv.w); EditorGUI.BeginChangeCheck(); scale = EditorGUILayout.Vector2Field(CUVScale, scale); offset = EditorGUILayout.Vector2Field(CUVOffset, offset); if (EditorGUI.EndChangeCheck()) { uv = new Vector4(scale.x, scale.y, offset.x, offset.y); mat.SetVector("_GlobalNormalUVScale", uv); EditorUtility.SetDirty(mat); } } } // saom if (SAOMBlend != SAOMBlendMode.Off && mat.HasProperty("_GlobalSAOMTex")) { materialEditor.TexturePropertySingleLine(new GUIContent("Smoothness(R)/AO(G)/Metal(B) Texture", "Global smoothness, ao, metallic Texture"), shaderGUI.FindProp("_GlobalSAOMTex", props)); Vector4 parms = mat.GetVector("_GlobalTextureParams"); EditorGUI.BeginChangeCheck(); parms.z = EditorGUILayout.Slider("Blend", parms.z, 0, 3); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalTextureParams", parms); EditorUtility.SetDirty(mat); } if (mat.HasProperty("_GlobalSAOMFade")) { Vector4 fade = mat.GetVector("_GlobalSAOMFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalSAOMFade", fade); EditorUtility.SetDirty(mat); } } if (mat.HasProperty("_GlobalSAOMUVScale")) { Vector4 uv = mat.GetVector("_GlobalSAOMUVScale"); Vector2 scale = new Vector2(uv.x, uv.y); Vector2 offset = new Vector2(uv.z, uv.w); EditorGUI.BeginChangeCheck(); scale = EditorGUILayout.Vector2Field(CUVScale, scale); offset = EditorGUILayout.Vector2Field(CUVOffset, offset); if (EditorGUI.EndChangeCheck()) { uv = new Vector4(scale.x, scale.y, offset.x, offset.y); mat.SetVector("_GlobalSAOMUVScale", uv); EditorUtility.SetDirty(mat); } } } // emis if (emisBlend != SAOMBlendMode.Off && mat.HasProperty("_GlobalEmisTex")) { materialEditor.TexturePropertySingleLine(new GUIContent("Emission Texture", "Global Emission"), shaderGUI.FindProp("_GlobalEmisTex", props)); Vector4 parms = mat.GetVector("_GlobalTextureParams"); EditorGUI.BeginChangeCheck(); parms.w = EditorGUILayout.Slider("Blend", parms.w, 0, 3); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalTextureParams", parms); EditorUtility.SetDirty(mat); } if (mat.HasProperty("_GlobalEmisFade")) { Vector4 fade = mat.GetVector("_GlobalEmisFade"); EditorGUI.BeginChangeCheck(); fade.x = EditorGUILayout.FloatField("Begin Fade", fade.x); fade.z = EditorGUILayout.Slider("Opacity At Begin", fade.z, 0, 1); fade.y = EditorGUILayout.FloatField("Fade Range", fade.y); fade.w = EditorGUILayout.Slider("Opacity At End", fade.w, 0, 1); if (EditorGUI.EndChangeCheck()) { mat.SetVector("_GlobalEmisFade", fade); EditorUtility.SetDirty(mat); } } if (mat.HasProperty("_GlobalEmisUVScale")) { Vector4 uv = mat.GetVector("_GlobalEmisUVScale"); Vector2 scale = new Vector2(uv.x, uv.y); Vector2 offset = new Vector2(uv.z, uv.w); EditorGUI.BeginChangeCheck(); scale = EditorGUILayout.Vector2Field(CUVScale, scale); offset = EditorGUILayout.Vector2Field(CUVOffset, offset); if (EditorGUI.EndChangeCheck()) { uv = new Vector4(scale.x, scale.y, offset.x, offset.y); mat.SetVector("_GlobalEmisUVScale", uv); EditorUtility.SetDirty(mat); } } } } }
public static Material NewShaderAndMaterial(string path, string name, string[] keywords = null) { string shaderPath = AssetDatabase.GenerateUniqueAssetPath(path + "/MicroSplat.shader"); string shaderBasePath = shaderPath.Replace(".shader", "_Base.shader"); string matPath = AssetDatabase.GenerateUniqueAssetPath(path + "/MicroSplat.mat"); shaderPath = shaderPath.Replace("//", "/"); shaderBasePath = shaderBasePath.Replace("//", "/"); matPath = matPath.Replace("//", "/"); MicroSplatCompiler compiler = new MicroSplatCompiler(); compiler.Init(); if (keywords == null) { keywords = new string[0]; } var pipeline = MicroSplatUtilities.DetectPipeline(); if (pipeline == MicroSplatUtilities.PipelineType.HDPipeline) { System.Array.Resize(ref keywords, keywords.Length + 1); keywords [keywords.Length - 1] = "_MSRENDERLOOP_UNITYHD"; } else if (pipeline == MicroSplatUtilities.PipelineType.UniversalPipeline) { System.Array.Resize(ref keywords, keywords.Length + 1); keywords [keywords.Length - 1] = "_MSRENDERLOOP_UNITYLD"; } string baseName = "Hidden/MicroSplat/" + name + "_Base"; string baseShader = compiler.Compile(keywords, baseName); string regularShader = compiler.Compile(keywords, name, baseName); System.IO.File.WriteAllText(shaderPath, regularShader); System.IO.File.WriteAllText(shaderBasePath, baseShader); if (keywords.Contains("_MESHOVERLAYSPLATS")) { string meshOverlayShader = compiler.Compile(keywords, name, null, true); System.IO.File.WriteAllText(shaderPath.Replace(".shader", "_MeshOverlay.shader"), meshOverlayShader); } AssetDatabase.Refresh(); Shader s = AssetDatabase.LoadAssetAtPath <Shader> (shaderPath); if (s == null) { Debug.LogError("Shader not found at path " + shaderPath); } Material m = new Material(s); AssetDatabase.CreateAsset(m, matPath); AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); var kwds = MicroSplatUtilities.FindOrCreateKeywords(m); kwds.keywords = new List <string> (keywords); EditorUtility.SetDirty(kwds); var propData = MicroSplatShaderGUI.FindOrCreatePropTex(m); if (propData != null) { EditorUtility.SetDirty(propData); } return(AssetDatabase.LoadAssetAtPath <Material> (matPath)); }
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, Material mat, MaterialEditor materialEditor, MaterialProperty[] props) { if (clusterMode != ClusterMode.None) { if (MicroSplatUtilities.DrawRollup("Texture Clustering")) { if (clusterMode == ClusterMode.Stochastic) { if (mat.HasProperty("_StochasticContrast")) { materialEditor.RangeProperty(shaderGUI.FindProp("_StochasticContrast", props), "Blend Contrast"); } if (mat.HasProperty("_StochasticScale")) { materialEditor.RangeProperty(shaderGUI.FindProp("_StochasticScale", props), "Noise Scale"); } } else { if (mat.HasProperty("_ClusterNoise")) { var noiseMap = shaderGUI.FindProp("_ClusterNoise", props); var albedoMap = shaderGUI.FindProp("_ClusterDiffuse2", props); var normalMap = shaderGUI.FindProp("_ClusterNormal2", props); var noiseParams = shaderGUI.FindProp("_ClusterParams", props); materialEditor.TexturePropertySingleLine(CAlbedoTex2, albedoMap); materialEditor.TexturePropertySingleLine(CNormalTex2, normalMap); if (mat.HasProperty("_ClusterSmoothAO2")) { var smoothAO = shaderGUI.FindProp("_ClusterSmoothAO2", props); materialEditor.TexturePropertySingleLine(CSmoothAO2, smoothAO); } if (mat.HasProperty("_ClusterEmissiveMetal2")) { var emis2 = shaderGUI.FindProp("_ClusterEmissiveMetal2", props); materialEditor.TexturePropertySingleLine(CEmis2, emis2); } if (clusterMode == ClusterMode.ThreeVariants) { var albedoMap3 = shaderGUI.FindProp("_ClusterDiffuse3", props); var normalMap3 = shaderGUI.FindProp("_ClusterNormal3", props); materialEditor.TexturePropertySingleLine(CAlbedoTex3, albedoMap3); materialEditor.TexturePropertySingleLine(CNormalTex3, normalMap3); if (mat.HasProperty("_ClusterSmoothAO3")) { var smoothAO = shaderGUI.FindProp("_ClusterSmoothAO3", props); materialEditor.TexturePropertySingleLine(CSmoothAO3, smoothAO); } if (mat.HasProperty("_ClusterEmissiveMetal3")) { var emis3 = shaderGUI.FindProp("_ClusterEmissiveMetal3", props); materialEditor.TexturePropertySingleLine(CEmis3, emis3); } } materialEditor.TexturePropertySingleLine(CNoiseTex, noiseMap); MicroSplatUtilities.EnforceDefaultTexture(noiseMap, "microsplat_def_clusternoise"); if (secondNoise && mat.HasProperty("_ClusterNoise2")) { var noiseMap2 = shaderGUI.FindProp("_ClusterNoise2", props); materialEditor.TexturePropertySingleLine(CNoiseTex, noiseMap2); MicroSplatUtilities.EnforceDefaultTexture(noiseMap, "microsplat_def_clusternoise"); } bool enabled = GUI.enabled; if (perTexClusterContrast) { GUI.enabled = false; } var contrastProp = shaderGUI.FindProp("_ClusterContrast", props); contrastProp.floatValue = EditorGUILayout.Slider(CInterpContrast, contrastProp.floatValue, 1.0f, 0.0001f); if (perTexClusterContrast) { GUI.enabled = enabled; } if (perTexClusterBoost) { GUI.enabled = false; } var boostProp = shaderGUI.FindProp("_ClusterBoost", props); boostProp.floatValue = EditorGUILayout.Slider(CClusterBoost, boostProp.floatValue, 0.5f, 4.0f); if (perTexClusterBoost) { GUI.enabled = enabled; } var skew = shaderGUI.FindProp("_ClusterScaleVar", props); skew.floatValue = EditorGUILayout.Slider(CClusterScale, skew.floatValue, 0.0f, 0.2f); { Vector4 vec = noiseParams.vectorValue; EditorGUI.BeginChangeCheck(); Vector2 scale = new Vector2(vec.x, vec.y); Vector2 offset = new Vector2(vec.z, vec.w); scale = EditorGUILayout.Vector2Field("Scale", scale); offset = EditorGUILayout.Vector2Field("Offset", offset); if (EditorGUI.EndChangeCheck()) { vec.x = scale.x; vec.y = scale.y; vec.z = offset.x; vec.w = offset.y; noiseParams.vectorValue = vec; } } if (mat.HasProperty("_ClusterParams2")) { EditorGUILayout.LabelField("Second Octave Noise"); var noiseParams2 = shaderGUI.FindProp("_ClusterParams2", props); Vector4 vec = noiseParams2.vectorValue; EditorGUI.BeginChangeCheck(); Vector2 scale = new Vector2(vec.x, vec.y); Vector2 offset = new Vector2(vec.z, vec.w); scale = EditorGUILayout.Vector2Field("Scale", scale); offset = EditorGUILayout.Vector2Field("Offset", offset); if (EditorGUI.EndChangeCheck()) { vec.x = scale.x; vec.y = scale.y; vec.z = offset.x; vec.w = offset.y; noiseParams2.vectorValue = vec; } } } } } } }