public virtual void DrawGPUInstancerPrototypeBillboardSettings(GPUInstancerPrototype selectedPrototype, GPUInstancerShaderBindings shaderBindings, GPUInstancerBillboardAtlasBindings billboardAtlasBindings) { if (selectedPrototype.isBillboardDisabled || (selectedPrototype is GPUInstancerDetailPrototype && !((GPUInstancerDetailPrototype)selectedPrototype).usePrototypeMesh)) { if (selectedPrototype.useGeneratedBillboard) { selectedPrototype.useGeneratedBillboard = false; } if (selectedPrototype.billboard != null) { selectedPrototype.billboard = null; } return; } if (Event.current.type == EventType.Repaint && !selectedPrototype.checkedForBillboardExtentions) { selectedPrototype.checkedForBillboardExtentions = true; if (CheckForBillboardExtentions(selectedPrototype, billboardAtlasBindings)) { return; } } EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); GPUInstancerEditorConstants.DrawCustomLabel(GPUInstancerEditorConstants.TEXT_billboardSettings, GPUInstancerEditorConstants.Styles.boldLabel); selectedPrototype.useGeneratedBillboard = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_useGeneratedBillboard, selectedPrototype.useGeneratedBillboard); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_useGeneratedBillboard); if (selectedPrototype.useGeneratedBillboard && selectedPrototype.billboard == null) { selectedPrototype.billboard = new GPUInstancerBillboard(); } else if (!selectedPrototype.useGeneratedBillboard && selectedPrototype.billboard != null) { if (selectedPrototype.billboard.albedoAtlasTexture != null) { billboardAtlasBindings.DeleteBillboardTextures(selectedPrototype); } if (!selectedPrototype.billboard.useCustomBillboard) { selectedPrototype.billboard = null; } } if (selectedPrototype.useGeneratedBillboard) { if (selectedPrototype.treeType != GPUInstancerTreeType.SpeedTree && selectedPrototype.treeType != GPUInstancerTreeType.TreeCreatorTree && selectedPrototype.treeType != GPUInstancerTreeType.SoftOcclusionTree && !selectedPrototype.billboard.useCustomBillboard) { EditorGUILayout.HelpBox(GPUInstancerEditorConstants.HELPTEXT_unsupportedBillboardWarning, MessageType.Warning); } bool previousUseCustomBillboard = selectedPrototype.billboard.useCustomBillboard; selectedPrototype.billboard.useCustomBillboard = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_useCustomBillboard, selectedPrototype.billboard.useCustomBillboard); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_useCustomBillboard); if (selectedPrototype.billboard.useCustomBillboard) { selectedPrototype.billboard.customBillboardMesh = (Mesh)EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_customBillboardMesh, selectedPrototype.billboard.customBillboardMesh, typeof(Mesh), false); selectedPrototype.billboard.customBillboardMaterial = (Material)EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_customBillboardMaterial, selectedPrototype.billboard.customBillboardMaterial, typeof(Material), false); selectedPrototype.billboard.isBillboardShadowCasting = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isBillboardShadowCasting, selectedPrototype.billboard.isBillboardShadowCasting); if (!previousUseCustomBillboard && selectedPrototype.billboard.albedoAtlasTexture != null) { billboardAtlasBindings.DeleteBillboardTextures(selectedPrototype); } if (shaderBindings != null && selectedPrototype.billboard.customBillboardMaterial != null) { if (!shaderBindings.IsShadersInstancedVersionExists(selectedPrototype.billboard.customBillboardMaterial.shader.name)) { Shader instancedShader = GPUInstancerUtility.CreateInstancedShader(selectedPrototype.billboard.customBillboardMaterial.shader, shaderBindings); if (instancedShader != null) { shaderBindings.AddShaderInstance(selectedPrototype.billboard.customBillboardMaterial.shader.name, instancedShader); } } } } else { if (selectedPrototype.billboard.customBillboardInLODGroup) { selectedPrototype.billboard.customBillboardInLODGroup = false; } selectedPrototype.billboard.billboardQuality = (BillboardQuality)EditorGUILayout.Popup(GPUInstancerEditorConstants.TEXT_billboardQuality, (int)selectedPrototype.billboard.billboardQuality, GPUInstancerEditorConstants.TEXT_BillboardQualityOptions); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_billboardQuality); switch (selectedPrototype.billboard.billboardQuality) { case BillboardQuality.Low: selectedPrototype.billboard.atlasResolution = 1024; break; case BillboardQuality.Mid: selectedPrototype.billboard.atlasResolution = 2048; break; case BillboardQuality.High: selectedPrototype.billboard.atlasResolution = 4096; break; case BillboardQuality.VeryHigh: selectedPrototype.billboard.atlasResolution = 8192; break; } selectedPrototype.billboard.frameCount = EditorGUILayout.IntSlider(GPUInstancerEditorConstants.TEXT_billboardFrameCount, selectedPrototype.billboard.frameCount, 8, 32); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_billboardFrameCount); selectedPrototype.billboard.frameCount = Mathf.NextPowerOfTwo(selectedPrototype.billboard.frameCount); selectedPrototype.billboard.billboardBrightness = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_billboardBrightness, selectedPrototype.billboard.billboardBrightness, 0.0f, 1.0f); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_billboardBrightness); selectedPrototype.billboard.isOverridingOriginalCutoff = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_overrideOriginalCutoff, selectedPrototype.billboard.isOverridingOriginalCutoff); if (selectedPrototype.billboard.isOverridingOriginalCutoff) { selectedPrototype.billboard.cutoffOverride = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_overrideCutoffAmount, selectedPrototype.billboard.cutoffOverride, 0.01f, 1.0f); } else { selectedPrototype.billboard.cutoffOverride = -1f; } DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_overrideOriginalCutoff); } if (!selectedPrototype.billboard.customBillboardInLODGroup) { bool hasLODGroup = selectedPrototype.prefabObject.GetComponent <LODGroup>() != null; bool speedTreeBillboard = selectedPrototype.treeType == GPUInstancerTreeType.SpeedTree && hasLODGroup && selectedPrototype.prefabObject.GetComponentInChildren <BillboardRenderer>() != null; if (hasLODGroup && !speedTreeBillboard) { selectedPrototype.billboard.replaceLODCullWithBillboard = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_replaceLODCull, selectedPrototype.billboard.replaceLODCullWithBillboard); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_replaceLODCull); } if ((!hasLODGroup || !selectedPrototype.billboard.replaceLODCullWithBillboard) && !speedTreeBillboard) { selectedPrototype.billboard.billboardDistance = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_generatedBillboardDistance, selectedPrototype.billboard.billboardDistance, 0.01f, 1f); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_generatedBillboardDistance); } } if (!selectedPrototype.billboard.useCustomBillboard) { selectedPrototype.billboard.billboardFaceCamPos = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_billboardFaceCamPos, selectedPrototype.billboard.billboardFaceCamPos); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_billboardFaceCamPos); if (selectedPrototype.billboard.albedoAtlasTexture == null) { GPUInstancerUtility.AssignBillboardBinding(selectedPrototype, billboardAtlasBindings); } EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_billboardAlbedo, selectedPrototype.billboard.albedoAtlasTexture, typeof(GameObject), false); EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_billboardNormal, selectedPrototype.billboard.normalAtlasTexture, typeof(GameObject), false); EditorGUI.EndDisabledGroup(); } GUILayout.Space(10); EditorGUILayout.BeginHorizontal(); if (!selectedPrototype.billboard.useCustomBillboard) { GPUInstancerEditorConstants.DrawColoredButton(selectedPrototype.billboard.albedoAtlasTexture == null ? GPUInstancerEditorConstants.Contents.generateBillboard : GPUInstancerEditorConstants.Contents.regenerateBillboard, GPUInstancerEditorConstants.Colors.green, Color.white, FontStyle.Bold, Rect.zero, () => { GPUInstancerUtility.GeneratePrototypeBillboard(selectedPrototype, billboardAtlasBindings, selectedPrototype.billboard.albedoAtlasTexture != null); }); } if ((!selectedPrototype.billboard.useCustomBillboard && selectedPrototype.billboard.albedoAtlasTexture != null) || (selectedPrototype.billboard.useCustomBillboard && selectedPrototype.billboard.customBillboardMesh != null && selectedPrototype.billboard.customBillboardMaterial != null)) { GPUInstancerEditorConstants.DrawColoredButton(GPUInstancerEditorConstants.Contents.showBillboard, GPUInstancerEditorConstants.Colors.lightBlue, Color.white, FontStyle.Bold, Rect.zero, () => { GPUInstancerUtility.ShowBillboardQuad(selectedPrototype, Vector3.zero); }); } EditorGUILayout.EndHorizontal(); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_regenerateBillboard); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_showBillboard); } if (selectedPrototype.useGeneratedBillboard && selectedPrototype.billboard != null && selectedPrototype.billboard.useCustomBillboard && GPUInstancerDefines.billboardExtentions != null && GPUInstancerDefines.billboardExtentions.Count > 0) { GUILayout.Space(10); EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); GPUInstancerEditorConstants.DrawCustomLabel("External Billboard Generators", GPUInstancerEditorConstants.Styles.boldLabel); GUILayout.Space(5); foreach (Extention.GPUInstancerBillboardExtention billboardExtention in GPUInstancerDefines.billboardExtentions) { try { EditorGUILayout.BeginHorizontal(); GUILayout.Label(billboardExtention.GetTitle(), GPUInstancerEditorConstants.Styles.label); GPUInstancerEditorConstants.DrawColoredButton(new GUIContent(billboardExtention.GetButtonText()), GPUInstancerEditorConstants.Colors.green, Color.white, FontStyle.Bold, Rect.zero, () => { _redirectObject = billboardExtention.GenerateBillboard(selectedPrototype.prefabObject); selectedPrototype.checkedForBillboardExtentions = false; }); EditorGUILayout.EndHorizontal(); GUILayout.Space(5); } catch (System.Exception e) { EditorUtility.ClearProgressBar(); Debug.LogError("Error generating billboard: " + e.Message + " StackTrace:" + e.StackTrace); } } EditorGUILayout.EndVertical(); } EditorGUILayout.EndVertical(); }
public static bool CheckForBillboardExtentions(GPUInstancerPrototype selectedPrototype, GPUInstancerBillboardAtlasBindings billboardAtlasBindings) { bool hasExtentionBillboard = false; if (GPUInstancerDefines.billboardExtentions != null && GPUInstancerDefines.billboardExtentions.Count > 0) { foreach (Extention.GPUInstancerBillboardExtention billboardExtention in GPUInstancerDefines.billboardExtentions) { try { if (billboardExtention.IsBillboardAdded(selectedPrototype.prefabObject)) { Mesh generatedMesh = billboardExtention.GetBillboardMesh(selectedPrototype.prefabObject); Material generatedMaterial = billboardExtention.GetBillboardMaterial(selectedPrototype.prefabObject); bool isInLODGroup = billboardExtention.IsInLODGroup(selectedPrototype.prefabObject); if (generatedMesh != null && generatedMaterial != null) { if (selectedPrototype.billboard == null) { selectedPrototype.billboard = new GPUInstancerBillboard(); } selectedPrototype.useGeneratedBillboard = true; selectedPrototype.billboard.useCustomBillboard = true; selectedPrototype.billboard.customBillboardInLODGroup = isInLODGroup; selectedPrototype.billboard.customBillboardMesh = generatedMesh; selectedPrototype.billboard.customBillboardMaterial = generatedMaterial; hasExtentionBillboard = true; break; } } } catch (System.Exception e) { EditorUtility.ClearProgressBar(); Debug.LogError("Error generating billboard: " + e.Message + " StackTrace:" + e.StackTrace); } } } return(hasExtentionBillboard); }
public virtual void DrawGPUInstancerPrototypeBox(GPUInstancerPrototype selectedPrototype, bool isFrustumCulling, bool isOcclusionCulling, GPUInstancerShaderBindings shaderBindings, GPUInstancerBillboardAtlasBindings billboardAtlasBindings) { if (selectedPrototype == null) { return; } EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); // title Rect foldoutRect = GUILayoutUtility.GetRect(0, 20, GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(false)); foldoutRect.x += 12; showPrototypeBox = EditorGUI.Foldout(foldoutRect, showPrototypeBox, selectedPrototype.ToString(), true, GPUInstancerEditorConstants.Styles.foldout); if (!showPrototypeBox) { EditorGUILayout.EndVertical(); return; } if (!string.IsNullOrEmpty(selectedPrototype.warningText)) { EditorGUILayout.HelpBox(selectedPrototype.warningText, MessageType.Error); if (selectedPrototype.warningText.StartsWith("Can not create instanced version for shader")) { GPUInstancerEditorConstants.DrawColoredButton(new GUIContent("Go to Unity Archive"), GPUInstancerEditorConstants.Colors.lightred, Color.white, FontStyle.Bold, Rect.zero, () => { Application.OpenURL("https://unity3d.com/get-unity/download/archive"); }); GUILayout.Space(10); } } EditorGUI.BeginDisabledGroup(true); EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_prefabObject, selectedPrototype.prefabObject, typeof(GameObject), false); EditorGUILayout.ObjectField(GPUInstancerEditorConstants.TEXT_prototypeSO, selectedPrototype, typeof(GPUInstancerPrototype), false); EditorGUI.EndDisabledGroup(); EditorGUI.BeginChangeCheck(); #region Shadows EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); GPUInstancerEditorConstants.DrawCustomLabel(GPUInstancerEditorConstants.TEXT_shadows, GPUInstancerEditorConstants.Styles.boldLabel); EditorGUI.BeginDisabledGroup(Application.isPlaying); selectedPrototype.isShadowCasting = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isShadowCasting, selectedPrototype.isShadowCasting); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_isShadowCasting); EditorGUI.EndDisabledGroup(); if (selectedPrototype.isShadowCasting) { if (selectedPrototype is GPUInstancerPrefabPrototype) { EditorGUI.BeginDisabledGroup(Application.isPlaying); selectedPrototype.useOriginalShaderForShadow = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_useOriginalShaderForShadow, selectedPrototype.useOriginalShaderForShadow); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_useOriginalShaderForShadow); EditorGUI.EndDisabledGroup(); } if (!(selectedPrototype is GPUInstancerDetailPrototype)) { selectedPrototype.useCustomShadowDistance = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_useCustomShadowDistance, selectedPrototype.useCustomShadowDistance); if (selectedPrototype.useCustomShadowDistance) { selectedPrototype.shadowDistance = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_shadowDistance, selectedPrototype.shadowDistance, 0.0f, QualitySettings.shadowDistance); } DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_useCustomShadowDistance); if (selectedPrototype.prefabObject != null && selectedPrototype.prefabObject.GetComponent <LODGroup>() != null) { LODGroup lodGroup = selectedPrototype.prefabObject.GetComponent <LODGroup>(); List <GUIContent> optionsList = GPUInstancerEditorConstants.Contents.LODs.GetRange(0, lodGroup.lodCount); optionsList.Add(GPUInstancerEditorConstants.Contents.LODs[8]); GUIContent[] options = optionsList.ToArray(); int index = 0; for (int i = 0; i < lodGroup.lodCount; i++) { index = i * 4; if (i >= 4) { index = (i - 4) * 4 + 1; } selectedPrototype.shadowLODMap[index] = EditorGUILayout.Popup(GPUInstancerEditorConstants.Contents.shadowLODs[i], selectedPrototype.shadowLODMap[index], options); } } selectedPrototype.cullShadows = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_cullShadows, selectedPrototype.cullShadows); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_cullShadows); } } EditorGUILayout.EndVertical(); #endregion Shadows #region Culling EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); GPUInstancerEditorConstants.DrawCustomLabel(GPUInstancerEditorConstants.TEXT_culling, GPUInstancerEditorConstants.Styles.boldLabel); selectedPrototype.maxDistance = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_maxDistance, selectedPrototype.maxDistance, 0.0f, GetMaxDistance(selectedPrototype)); DrawHelpText(selectedPrototype is GPUInstancerDetailPrototype ? GPUInstancerEditorConstants.HELPTEXT_maxDistanceDetail : GPUInstancerEditorConstants.HELPTEXT_maxDistance); if (isFrustumCulling) { selectedPrototype.isFrustumCulling = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isFrustumCulling, selectedPrototype.isFrustumCulling); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_isFrustumCulling); selectedPrototype.frustumOffset = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_frustumOffset, selectedPrototype.frustumOffset, 0.0f, 0.5f); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_frustumOffset); } if (isOcclusionCulling) { selectedPrototype.isOcclusionCulling = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isOcclusionCulling, selectedPrototype.isOcclusionCulling); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_isOcclusionCulling); } if (isFrustumCulling || isOcclusionCulling) { selectedPrototype.minCullingDistance = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_minCullingDistance, selectedPrototype.minCullingDistance, 0, 100); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_minCullingDistance); } EditorGUILayout.EndVertical(); #endregion Culling #region LOD if (selectedPrototype.prefabObject != null && (selectedPrototype.prefabObject.GetComponent <LODGroup>() != null || selectedPrototype.useGeneratedBillboard)) { EditorGUILayout.BeginVertical(GPUInstancerEditorConstants.Styles.box); GPUInstancerEditorConstants.DrawCustomLabel(GPUInstancerEditorConstants.TEXT_LOD, GPUInstancerEditorConstants.Styles.boldLabel); EditorGUI.BeginDisabledGroup(Application.isPlaying); selectedPrototype.isLODCrossFade = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isLODCrossFade, selectedPrototype.isLODCrossFade); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_isLODCrossFade); if (selectedPrototype.isLODCrossFade) { selectedPrototype.isLODCrossFadeAnimate = EditorGUILayout.Toggle(GPUInstancerEditorConstants.TEXT_isLODCrossFadeAnimate, selectedPrototype.isLODCrossFadeAnimate); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_isLODCrossFadeAnimate); if (!selectedPrototype.isLODCrossFadeAnimate) { selectedPrototype.lodFadeTransitionWidth = EditorGUILayout.Slider(GPUInstancerEditorConstants.TEXT_lodFadeTransitionWidth, selectedPrototype.lodFadeTransitionWidth, 0.0f, 1.0f); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_lodFadeTransitionWidth); } } selectedPrototype.lodBiasAdjustment = EditorGUILayout.FloatField(GPUInstancerEditorConstants.TEXT_lodBiasAdjustment, selectedPrototype.lodBiasAdjustment); DrawHelpText(GPUInstancerEditorConstants.HELPTEXT_lodBiasAdjustment); EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); } #endregion LOD EditorGUI.BeginDisabledGroup(Application.isPlaying); DrawGPUInstancerPrototypeInfo(selectedPrototype); DrawGPUInstancerPrototypeBillboardSettings(selectedPrototype, shaderBindings, billboardAtlasBindings); DrawGPUInstancerPrototypeActions(); DrawGPUInstancerPrototypeAdvancedActions(); if (EditorGUI.EndChangeCheck() && selectedPrototype != null) { EditorUtility.SetDirty(selectedPrototype); } EditorGUI.EndDisabledGroup(); EditorGUILayout.EndVertical(); }