浏览代码

decals working on transparency

/main
Paul Melamed 7 年前
当前提交
8668ed75
共有 11 个文件被更改,包括 172 次插入64 次删除
  1. 64
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs
  2. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  3. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs
  4. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs
  5. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs
  6. 16
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl
  7. 6
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.hlsl
  8. 15
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalData.hlsl
  9. 103
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalUtilities.hlsl
  10. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl
  11. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl

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


}
private static readonly int m_NormalToWorldID = Shader.PropertyToID("normalToWorld");
private static readonly int m_DecalAtlasID = Shader.PropertyToID("_DecalAtlas");
private static MaterialPropertyBlock m_PropertyBlock = new MaterialPropertyBlock();
private const int kDecalBlockSize = 128;

static public Matrix4x4[] m_InstanceNormalToWorld = new Matrix4x4[kDrawIndexedBatchSize];
static public float[] m_BoundingDistances = new float[1];
private const int kMaxClusteredDecals = 2048;
static public DecalData[] m_ClusteredDecalData = new DecalData[kMaxClusteredDecals];
static public int m_TotalClusteredDecals = 0;
private void InitializeMaterialValues()
{
m_DiffuseTexture = m_Material.GetTexture("_BaseColorMap");
m_NormalTexture = m_Material.GetTexture("_NormalMap");
m_MaskTexture = m_Material.GetTexture("_MaskMap");
m_Blend = m_Material.GetFloat("_DecalBlend");
}
m_DiffuseTexture = material.GetTexture("_BaseColorMap");
m_NormalTexture = material.GetTexture("_NormalMap");
m_MaskTexture = material.GetTexture("_MaskMap");
InitializeMaterialValues();
}
private BoundingSphere GetDecalProjectBoundingSphere(Matrix4x4 decalToWorld)

m_CachedNormalToWorld[decal.CullIndex] = decalRotation;
// draw distance can't be more than global draw distance
m_CachedDrawDistances[decal.CullIndex].x = decal.m_DrawDistance < DecalSystem.instance.DrawDistance
m_CachedDrawDistances[decal.CullIndex].x = decal.m_DrawDistance < instance.DrawDistance
: DecalSystem.instance.DrawDistance;
: instance.DrawDistance;
m_CachedDrawDistances[decal.CullIndex].y = decal.m_FadeScale;
m_BoundingSpheres[decal.CullIndex] = GetDecalProjectBoundingSphere(m_CachedTransforms[decal.CullIndex]);
}

{
if ((m_DiffuseTexIndex == -1) && (m_DiffuseTexture != null))
{
m_DiffuseTexIndex = DecalSystem.instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture);
m_DiffuseTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_DiffuseTexture);
m_NormalTexIndex = DecalSystem.instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture);
m_NormalTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_NormalTexture);
m_MaskTexIndex = DecalSystem.instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture);
m_MaskTexIndex = instance.TextureAtlas.FetchSlice(cmd, m_MaskTexture);
}
}

{
DecalSystem.instance.TextureAtlas.RemoveEntryFromSlice(m_DiffuseTexture);
instance.TextureAtlas.RemoveEntryFromSlice(m_DiffuseTexture);
DecalSystem.instance.TextureAtlas.RemoveEntryFromSlice(m_NormalTexture);
instance.TextureAtlas.RemoveEntryFromSlice(m_NormalTexture);
DecalSystem.instance.TextureAtlas.RemoveEntryFromSlice(m_MaskTexture);
instance.TextureAtlas.RemoveEntryFromSlice(m_MaskTexture);
}
}

return;
InitializeMaterialValues(); // refresh in case they changed in the UI
UpdateTextureCache(cmd);
var worldToView = Matrix4x4.Scale(new Vector3(1, 1, -1)) * camera.camera.worldToCameraMatrix;
int instanceCount = 0;

{
m_InstanceMatrices[instanceCount] = m_CachedTransforms[decalIndex];
m_InstanceNormalToWorld[instanceCount] = m_CachedNormalToWorld[decalIndex];
float fadeFactor = (cullDistance - distanceToDecal) / (cullDistance * (1.0f - m_CachedDrawDistances[decalIndex].y));
m_InstanceNormalToWorld[instanceCount].m03 = fadeFactor; // rotation only matrix so 3rd column can be used to pass some values
float fadeFactor = Mathf.Clamp((cullDistance - distanceToDecal) / (cullDistance * (1.0f - m_CachedDrawDistances[decalIndex].y)), 0.0f, 1.0f);
m_InstanceNormalToWorld[instanceCount].m03 = fadeFactor * m_Blend; // rotation only matrix so 3rd column can be used to pass some values
m_InstanceNormalToWorld[instanceCount].m13 = m_DiffuseTexIndex;
m_InstanceNormalToWorld[instanceCount].m23 = m_NormalTexIndex;
m_InstanceNormalToWorld[instanceCount].m33 = m_MaskTexIndex;
if (m_TotalClusteredDecals < kMaxClusteredDecals)
{
lightLoop.GetDecalVolumeDataAndBound(m_CachedTransforms[decalIndex], worldToView);
m_ClusteredDecalData[m_TotalClusteredDecals].normalToWorld = m_InstanceNormalToWorld[instanceCount];
m_ClusteredDecalData[m_TotalClusteredDecals].diffuseIndex = m_DiffuseTexIndex;
m_ClusteredDecalData[m_TotalClusteredDecals].normalIndex = m_NormalTexIndex;
m_ClusteredDecalData[m_TotalClusteredDecals].maskIndex = m_MaskTexIndex;
m_TotalClusteredDecals++;
}
DecalData decalData = new DecalData();
decalData.worldToDecal = m_CachedTransforms[decalIndex].inverse;
decalData.normalToWorld = m_InstanceNormalToWorld[instanceCount];
lightLoop.GetDecalVolumeDataAndBound(decalData, m_CachedTransforms[decalIndex], worldToView);
instanceCount++;
if (instanceCount == kDrawIndexedBatchSize)
{

private Texture m_DiffuseTexture = null;
private Texture m_NormalTexture = null;
private Texture m_MaskTexture = null;
private float m_Blend = 0;
private int m_DiffuseTexIndex = -1;
private int m_NormalTexIndex = -1;
private int m_MaskTexIndex = -1;

if (m_DecalMesh == null)
m_DecalMesh = CoreUtils.CreateCubeMesh(kMin, kMax);
m_TotalClusteredDecals = 0;
}
public void SetAtlas(CommandBuffer cmd)
{
cmd.SetGlobalTexture(m_DecalAtlasID, m_DecalAtlas.GetTexCache());
}
}
}

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


DecalSystem.instance.Render(renderContext, camera, cmd, m_LightLoop);
m_DbufferManager.UnSetHTile(cmd);
m_DbufferManager.SetHTileTexture(cmd);
DecalSystem.instance.SetAtlas(cmd);
}
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDStringConstants.cs


public static readonly int _EnvLightCount = Shader.PropertyToID("_EnvLightCount");
public static readonly int _EnvProxyCount = Shader.PropertyToID("_EnvProxyCount");
public static readonly int _ShadowDatas = Shader.PropertyToID("_ShadowDatas");
public static readonly int _DecalCount = Shader.PropertyToID("_DecalCount");
public static readonly int _DecalDatas = Shader.PropertyToID("_DecalDatas");
public static readonly int _NumTileFtplX = Shader.PropertyToID("_NumTileFtplX");
public static readonly int _NumTileFtplY = Shader.PropertyToID("_NumTileFtplY");
public static readonly int _NumTileClusteredX = Shader.PropertyToID("_NumTileClusteredX");

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Lighting/LightLoop/LightLoop.cs


public const int k_MaxLightsOnScreen = k_MaxDirectionalLightsOnScreen + k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnScreen;
public const int k_MaxEnvLightsOnScreen = 64;
public const int k_MaxShadowOnScreen = 16;
public const int k_MaxDecalsOnScreen = 10;
public const int k_MaxCascadeCount = 4; //Should be not less than m_Settings.directionalLightCascadeCount;
static readonly Vector3 k_BoxCullingExtentThreshold = Vector3.one * 0.01f;

static ComputeBuffer s_EnvLightDatas = null;
static ComputeBuffer s_shadowDatas = null;
static ComputeBuffer s_DecalDatas = null;
static Texture2DArray s_DefaultTexture2DArray;
static Cubemap s_DefaultTextureCube;

public List<LightData> lights;
public List<EnvLightData> envLights;
public List<ShadowData> shadows;
public List<DecalData> decals;
public int decalCount;
public void Clear()
{

shadows.Clear();
decalCount = 0;
decals.Clear();
bounds.Clear();
lightVolumes.Clear();

lights = new List<LightData>();
envLights = new List<EnvLightData>();
shadows = new List<ShadowData>();
decalCount = 0;
decals = new List<DecalData>();
bounds = new List<SFiniteLightBound>();
lightVolumes = new List<LightVolumeData>();

s_LightDatas = new ComputeBuffer(k_MaxPunctualLightsOnScreen + k_MaxAreaLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(LightData)));
s_EnvLightDatas = new ComputeBuffer(k_MaxEnvLightsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(EnvLightData)));
s_shadowDatas = new ComputeBuffer(k_MaxCascadeCount + k_MaxShadowOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(ShadowData)));
s_DecalDatas = new ComputeBuffer(k_MaxDecalsOnScreen, System.Runtime.InteropServices.Marshal.SizeOf(typeof(DecalData)));
GlobalLightLoopSettings gLightLoopSettings = hdAsset.GetRenderPipelineSettings().lightLoopSettings;
m_CookieTexArray = new TextureCache2D();

CoreUtils.SafeRelease(s_LightDatas);
CoreUtils.SafeRelease(s_EnvLightDatas);
CoreUtils.SafeRelease(s_shadowDatas);
CoreUtils.SafeRelease(s_DecalDatas);
if (m_ReflectionProbeCache != null)
{

return true;
}
public void GetDecalVolumeDataAndBound(Matrix4x4 decalToWorld, Matrix4x4 worldToView)
public void GetDecalVolumeDataAndBound(DecalData decalData, Matrix4x4 decalToWorld, Matrix4x4 worldToView)
{
var bound = new SFiniteLightBound();
var lightVolumeData = new LightVolumeData();

m_lightList.bounds.Add(bound);
m_lightList.lightVolumes.Add(lightVolumeData);
m_lightList.decals.Add(decalData);
m_lightCount++;
}

s_LightDatas.SetData(m_lightList.lights);
s_EnvLightDatas.SetData(m_lightList.envLights);
s_shadowDatas.SetData(m_lightList.shadows);
s_DecalDatas.SetData(m_lightList.decals);
// These two buffers have been set in Rebuild()
s_ConvexBoundsBuffer.SetData(m_lightList.bounds);

cmd.SetGlobalInt(HDShaderIDs._AreaLightCount, m_areaLightCount);
cmd.SetGlobalBuffer(HDShaderIDs._EnvLightDatas, s_EnvLightDatas);
cmd.SetGlobalInt(HDShaderIDs._EnvLightCount, m_lightList.envLights.Count);
cmd.SetGlobalBuffer(HDShaderIDs._DecalDatas, s_DecalDatas);
cmd.SetGlobalInt(HDShaderIDs._DecalCount, m_lightList.decals.Count);
cmd.SetGlobalBuffer(HDShaderIDs._ShadowDatas, s_shadowDatas);
cmd.SetGlobalInt(HDShaderIDs._NumTileFtplX, GetNumTileFtplX(camera));

8
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs


}
}
// normalToWorld.m03 - total blend factor
// normalToWorld.m13 - diffuse texture index in atlas
// normalToWorld.m23 - normal texture index in atlas
// normalToWorld.m33 - mask texture index in atlas
public Matrix4x4 worldToDecal;
public int diffuseIndex;
public int normalIndex;
public int maskIndex;
};
}

16
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl


// PackingRules = Exact
struct DecalData
{
float4x4 worldToDecal;
int diffuseIndex;
int normalIndex;
int maskIndex;
};
//

{
return value.normalToWorld;
}
int GetDiffuseIndex(DecalData value)
{
return value.diffuseIndex;
}
int GetNormalIndex(DecalData value)
{
return value.normalIndex;
}
int GetMaskIndex(DecalData value)
{
return value.maskIndex;
}
//

6
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.hlsl


RW_TEXTURE2D(float, _DecalHTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
TEXTURE2D(_DecalHTileTexture);
uint _DecalCount;
StructuredBuffer<DecalData> _DecalDatas;
TEXTURE2D_ARRAY(_DecalAtlas);
SAMPLER(sampler_DecalAtlas);
// Must be in sync with RT declared in HDRenderPipeline.cs ::Rebuild
void EncodeIntoDBuffer( DecalSurfaceData surfaceData,
out DBufferType0 outDBuffer0,

15
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalData.hlsl


#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "CoreRP/ShaderLibrary/Sampling/SampleUVMapping.hlsl"
#if defined(UNITY_NO_DXT5nm)
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#else
#define UNPACK_NORMAL_FUNC UnpackNormalmapRGorAG
#endif
void GetSurfaceData(float2 texCoordDS, float4x4 decalToWorld, out DecalSurfaceData surfaceData)
{
surfaceData.baseColor = float4(0,0,0,0);

float totalBlend = _DecalBlend * clamp(decalToWorld[0][3], 0.0f, 1.0f);
float totalBlend = clamp(decalToWorld[0][3], 0.0f, 1.0f);
UVMapping texCoord;
ZERO_INITIALIZE(UVMapping, texCoord);
texCoord.uv = texCoordDS.xy;
surfaceData.normalWS.xyz = mul((float3x3)decalToWorld, SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, sampler_NormalMap, texCoord, 1)) * 0.5f + 0.5f;
surfaceData.normalWS.xyz = mul((float3x3)decalToWorld, UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, texCoordDS))) * 0.5f + 0.5f;
surfaceData.normalWS.w = totalBlend;
surfaceData.HTileMask |= DBUFFERHTILEBIT_NORMAL;
#endif

surfaceData.HTileMask |= DBUFFERHTILEBIT_MASK;
#endif
}
#undef UNPACK_NORMAL_FUNC

103
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalUtilities.hlsl


DECLARE_DBUFFER_TEXTURE(_DBufferTexture);
void AddDecalContribution(uint2 unPositionSS, inout SurfaceData surfaceData)
DecalData FetchDecal(uint start, uint i)
{
#ifdef LIGHTLOOP_TILE_PASS
int j = FetchIndex(start, i);
#else
int j = start + i;
#endif
return _DecalDatas[j];
}
#if defined(UNITY_NO_DXT5nm)
#define UNPACK_NORMAL_FUNC UnpackNormalRGB
#else
#define UNPACK_NORMAL_FUNC UnpackNormalmapRGorAG
#endif
void ApplyBlendNormal(inout float4 dst, inout int matMask, float2 texCoords, int sliceIndex, int mapMask, float3x3 decalToWorld, float blend)
{
float4 src;
src.xyz = mul(decalToWorld, UNPACK_NORMAL_FUNC(SAMPLE_TEXTURE2D_ARRAY(_DecalAtlas, sampler_DecalAtlas, texCoords, sliceIndex))) * 0.5f + 0.5f;
src.w = blend;
dst.xyz = src.xyz * src.w + dst.xyz * (1.0f - src.w);
dst.w = dst.w * (1.0f - src.w);
matMask |= mapMask;
}
#undef UNPACK_NORMAL_FUNC
void ApplyBlendDiffuse(inout float4 dst, inout int matMask, float2 texCoords, int sliceIndex, int mapMask, float blend)
{
float4 src = SAMPLE_TEXTURE2D_ARRAY(_DecalAtlas, sampler_DecalAtlas, texCoords, sliceIndex);
src.w *= blend;
dst.xyz = src.xyz * src.w + dst.xyz * (1.0f - src.w);
dst.w = dst.w * (1.0f - src.w);
matMask |= mapMask;
}
void ApplyBlendMask(inout float4 dst, inout int matMask, float2 texCoords, int sliceIndex, int mapMask, float blend)
{
float4 src = SAMPLE_TEXTURE2D_ARRAY(_DecalAtlas, sampler_DecalAtlas, texCoords, sliceIndex);
src.z = src.w;
src.w = blend;
dst.xyz = src.xyz * src.w + dst.xyz * (1.0f - src.w);
dst.w = dst.w * (1.0f - src.w);
matMask |= mapMask;
}
void AddDecalContribution(PositionInputs posInput, inout SurfaceData surfaceData)
DecalSurfaceData decalSurfaceData;
uint mask = 0;
FETCH_DBUFFER(DBuffer, _DBufferTexture, unPositionSS);
DecalSurfaceData decalSurfaceData;
FETCH_DBUFFER(DBuffer, _DBufferTexture, posInput.positionSS);
#ifdef _SURFACE_TYPE_TRANSPARENT
uint decalCount, decalStart;
DBuffer0 = float4(0.0f, 0.0f, 0.0f, 1.0f);
DBuffer1 = float4(0.5f, 0.5f, 0.5f, 1.0f);
DBuffer2 = float4(0.0f, 0.0f, 0.0f, 1.0f);
#ifdef LIGHTLOOP_TILE_PASS
GetCountAndStart(posInput, LIGHTCATEGORY_DECAL, decalStart, decalCount);
#else
decalCount = _DecalCount;
decalStart = 0;
#endif
float3 positionWS = GetAbsolutePositionWS(posInput.positionWS);
uint i = 0;
for (i = 0; i < decalCount; i++)
{
DecalData decalData = FetchDecal(decalStart, i);
float3 positionDS = mul(decalData.worldToDecal, float4(positionWS, 1.0)).xyz;
positionDS = positionDS * float3(1.0, -1.0, 1.0) + float3(0.5, 0.0f, 0.5);
float decalBlend = decalData.normalToWorld[0][3];
int diffuseIndex = decalData.normalToWorld[1][3];
int normalIndex = decalData.normalToWorld[2][3];
int maskIndex = decalData.normalToWorld[3][3];
if((all(positionDS.xyz > 0.0f) && all(1.0f - positionDS.xyz > 0.0f)))
{
if(diffuseIndex != -1)
{
ApplyBlendDiffuse(DBuffer0, mask, positionDS.xz, diffuseIndex, DBUFFERHTILEBIT_DIFFUSE, decalBlend);
}
if(normalIndex != -1)
{
ApplyBlendNormal(DBuffer1, mask, positionDS.xz, normalIndex, DBUFFERHTILEBIT_NORMAL, (float3x3)decalData.normalToWorld, decalBlend);
}
if(maskIndex != -1)
{
ApplyBlendMask(DBuffer2, mask, positionDS.xz, maskIndex, DBUFFERHTILEBIT_MASK, decalBlend);
}
}
}
#else
mask = UnpackByte(LOAD_TEXTURE2D(_DecalHTileTexture, posInput.positionSS / 8));
#endif
//uint mask = UnpackByte(_DecalHTile[unPositionSS / 8]);
uint mask = UnpackByte(LOAD_TEXTURE2D(_DecalHTileTexture, unPositionSS / 8));
if(mask & DBUFFERHTILEBIT_NORMAL)
{
surfaceData.normalWS.xyz = normalize(surfaceData.normalWS.xyz * decalSurfaceData.normalWS.w + decalSurfaceData.normalWS.xyz);

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/LayeredLit/LayeredLitData.hlsl


#endif
#ifndef _DISABLE_DBUFFER
AddDecalContribution(posInput.positionSS, surfaceData);
AddDecalContribution(posInput, surfaceData);
#endif
#if defined(DEBUG_DISPLAY)

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/LitData.hlsl


surfaceData.tangentWS = Orthonormalize(surfaceData.tangentWS, surfaceData.normalWS);
#ifndef _DISABLE_DBUFFER
AddDecalContribution(posInput.positionSS, surfaceData);
AddDecalContribution(posInput, surfaceData);
#endif
#if defined(DEBUG_DISPLAY)

正在加载...
取消
保存