4 using UnityEngine.Rendering;
6 namespace UnityEngine.Experimental.Rendering.HDPipeline
10 [CanEditMultipleObjects]
12 public partial class DecalProjectorComponent : MonoBehaviour
14 internal static readonly Quaternion k_MinusYtoZRotation = Quaternion.Euler(-90, 0, 0);
17 private Material m_Material = null;
18 public Material material
32 private float m_DrawDistance = 1000.0f;
33 public float drawDistance
37 return m_DrawDistance;
41 m_DrawDistance = Mathf.Max(0f, value);
48 private float m_FadeScale = 0.9f;
49 public float fadeScale
57 m_FadeScale = Mathf.Clamp01(value);
63 private Vector2 m_UVScale = new Vector2(1, 1);
64 public Vector2 uvScale
78 private Vector2 m_UVBias = new Vector2(0, 0);
93 private bool m_AffectsTransparency = false;
94 public bool affectsTransparency
98 return m_AffectsTransparency;
102 m_AffectsTransparency = value;
108 private Vector3 m_Offset = new Vector3(0, -0.5f, 0);
109 public Vector3 offset
123 Vector3 m_Size = new Vector3(1, 1, 1);
139 private float m_FadeFactor = 1.0f;
140 public float fadeFactor
148 m_FadeFactor = Mathf.Clamp01(value);
153 private Material m_OldMaterial = null;
154 private DecalSystem.DecalHandle m_Handle = null;
157 /// <summary>current rotation in a way the DecalSystem will be able to use it</summary>
158 internal Quaternion rotation => transform.rotation * k_MinusYtoZRotation;
159 /// <summary>current position in a way the DecalSystem will be able to use it</summary>
160 internal Vector3 position => transform.position;
161 /// <summary>current size in a way the DecalSystem will be able to use it</summary>
162 internal Vector3 decalSize => new Vector3(m_Size.x, m_Size.z, m_Size.y);
163 /// <summary>current size in a way the DecalSystem will be able to use it</summary>
164 internal Vector3 decalOffset => new Vector3(m_Offset.x, -m_Offset.z, m_Offset.y);
165 /// <summary>current uv parameters in a way the DecalSystem will be able to use it</summary>
166 internal Vector4 uvScaleBias => new Vector4(m_UVScale.x, m_UVScale.y, m_UVBias.x, m_UVBias.y);
168 public DecalSystem.DecalHandle Handle
172 return this.m_Handle;
176 this.m_Handle = value;
180 public void OnEnable()
182 if (m_Material == null)
185 var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
186 m_Material = hdrp != null ? hdrp.GetDefaultDecalMaterial() : null;
192 if (m_Handle != null)
194 DecalSystem.instance.RemoveDecal(m_Handle);
198 Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize);
199 m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, m_FadeFactor);
202 public void OnDisable()
204 if (m_Handle != null)
206 DecalSystem.instance.RemoveDecal(m_Handle);
211 // Declare the method signature of the delegate to call.
212 public delegate void OnMaterialChangeDelegate();
214 // Declare the event to which editor code will hook itself.
215 public event OnMaterialChangeDelegate OnMaterialChange;
217 public void OnValidate()
219 if (m_Handle != null) // don't do anything if OnEnable hasn't been called yet when scene is loading.
221 Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize);
222 // handle material changes, because decals are stored as sets sorted by material, if material changes decal needs to be removed and re-added to that it goes into correct set
223 if (m_OldMaterial != m_Material)
225 DecalSystem.instance.RemoveDecal(m_Handle);
226 m_Handle = DecalSystem.instance.AddDecal(position, rotation, Vector3.one, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Material, gameObject.layer, m_FadeFactor);
227 m_OldMaterial = m_Material;
229 if (!DecalSystem.IsHDRenderPipelineDecal(m_Material.shader.name)) // non HDRP/decal shaders such as shader graph decal do not affect transparency
231 m_AffectsTransparency = false;
234 // notify the editor that material has changed so it can update the shader foldout
235 if (OnMaterialChange != null)
240 else // no material change, just update whatever else changed
242 DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, m_FadeFactor);
247 public void LateUpdate()
249 if (m_Handle != null)
251 if (transform.hasChanged == true)
253 Matrix4x4 sizeOffset = Matrix4x4.Translate(decalOffset) * Matrix4x4.Scale(decalSize);
254 DecalSystem.instance.UpdateCachedData(position, rotation, sizeOffset, m_DrawDistance, m_FadeScale, uvScaleBias, m_AffectsTransparency, m_Handle, gameObject.layer, m_FadeFactor);
255 transform.hasChanged = false;
260 public bool IsValid()
262 // don't draw if no material or if material is the default decal material (empty)
263 if (m_Material == null)
267 var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
268 if ((hdrp != null) && (m_Material == hdrp.GetDefaultDecalMaterial()))