From e4903ca391c6bbad85d320de5c97d6c98f463e79 Mon Sep 17 00:00:00 2001 From: Nico de Poel Date: Wed, 14 Jul 2021 10:46:15 +0200 Subject: [PATCH] Made a start on scriptable visual styles, which encompasses material templates, mesh renderer configuration and texture assignment. The default implementation is based on the GLQuake look, but everything can be overridden to create completely new visual styles. --- Assets/Scenes/Default.unity | 2 + Assets/Scripts/Bootstrap.cs | 3 + Assets/Scripts/VisualStyle.cs | 96 +++++++++++++ Assets/Scripts/VisualStyle.cs.meta | 11 ++ Assets/Styles.meta | 8 ++ Assets/Styles/GLQuake.meta | 8 ++ Assets/Styles/GLQuake/GLQuake.asset | 17 +++ Assets/Styles/GLQuake/GLQuake.asset.meta | 8 ++ Assets/Styles/GLQuake/Materials.meta | 8 ++ .../GLQuake/Materials/GLQuake_Entity.mat | 128 ++++++++++++++++++ .../GLQuake/Materials/GLQuake_Entity.mat.meta | 8 ++ .../GLQuake/Materials/GLQuake_World.mat | 128 ++++++++++++++++++ .../GLQuake/Materials/GLQuake_World.mat.meta | 8 ++ 13 files changed, 433 insertions(+) create mode 100644 Assets/Scripts/VisualStyle.cs create mode 100644 Assets/Scripts/VisualStyle.cs.meta create mode 100644 Assets/Styles.meta create mode 100644 Assets/Styles/GLQuake.meta create mode 100644 Assets/Styles/GLQuake/GLQuake.asset create mode 100644 Assets/Styles/GLQuake/GLQuake.asset.meta create mode 100644 Assets/Styles/GLQuake/Materials.meta create mode 100644 Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat create mode 100644 Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat.meta create mode 100644 Assets/Styles/GLQuake/Materials/GLQuake_World.mat create mode 100644 Assets/Styles/GLQuake/Materials/GLQuake_World.mat.meta diff --git a/Assets/Scenes/Default.unity b/Assets/Scenes/Default.unity index b44f4ab..52e7f77 100644 --- a/Assets/Scenes/Default.unity +++ b/Assets/Scenes/Default.unity @@ -153,6 +153,8 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 941b1c44c09860d4fa2547fa7c914d55, type: 3} m_Name: m_EditorClassIdentifier: + visualStyles: + - {fileID: 11400000, guid: d187fe54fb9a3e047bf4cec083877e72, type: 2} --- !u!4 &157597865 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/Bootstrap.cs b/Assets/Scripts/Bootstrap.cs index 784fa33..0e5656e 100644 --- a/Assets/Scripts/Bootstrap.cs +++ b/Assets/Scripts/Bootstrap.cs @@ -9,6 +9,9 @@ public class Bootstrap : MonoBehaviour private float speed = 1.0f; private UniQuake uq; + + [SerializeField] + private List visualStyles = new List(); private void Start() { diff --git a/Assets/Scripts/VisualStyle.cs b/Assets/Scripts/VisualStyle.cs new file mode 100644 index 0000000..036b680 --- /dev/null +++ b/Assets/Scripts/VisualStyle.cs @@ -0,0 +1,96 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; +using UnityEngine.Rendering; + +[CreateAssetMenu(fileName = "VisualStyle", menuName = "UniQuake/Visual Style", order = 1)] +public class VisualStyle : ScriptableObject +{ + [SerializeField] + private Material aliasModelMaterial; + + [SerializeField] + private Material brushModelMaterial; // TODO: not sure if this should be separate or combined into one entityMaterial + + [SerializeField] + private Material worldModelMaterial; // TODO: split into wall, liquid, sky, etc + + // TODO: add particle effects + + public virtual void SetupAliasModelRenderer(MeshRenderer meshRenderer) + { + meshRenderer.material = new Material(aliasModelMaterial); + meshRenderer.shadowCastingMode = ShadowCastingMode.Off; + meshRenderer.receiveShadows = false; + meshRenderer.lightProbeUsage = LightProbeUsage.Off; + meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; + } + + public virtual void SetupAliasModelRenderer(SkinnedMeshRenderer skinnedMeshRenderer) + { + skinnedMeshRenderer.material = new Material(aliasModelMaterial); + skinnedMeshRenderer.shadowCastingMode = ShadowCastingMode.Off; + skinnedMeshRenderer.receiveShadows = false; + skinnedMeshRenderer.lightProbeUsage = LightProbeUsage.Off; + skinnedMeshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; + } + + public virtual void SetupBrushModelRenderer(MeshRenderer meshRenderer) + { + meshRenderer.material = new Material(brushModelMaterial); + meshRenderer.shadowCastingMode = ShadowCastingMode.Off; + meshRenderer.receiveShadows = false; + meshRenderer.lightProbeUsage = LightProbeUsage.Off; + meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; + } + + public virtual void SetupWorldModelRenderer(MeshRenderer meshRenderer) + { + meshRenderer.material = new Material(worldModelMaterial); + meshRenderer.shadowCastingMode = ShadowCastingMode.Off; + meshRenderer.receiveShadows = false; + meshRenderer.lightProbeUsage = LightProbeUsage.Off; + meshRenderer.reflectionProbeUsage = ReflectionProbeUsage.Off; + } + + public virtual void SetAliasModelTextures(Material material, Texture2D mainTexture, Texture2D fullBright) + { + material.mainTexture = mainTexture; + + material.SetTexture("_EmissionMap", fullBright); + material.SetColor("_EmissionColor", Color.white); + + if (fullBright != null) + material.EnableKeyword("_EMISSION"); + else + material.DisableKeyword("_EMISSION"); + } + + public virtual void SetBrushModelTextures(Material material, Texture2D mainTexture, Texture2D fullBright) + { + material.mainTexture = mainTexture; + + material.SetTexture("_EmissionMap", fullBright); + material.SetColor("_EmissionColor", Color.white); + + if (fullBright != null) + material.EnableKeyword("_EMISSION"); + else + material.DisableKeyword("_EMISSION"); + } + + public virtual void SetWorldModelTextures(Material material, Texture2D mainTexture, Texture2D fullBright, Texture2D lightmap) + { + material.mainTexture = mainTexture; + + material.SetTexture("_EmissionMap", fullBright); + material.SetColor("_EmissionColor", Color.white); + + if (fullBright != null) + material.EnableKeyword("_EMISSION"); + else + material.DisableKeyword("_EMISSION"); + + // TODO: lightmap texture + } +} diff --git a/Assets/Scripts/VisualStyle.cs.meta b/Assets/Scripts/VisualStyle.cs.meta new file mode 100644 index 0000000..7a895ad --- /dev/null +++ b/Assets/Scripts/VisualStyle.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2df0cbad06a6ed5489201e395f9c5bb3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles.meta b/Assets/Styles.meta new file mode 100644 index 0000000..e3e4dc3 --- /dev/null +++ b/Assets/Styles.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ba7137fbd14068044b1a108a1b1afad4 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles/GLQuake.meta b/Assets/Styles/GLQuake.meta new file mode 100644 index 0000000..2127722 --- /dev/null +++ b/Assets/Styles/GLQuake.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 288aaeac807f2b64bb93a49b31170ca5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles/GLQuake/GLQuake.asset b/Assets/Styles/GLQuake/GLQuake.asset new file mode 100644 index 0000000..a9a09e9 --- /dev/null +++ b/Assets/Styles/GLQuake/GLQuake.asset @@ -0,0 +1,17 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 2df0cbad06a6ed5489201e395f9c5bb3, type: 3} + m_Name: GLQuake + m_EditorClassIdentifier: + aliasModelMaterial: {fileID: 2100000, guid: 4d7703ac1adf3534f89b4041b779ff5e, type: 2} + brushModelMaterial: {fileID: 2100000, guid: 4d7703ac1adf3534f89b4041b779ff5e, type: 2} + worldModelMaterial: {fileID: 2100000, guid: fcbaf32c00bea2344bbb1419c61364b6, type: 2} diff --git a/Assets/Styles/GLQuake/GLQuake.asset.meta b/Assets/Styles/GLQuake/GLQuake.asset.meta new file mode 100644 index 0000000..9ce6bde --- /dev/null +++ b/Assets/Styles/GLQuake/GLQuake.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d187fe54fb9a3e047bf4cec083877e72 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles/GLQuake/Materials.meta b/Assets/Styles/GLQuake/Materials.meta new file mode 100644 index 0000000..b7278d2 --- /dev/null +++ b/Assets/Styles/GLQuake/Materials.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 135077c9e6757bf4299c007826ead037 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat b/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat new file mode 100644 index 0000000..868e641 --- /dev/null +++ b/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat @@ -0,0 +1,128 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: GLQuake_Entity + m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3} + m_ShaderKeywords: _RECEIVE_SHADOWS_OFF + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaClip: 0 + - _Blend: 0 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossinessSource: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 0 + - _Shininess: 0 + - _Smoothness: 0.5 + - _SmoothnessSource: 0 + - _SmoothnessTextureChannel: 0 + - _SpecSource: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] +--- !u!114 &8101105055909889178 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 4 diff --git a/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat.meta b/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat.meta new file mode 100644 index 0000000..468aea3 --- /dev/null +++ b/Assets/Styles/GLQuake/Materials/GLQuake_Entity.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4d7703ac1adf3534f89b4041b779ff5e +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Styles/GLQuake/Materials/GLQuake_World.mat b/Assets/Styles/GLQuake/Materials/GLQuake_World.mat new file mode 100644 index 0000000..8ee7f2b --- /dev/null +++ b/Assets/Styles/GLQuake/Materials/GLQuake_World.mat @@ -0,0 +1,128 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &-538773200983810463 +MonoBehaviour: + m_ObjectHideFlags: 11 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: d0353a89b1f911e48b9e16bdc9f2e058, type: 3} + m_Name: + m_EditorClassIdentifier: + version: 4 +--- !u!21 &2100000 +Material: + serializedVersion: 6 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: GLQuake_World + m_Shader: {fileID: 4800000, guid: 8d2bb70cbf9db8d4da26e15b26e74248, type: 3} + m_ShaderKeywords: _RECEIVE_SHADOWS_OFF + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: 2000 + stringTagMap: + RenderType: Opaque + disabledShaderPasses: [] + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _BaseMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _SpecGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_Lightmaps: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_LightmapsInd: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - unity_ShadowMasks: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Floats: + - _AlphaClip: 0 + - _Blend: 0 + - _BumpScale: 1 + - _ClearCoatMask: 0 + - _ClearCoatSmoothness: 0 + - _Cull: 2 + - _Cutoff: 0.5 + - _DetailAlbedoMapScale: 1 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnvironmentReflections: 1 + - _GlossMapScale: 0 + - _Glossiness: 0 + - _GlossinessSource: 0 + - _GlossyReflections: 0 + - _Metallic: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.005 + - _QueueOffset: 0 + - _ReceiveShadows: 0 + - _Shininess: 0 + - _Smoothness: 0.5 + - _SmoothnessSource: 0 + - _SmoothnessTextureChannel: 0 + - _SpecSource: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _Surface: 0 + - _WorkflowMode: 1 + - _ZWrite: 1 + m_Colors: + - _BaseColor: {r: 1, g: 1, b: 1, a: 1} + - _Color: {r: 1, g: 1, b: 1, a: 1} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _SpecColor: {r: 0.19999996, g: 0.19999996, b: 0.19999996, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Styles/GLQuake/Materials/GLQuake_World.mat.meta b/Assets/Styles/GLQuake/Materials/GLQuake_World.mat.meta new file mode 100644 index 0000000..e7dcdc9 --- /dev/null +++ b/Assets/Styles/GLQuake/Materials/GLQuake_World.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: fcbaf32c00bea2344bbb1419c61364b6 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: