浏览代码

Backport: Decals/api change - Fix issue with decal never removed

/2018.1
sebastienlagarde 7 年前
当前提交
a0400775
共有 2 个文件被更改,包括 79 次插入94 次删除
  1. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  2. 141
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs


public float m_DrawDistance = 1000.0f;
public float m_FadeScale = 0.9f;
private Material m_OldMaterial = null;
public const int kInvalidIndex = -1;
private int m_CullIndex = kInvalidIndex;
private DecalSystem.DecalHandle m_Handle = null;
public int CullIndex
public DecalSystem.DecalHandle Handle
return this.m_CullIndex;
return this.m_Handle;
this.m_CullIndex = value;
this.m_Handle = value;
}
}

m_Material = hdrp != null ? hdrp.GetDefaultDecalMaterial() : null;
}
DecalSystem.instance.AddDecal(this);
}
public void Start()
{
DecalSystem.instance.AddDecal(this);
if(m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
DecalSystem.instance.RemoveDecal(this);
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = null;
}
// Declare the method signature of the delegate to call.

// handle material changes
if (m_OldMaterial != m_Material)
{
Material tempMaterial = m_Material;
m_Material = m_OldMaterial;
if(m_Material != null)
DecalSystem.instance.RemoveDecal(this);
m_Material = tempMaterial;
DecalSystem.instance.AddDecal(this);
if( m_Handle != null)
DecalSystem.instance.RemoveDecal(m_Handle);
m_Handle = DecalSystem.instance.AddDecal(transform, m_DrawDistance, m_FadeScale, m_Material);
m_OldMaterial = m_Material;
// notify the editor that material has changed so it can update the shader foldout

{
DrawGizmo(true);
// if this object is selected there is a chance the transform was changed so update culling info
DecalSystem.instance.UpdateCachedData(this);
DecalSystem.instance.UpdateCachedData(transform, m_DrawDistance, m_FadeScale, m_Handle);
}
public void OnDrawGizmos()

141
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs


{
public class DecalSystem
{
public const int kInvalidIndex = -1;
public class DecalHandle
{
public DecalHandle(int index, int materialID)
{
m_MaterialID = materialID;
m_Index = index;
}
public static bool IsValid(DecalHandle handle)
{
if (handle == null)
return false;
if (handle.m_Index == kInvalidIndex)
return false;
return true;
}
public int m_MaterialID; // identifies decal set
public int m_Index; // identifies decal within the set
}
static DecalSystem m_Instance;
static public DecalSystem instance
{

return m_DecalAtlas;
}
}
public Camera CurrentCamera
{

return res;
}
public void UpdateCachedData(DecalProjectorComponent decal)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
m_CachedDecalToWorld[decal.CullIndex] = decal.transform.localToWorldMatrix;
int index = handle.m_Index;
m_CachedDecalToWorld[index] = transform.localToWorldMatrix;
Matrix4x4 decalRotation = Matrix4x4.Rotate(decal.transform.rotation);
Matrix4x4 decalRotation = Matrix4x4.Rotate(transform.rotation);
// z/y axis swap for normal to decal space, Unity is column major
float y0 = decalRotation.m01;
float y1 = decalRotation.m11;

decalRotation.m12 = y1;
decalRotation.m22 = y2;
m_CachedNormalToWorld[decal.CullIndex] = decalRotation;
m_CachedNormalToWorld[index] = decalRotation;
m_CachedDrawDistances[decal.CullIndex].x = decal.m_DrawDistance < instance.DrawDistance
? decal.m_DrawDistance
m_CachedDrawDistances[index].x = drawDistance < instance.DrawDistance
? drawDistance
m_CachedDrawDistances[decal.CullIndex].y = decal.m_FadeScale;
m_BoundingSpheres[decal.CullIndex] = GetDecalProjectBoundingSphere(m_CachedDecalToWorld[decal.CullIndex]);
m_CachedDrawDistances[index].y = fadeScale;
m_BoundingSpheres[index] = GetDecalProjectBoundingSphere(m_CachedDecalToWorld[index]);
public void AddDecal(DecalProjectorComponent decal)
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, int materialID)
if (m_DecalsCount == m_Decals.Length)
if (m_DecalsCount == m_Handles.Length)
DecalProjectorComponent[] newDecals = new DecalProjectorComponent[m_DecalsCount + kDecalBlockSize];
DecalHandle[] newHandles = new DecalHandle[m_DecalsCount + kDecalBlockSize];
BoundingSphere[] newSpheres = new BoundingSphere[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedTransforms = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedNormalToWorld = new Matrix4x4[m_DecalsCount + kDecalBlockSize];

m_Decals.CopyTo(newDecals, 0);
m_Handles.CopyTo(newHandles, 0);
m_Decals = newDecals;
m_Handles = newHandles;
m_BoundingSpheres = newSpheres;
m_CachedDecalToWorld = newCachedTransforms;
m_CachedNormalToWorld = newCachedNormalToWorld;

m_Decals[m_DecalsCount] = decal;
m_Decals[m_DecalsCount].CullIndex = m_DecalsCount;
UpdateCachedData(m_Decals[m_DecalsCount]);
DecalHandle decalHandle = new DecalHandle(m_DecalsCount, materialID);
m_Handles[m_DecalsCount] = decalHandle;
UpdateCachedData(transform, drawDistance, fadeScale, decalHandle);
return decalHandle;
public void RemoveDecal(DecalProjectorComponent decal)
public void RemoveDecal(DecalHandle handle)
int removeAtIndex = decal.CullIndex;
int removeAtIndex = handle.m_Index;
m_Decals[removeAtIndex] = m_Decals[m_DecalsCount - 1]; // move the last decal in list
m_Decals[removeAtIndex].CullIndex = removeAtIndex;
m_Decals[m_DecalsCount - 1] = null;
m_Handles[removeAtIndex] = m_Handles[m_DecalsCount - 1]; // move the last decal in list
m_Handles[removeAtIndex].m_Index = removeAtIndex;
m_Handles[m_DecalsCount - 1] = null;
// update the bounding spheres array
// update cached data
decal.CullIndex = DecalProjectorComponent.kInvalidIndex;
handle.m_Index = kInvalidIndex;
}
public void BeginCull()

private void GetDecalVolumeDataAndBound(Matrix4x4 decalToWorld, Matrix4x4 worldToView)
{
var influenceX = decalToWorld.GetColumn(0) * 0.5f;
var influenceY = decalToWorld.GetColumn(1) * 0.5f;
var influenceZ = decalToWorld.GetColumn(2) * 0.5f;

normalToWorldBatch[instanceCount].m23 = m_NormalTexIndex;
normalToWorldBatch[instanceCount].m33 = m_MaskTexIndex;
// clustered forward data
m_DecalDatas[m_DecalDatasCount].worldToDecal = decalToWorldBatch[instanceCount].inverse;
m_DecalDatas[m_DecalDatasCount].normalToWorld = normalToWorldBatch[instanceCount];

void UpdateTextureCache(CommandBuffer cmd)
{
if (m_DiffuseTexture != null)
{
m_DiffuseTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture);
}
else
{
m_DiffuseTexIndex = -1;
}
if (m_NormalTexture != null)
{
m_NormalTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture);
}
else
{
m_NormalTexIndex = -1;
}
if (m_MaskTexture != null)
{
m_MaskTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture);
}
else
{
m_MaskTexIndex = -1;
}
m_DiffuseTexIndex = (m_DiffuseTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture) : -1;
m_NormalTexIndex = (m_NormalTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture) : -1;
m_MaskTexIndex = (m_MaskTexture != null) ? instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture) : -1;
}
public void RemoveFromTextureCache()

private CullingGroup m_CullingGroup = null;
private BoundingSphere[] m_BoundingSpheres = new BoundingSphere[kDecalBlockSize];
private DecalProjectorComponent[] m_Decals = new DecalProjectorComponent[kDecalBlockSize];
private DecalHandle[] m_Handles = new DecalHandle[kDecalBlockSize];
private int[] m_ResultIndices = new int[kDecalBlockSize];
private int m_NumResults = 0;
private int m_DecalsCount = 0;

private int m_MaskTexIndex = -1;
}
public void AddDecal(DecalProjectorComponent decal)
{
if (decal.CullIndex != DecalProjectorComponent.kInvalidIndex) //do not add the same decal more than once
return;
if(!decal.IsValid())
return;
public DecalHandle AddDecal(Transform transform, float drawDistance, float fadeScale, Material material)
{
int key = decal.m_Material.GetInstanceID();
int key = material.GetInstanceID();
decalSet = new DecalSet(decal.m_Material);
decalSet = new DecalSet(material);
decalSet.AddDecal(decal);
return decalSet.AddDecal(transform, drawDistance, fadeScale, key);
public void RemoveDecal(DecalProjectorComponent decal)
public void RemoveDecal(DecalHandle handle)
if (decal.CullIndex == DecalProjectorComponent.kInvalidIndex) // check if we have this decal
return;
if (!DecalHandle.IsValid(handle))
return;
int key = decal.m_Material.GetInstanceID();
int key = handle.m_MaterialID;
decalSet.RemoveDecal(decal);
decalSet.RemoveDecal(handle);
if (decalSet.Count == 0)
{
decalSet.RemoveFromTextureCache();

}
public void UpdateCachedData(DecalProjectorComponent decal)
public void UpdateCachedData(Transform transform, float drawDistance, float fadeScale, DecalHandle handle)
if (decal.CullIndex == DecalProjectorComponent.kInvalidIndex) // check if we have this decal
if(!DecalHandle.IsValid(handle))
int key = decal.m_Material.GetInstanceID();
int key = handle.m_MaterialID;
decalSet.UpdateCachedData(decal);
decalSet.UpdateCachedData(transform, drawDistance, fadeScale, handle);
}
}

pair.Value.EndCull();
}
}
// need a better way than passing light loop here
public void RenderIntoDBuffer(CommandBuffer cmd)
{
if (m_DecalMesh == null)

正在加载...
取消
保存