浏览代码

Merge pull request #885 from Unity-Technologies/prototype/decals_gpu_optimization

Prototype/decals gpu optimization
/main
GitHub 7 年前
当前提交
f3a96513
共有 11 个文件被更改,包括 132 次插入18 次删除
  1. 14
      ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs
  2. 18
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  3. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs
  4. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs
  5. 39
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs
  6. 8
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs
  7. 7
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl
  8. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.hlsl
  9. 21
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalUtilities.hlsl
  10. 12
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs
  11. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassDBuffer.hlsl

14
ScriptableRenderPipeline/Core/CoreRP/CoreUtils.cs


mesh.triangles = triangles;
return mesh;
}
public static void ResizeHTile(ref RenderTexture hTile, ref RenderTargetIdentifier hTileRT, RenderTextureDescriptor desc)
{
// We must use a RenderTexture and not GetTemporaryRT() as currently Unity only aloow to bind a RenderTexture for a UAV in a pixel shader
// We use 8x8 tiles in order to match the native GCN HTile as closely as possible.
desc.width = (desc.width + 7) / 8;
desc.height = (desc.height + 7) / 8;
// TODO: This fails allocation with MSAA enabled?
hTile = CreateRenderTexture(desc, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
hTile.filterMode = FilterMode.Point;
hTile.enableRandomWrite = true;
hTile.Create();
hTileRT = new RenderTargetIdentifier(hTile);
}
}
}

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


DecalSystem.instance.RemoveDecal(this);
}
// Declare the method signature of the delegate to call.
public delegate void OnMaterialChangeDelegate();
// Declare the event to which editor code will hook itself.
public event OnMaterialChangeDelegate OnMaterialChange;
public void OnValidate()
{
// handle material changes

m_Material = tempMaterial;
DecalSystem.instance.AddDecal(this);
m_OldMaterial = m_Material;
// notify the editor that material has changed so it can update the shader foldout
if (OnMaterialChange != null)
{
OnMaterialChange();
}
}
if (m_Material != null)

public bool IsValid()
{
// don't draw if no material or if material is the default decal material (empty)
var hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if ((hdrp != null) && (m_Material == hdrp.GetDefaultDecalMaterial()))
return false;
return true;
}
}

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


decalRotation.m02 = y0;
decalRotation.m12 = y1;
decalRotation.m22 = y2;
m_CachedNormalToWorld[decal.CullIndex] = decalRotation;
m_BoundingSpheres[decal.CullIndex] = GetDecalProjectBoundingSphere(m_CachedTransforms[decal.CullIndex]);

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs


// Create an instance of the MaterialEditor
m_DecalProjectorComponent = (DecalProjectorComponent)target;
m_MaterialEditor = (MaterialEditor)CreateEditor(m_DecalProjectorComponent.Mat);
m_DecalProjectorComponent.OnMaterialChange += OnMaterialChange;
private void OnDisable()
{
m_DecalProjectorComponent.OnMaterialChange -= OnMaterialChange;
}
public void OnMaterialChange()
{
// Update material editor with the new material
m_MaterialEditor = (MaterialEditor)CreateEditor(m_DecalProjectorComponent.Mat);
}
public override void OnInspectorGUI()
{

39
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipeline.cs


RenderTargetIdentifier[] m_ColorMRTs;
RenderTargetIdentifier[] m_RTIDs = new RenderTargetIdentifier[k_MaxDbuffer];
RenderTexture m_HTile;
RenderTargetIdentifier m_HTileRT;
public void InitDBuffers(RenderTextureDescriptor rtDesc, CommandBuffer cmd)
{
dbufferCount = Decal.GetMaterialDBufferCount();

return m_ColorMRTs;
}
public void ClearNormalTarget(Color clearColor, CommandBuffer cmd)
public void ClearNormalTargetAndHTile(Color clearColor, CommandBuffer cmd)
CoreUtils.SetRenderTarget(cmd, m_HTileRT, ClearFlag.Color, CoreUtils.clearColorAllBlack);
public void SetHTile(int bindSlot, CommandBuffer cmd)
{
cmd.SetRandomWriteTarget(bindSlot, m_HTile);
}
public void UnSetHTile(CommandBuffer cmd)
{
cmd.ClearRandomWriteTargets();
}
}
public void Resize(HDCamera camera)
{
CoreUtils.ResizeHTile(ref m_HTile, ref m_HTileRT, camera.renderTextureDesc);
}
}

if (resolutionChanged || m_CameraDepthStencilBuffer == null)
{
CreateDepthStencilBuffer(hdCamera);
if (m_FrameSettings.enableDBuffer)
{
m_DbufferManager.Resize(hdCamera);
}
if (m_FrameSettings.enableSubsurfaceScattering)
{

{
// setup GBuffer for rendering
CoreUtils.SetRenderTarget(cmd, m_GbufferManager.GetGBuffers(), m_CameraDepthStencilBufferRT);
if (m_FrameSettings.enableDBuffer)
{
m_DbufferManager.SetHTile(m_GbufferManager.gbufferCount, cmd);
}
// Render opaque objects into GBuffer
if (m_CurrentDebugDisplaySettings.IsDebugDisplayEnabled())

RenderOpaqueRenderList(cull, camera, renderContext, cmd, HDShaderPassNames.s_GBufferName, m_currentRendererConfigurationBakedLighting, HDRenderQueue.k_RenderQueue_AllOpaque, m_DepthStateOpaque);
}
}
if (m_FrameSettings.enableDBuffer)
{
m_DbufferManager.UnSetHTile(cmd);
}
}
}

// we need to do a separate clear for normals, because they are cleared to a different color
Color clearColorNormal = new Color(0.5f, 0.5f, 0.5f, 1.0f); // for normals 0.5 is neutral
m_DbufferManager.ClearNormalTarget(clearColorNormal, cmd);
m_DbufferManager.ClearNormalTargetAndHTile(clearColorNormal, cmd);
m_DbufferManager.SetHTile(m_DbufferManager.dbufferCount, cmd);
m_DbufferManager.UnSetHTile(cmd);
}
}

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


Count = 3
};
[GenerateHLSL(PackingRules.Exact)]
public enum DBufferHTileBit
{
Diffuse = 1,
Normal = 2,
Mask = 4
};
//-----------------------------------------------------------------------------
// DBuffer management
//-----------------------------------------------------------------------------

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


//
#define DBUFFERMATERIAL_COUNT (3)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Decal+DBufferHTileBit: static fields
//
#define DBUFFERHTILEBIT_DIFFUSE (1)
#define DBUFFERHTILEBIT_NORMAL (2)
#define DBUFFERHTILEBIT_MASK (4)
// Generated from UnityEngine.Experimental.Rendering.HDPipeline.Decal+DecalSurfaceData
// PackingRules = Exact
struct DecalSurfaceData

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


UNITY_DEFINE_INSTANCED_PROP(float4x4, normalToWorld)
UNITY_INSTANCING_BUFFER_END(matrix)
RW_TEXTURE2D(float, _DecalHTile); // DXGI_FORMAT_R8_UINT is not supported by Unity
// Must be in sync with RT declared in HDRenderPipeline.cs ::Rebuild
void EncodeIntoDBuffer( DecalSurfaceData surfaceData,

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


{
if(_EnableDBuffer)
{
// the code in the macros, gets moved inside the conditionals by the compiler
uint mask = UnpackByte(_DecalHTile[unPositionSS / 8]);
surfaceData.baseColor.xyz = surfaceData.baseColor.xyz * decalSurfaceData.baseColor.w + decalSurfaceData.baseColor.xyz;
surfaceData.normalWS.xyz = normalize(surfaceData.normalWS.xyz * decalSurfaceData.normalWS.w + decalSurfaceData.normalWS.xyz);
surfaceData.metallic = surfaceData.metallic * decalSurfaceData.mask.w + decalSurfaceData.mask.x;
surfaceData.ambientOcclusion = surfaceData.ambientOcclusion * decalSurfaceData.mask.w + decalSurfaceData.mask.y;
surfaceData.perceptualSmoothness = surfaceData.perceptualSmoothness * decalSurfaceData.mask.w + decalSurfaceData.mask.z;
if(mask & DBUFFERHTILEBIT_DIFFUSE)
{
surfaceData.baseColor.xyz = surfaceData.baseColor.xyz * decalSurfaceData.baseColor.w + decalSurfaceData.baseColor.xyz;
}
if(mask & DBUFFERHTILEBIT_NORMAL)
{
surfaceData.normalWS.xyz = normalize(surfaceData.normalWS.xyz * decalSurfaceData.normalWS.w + decalSurfaceData.normalWS.xyz);
}
if(mask & DBUFFERHTILEBIT_MASK)
{
surfaceData.metallic = surfaceData.metallic * decalSurfaceData.mask.w + decalSurfaceData.mask.x;
surfaceData.ambientOcclusion = surfaceData.ambientOcclusion * decalSurfaceData.mask.w + decalSurfaceData.mask.y;
surfaceData.perceptualSmoothness = surfaceData.perceptualSmoothness * decalSurfaceData.mask.w + decalSurfaceData.mask.z;
}
}
}

12
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/SubsurfaceScattering/SubsurfaceScatteringManager.cs


public void Resize(HDCamera hdCamera)
{
// We must use a RenderTexture and not GetTemporaryRT() as currently Unity only aloow to bind a RenderTexture for a UAV in a pixel shader
// We use 8x8 tiles in order to match the native GCN HTile as closely as possible.
var desc = hdCamera.renderTextureDesc;
desc.width = (desc.width + 7) / 8;
desc.height = (desc.height + 7) / 8;
// TODO: This fails allocation with MSAA enabled?
m_HTile = CoreUtils.CreateRenderTexture(desc, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); // DXGI_FORMAT_R8_UINT is not supported by Unity
m_HTile.filterMode = FilterMode.Point;
m_HTile.enableRandomWrite = true;
m_HTile.Create();
m_HTileRT = new RenderTargetIdentifier(m_HTile);
CoreUtils.ResizeHTile(ref m_HTile, ref m_HTileRT, hdCamera.renderTextureDesc);
}
public void PushGlobalParams(CommandBuffer cmd, DiffusionProfileSettings sssParameters, FrameSettings frameSettings)

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassDBuffer.hlsl


float3x3 decalToWorld = (float3x3)UNITY_ACCESS_INSTANCED_PROP(matrix, normalToWorld);
GetSurfaceData(positionDS.xz, decalToWorld, surfaceData);
// have to do explicit test since compiler behavior is not defined for RW resources and discard instructions
if((all(positionDS.xyz > 0.0f) && all(1.0f - positionDS.xyz > 0.0f)))
{
uint mask = 0;
#if _COLORMAP
mask |= DBUFFERHTILEBIT_DIFFUSE;
#endif
#if _NORMALMAP
mask |= DBUFFERHTILEBIT_NORMAL;
#endif
#if _MASKMAP
mask |= DBUFFERHTILEBIT_MASK;
#endif
uint oldVal = UnpackByte(_DecalHTile[posInput.positionSS.xy / 8]);
oldVal |= mask;
_DecalHTile[posInput.positionSS.xy / 8] = PackByte(oldVal);
}
ENCODE_INTO_DBUFFER(surfaceData, outDBuffer);
}
正在加载...
取消
保存