浏览代码

Merge pull request #896 from Unity-Technologies/decals/distance_culling

Decals/distance culling
/main
GitHub 7 年前
当前提交
6157d668
共有 18 个文件被更改,包括 202 次插入36 次删除
  1. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalProjectorComponent.cs
  2. 66
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/DecalSystem.cs
  3. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/Material/Decal/DecalProjectorComponentEditor.cs
  4. 10
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs
  5. 2
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs
  6. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset
  7. 4
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs
  8. 5
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.cs.hlsl
  9. 3
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/Decal.hlsl
  10. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Decal/DecalData.hlsl
  11. 1
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs
  12. 14
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/ShaderPass/ShaderPassDBuffer.hlsl
  13. 17
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/GlobalDecalSettings.cs
  14. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/GlobalDecalSettings.cs.meta
  15. 32
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalDecalSettingsUI.cs
  16. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalDecalSettingsUI.cs.meta
  17. 20
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalDecalSettings.cs
  18. 11
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalDecalSettings.cs.meta

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


public class DecalProjectorComponent : MonoBehaviour
{
public Material m_Material = null;
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;

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

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


}
}
private const int kDefaultDrawDistance = 1000;
static public int DrawDistance
{
get
{
HDRenderPipelineAsset hdrp = GraphicsSettings.renderPipelineAsset as HDRenderPipelineAsset;
if (hdrp != null)
{
return hdrp.renderPipelineSettings.decalSettings.drawDistance;
}
return kDefaultDrawDistance;
}
}
private static readonly int m_NormalToWorldID = Shader.PropertyToID("normalToWorld");
private static MaterialPropertyBlock m_PropertyBlock = new MaterialPropertyBlock();

static public Mesh m_DecalMesh = null;
static public Matrix4x4[] m_InstanceMatrices = new Matrix4x4[kDrawIndexedBatchSize];
static public Matrix4x4[] m_InstanceNormalToWorld = new Matrix4x4[kDrawIndexedBatchSize];
static public float[] m_BoundingDistances = new float[1];
private Dictionary<int, DecalSet> m_DecalSets = new Dictionary<int, DecalSet>();

return res;
}
public void UpdateBoundingSphere(DecalProjectorComponent decal)
public void UpdateCachedData(DecalProjectorComponent decal)
{
m_CachedTransforms[decal.CullIndex] = decal.transform.localToWorldMatrix;

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

BoundingSphere[] newSpheres = new BoundingSphere[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedTransforms = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Matrix4x4[] newCachedNormalToWorld = new Matrix4x4[m_DecalsCount + kDecalBlockSize];
Vector2[] newCachedDrawDistances = new Vector2[m_DecalsCount + kDecalBlockSize];
m_ResultIndices = new int[m_DecalsCount + kDecalBlockSize];
m_Decals.CopyTo(newDecals, 0);

m_CachedDrawDistances.CopyTo(newCachedDrawDistances, 0);
m_CachedDrawDistances = newCachedDrawDistances;
UpdateBoundingSphere(m_Decals[m_DecalsCount]);
UpdateCachedData(m_Decals[m_DecalsCount]);
m_DecalsCount++;
}

m_BoundingSpheres[removeAtIndex] = m_BoundingSpheres[m_DecalsCount - 1];
m_CachedTransforms[removeAtIndex] = m_CachedTransforms[m_DecalsCount - 1];
m_CachedNormalToWorld[removeAtIndex] = m_CachedNormalToWorld[m_DecalsCount - 1];
m_CachedDrawDistances[removeAtIndex] = m_CachedDrawDistances[m_DecalsCount - 1];
m_DecalsCount--;
decal.CullIndex = DecalProjectorComponent.kInvalidIndex;
}

{
Debug.LogError("Begin/EndCull() called out of sequence for decal projectors.");
}
// let the culling group code do some of the heavy lifting for global draw distance
m_BoundingDistances[0] = DrawDistance;
m_CullingGroup.SetDistanceReferencePoint(camera.transform.position);
m_CullingGroup.SetBoundingDistances(m_BoundingDistances);
m_CullingGroup.SetBoundingSpheres(m_BoundingSpheres);
m_CullingGroup.SetBoundingSphereCount(m_DecalsCount);
}

public void Render(ScriptableRenderContext renderContext, HDCamera camera, CommandBuffer cmd)
{
int instanceCount = 0;
Vector3 cameraPos = camera.cameraPos;
m_InstanceMatrices[instanceCount] = m_CachedTransforms[decalIndex];
m_InstanceNormalToWorld[instanceCount] = m_CachedNormalToWorld[decalIndex];
instanceCount++;
if (instanceCount == kDrawIndexedBatchSize)
{
m_PropertyBlock.SetMatrixArray(m_NormalToWorldID, m_InstanceNormalToWorld);
cmd.DrawMeshInstanced(m_DecalMesh, 0, KeyMaterial, 0, m_InstanceMatrices, kDrawIndexedBatchSize, m_PropertyBlock);
instanceCount = 0;
}
// do additional culling based on individual decal draw distances
float distanceToDecal = (cameraPos - m_BoundingSpheres[decalIndex].position).magnitude;
float cullDistance = m_CachedDrawDistances[decalIndex].x + m_BoundingSpheres[decalIndex].radius;
if (distanceToDecal < cullDistance)
{
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
instanceCount++;
if (instanceCount == kDrawIndexedBatchSize)
{
m_PropertyBlock.SetMatrixArray(m_NormalToWorldID, m_InstanceNormalToWorld);
cmd.DrawMeshInstanced(m_DecalMesh, 0, KeyMaterial, 0, m_InstanceMatrices, kDrawIndexedBatchSize, m_PropertyBlock);
instanceCount = 0;
}
}
}
if (instanceCount > 0)
{

private int m_DecalsCount = 0;
private Matrix4x4[] m_CachedTransforms = new Matrix4x4[kDecalBlockSize];
private Matrix4x4[] m_CachedNormalToWorld = new Matrix4x4[kDecalBlockSize];
private Vector2[] m_CachedDrawDistances = new Vector2[kDecalBlockSize]; // x - draw distance, y - fade scale
private Material m_Material;
}

}
}
public void UpdateBoundingSphere(DecalProjectorComponent decal)
public void UpdateCachedData(DecalProjectorComponent decal)
{
if (decal.CullIndex == DecalProjectorComponent.kInvalidIndex) // check if we have this decal
return;

if (m_DecalSets.TryGetValue(key, out decalSet))
{
decalSet.UpdateBoundingSphere(decal);
decalSet.UpdateCachedData(decal);
}
}

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


{
private MaterialEditor m_MaterialEditor = null;
private DecalProjectorComponent m_DecalProjectorComponent = null;
private SerializedProperty m_MaterialProperty;
private SerializedProperty m_DrawDistanceProperty;
private SerializedProperty m_FadeScaleProperty;
private void OnEnable()
{

m_DecalProjectorComponent.OnMaterialChange += OnMaterialChange;
m_MaterialProperty = serializedObject.FindProperty("m_Material");
m_DrawDistanceProperty = serializedObject.FindProperty("m_DrawDistance");
m_FadeScaleProperty = serializedObject.FindProperty("m_FadeScale");
}
private void OnDisable()

{
EditorGUI.BeginChangeCheck();
base.OnInspectorGUI();
EditorGUILayout.PropertyField(m_MaterialProperty);
EditorGUILayout.PropertyField(m_DrawDistanceProperty);
EditorGUILayout.Slider(m_FadeScaleProperty, 0.0f, 1.0f, new GUIContent("Fade scale"));
if (EditorGUI.EndChangeCheck())
{
serializedObject.ApplyModifiedProperties();

10
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/RenderPipelineSettingsUI.cs


(s, d, o) => s.shadowInitParams,
(s, d, o) => d.shadowInitParams,
ShadowInitParametersUI.SectionAtlas
),
CED.space,
CED.Select(
(s, d, o) => s.decalSettings,
(s, d, o) => d.decalSettings,
GlobalDecalSettingsUI.Inspector
);
}

);
GlobalLightLoopSettingsUI lightLoopSettings = new GlobalLightLoopSettingsUI();
GlobalDecalSettingsUI decalSettings = new GlobalDecalSettingsUI();
ShadowInitParametersUI shadowInitParams = new ShadowInitParametersUI();
public RenderPipelineSettingsUI()

{
lightLoopSettings.Reset(data.lightLoopSettings, repaint);
shadowInitParams.Reset(data.shadowInitParams, repaint);
decalSettings.Reset(data.decalSettings, repaint);
base.Reset(data, repaint);
}

shadowInitParams.Update();
decalSettings.Update();
base.Update();
}

2
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedRenderPipelineSettings.cs


public SerializedGlobalLightLoopSettings lightLoopSettings;
public SerializedShadowInitParameters shadowInitParams;
public SerializedGlobalDecalSettings decalSettings;
public SerializedRenderPipelineSettings(SerializedProperty root)
{

lightLoopSettings = new SerializedGlobalLightLoopSettings(root.Find((RenderPipelineSettings s) => s.lightLoopSettings));
shadowInitParams = new SerializedShadowInitParameters(root.Find((RenderPipelineSettings s) => s.shadowInitParams));
decalSettings = new SerializedGlobalDecalSettings(root.Find((RenderPipelineSettings s) => s.decalSettings));
}
}
}

5
ScriptableRenderPipeline/HDRenderPipeline/HDRP/HDRenderPipelineAsset.asset


--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_PrefabParentObject: {fileID: 0}
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInternal: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1

shadowInitParams:
shadowAtlasWidth: 4096
shadowAtlasHeight: 4096
decalSettings:
drawDistance: 1000
atlasSize: 8192
diffusionProfileSettings: {fileID: 11400000, guid: 404820c4cf36ad944862fa59c56064f0,
type: 2}

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


[SurfaceDataAttributes("Normal", true)]
public Vector4 normalWS;
[SurfaceDataAttributes("Mask", true)]
public Vector4 mask;
public Vector4 mask;
[SurfaceDataAttributes("HTileMask")]
public uint HTileMask;
};
[GenerateHLSL(PackingRules.Exact)]

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


#define DEBUGVIEW_DECAL_DECALSURFACEDATA_BASE_COLOR (10000)
#define DEBUGVIEW_DECAL_DECALSURFACEDATA_NORMAL_WS (10001)
#define DEBUGVIEW_DECAL_DECALSURFACEDATA_MASK (10002)
#define DEBUGVIEW_DECAL_DECALSURFACEDATA_HTILE_MASK (10003)
//
// UnityEngine.Experimental.Rendering.HDPipeline.Decal+DBufferMaterial: static fields

float4 baseColor;
float4 normalWS;
float4 mask;
int HTileMask;
};
//

break;
case DEBUGVIEW_DECAL_DECALSURFACEDATA_MASK:
result = decalsurfacedata.mask.xyz;
break;
case DEBUGVIEW_DECAL_DECALSURFACEDATA_HTILE_MASK:
result = GetIndexColor(decalsurfacedata.HTileMask);
break;
}
}

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


#include "Decal.cs.hlsl"
#include "CoreRP/ShaderLibrary/Debug.hlsl"
#include "Decal.cs.hlsl"
#define DBufferType0 float4
#define DBufferType1 float4

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


#include "CoreRP/ShaderLibrary/Packing.hlsl"
#include "CoreRP/ShaderLibrary/Sampling/SampleUVMapping.hlsl"
void GetSurfaceData(float2 texCoordDS, float3x3 decalToWorld, out DecalSurfaceData surfaceData)
void GetSurfaceData(float2 texCoordDS, float4x4 decalToWorld, out DecalSurfaceData surfaceData)
float totalBlend = _DecalBlend;
surfaceData.HTileMask = 0;
float totalBlend = _DecalBlend * clamp(decalToWorld[0][3], 0.0f, 1.0f);
surfaceData.HTileMask |= DBUFFERHTILEBIT_DIFFUSE;
surfaceData.normalWS.xyz = mul(decalToWorld, SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, sampler_NormalMap, texCoord, 1)) * 0.5f + 0.5f;
surfaceData.normalWS.xyz = mul((float3x3)decalToWorld, SAMPLE_UVMAPPING_NORMALMAP(_NormalMap, sampler_NormalMap, texCoord, 1)) * 0.5f + 0.5f;
surfaceData.HTileMask |= DBUFFERHTILEBIT_NORMAL;
surfaceData.HTileMask |= DBUFFERHTILEBIT_MASK;
}

1
ScriptableRenderPipeline/HDRenderPipeline/HDRP/RenderPipeline/RenderPipelineSettings.cs


public GlobalLightLoopSettings lightLoopSettings = new GlobalLightLoopSettings();
public ShadowInitParameters shadowInitParams = new ShadowInitParameters();
public GlobalDecalSettings decalSettings = new GlobalDecalSettings();
}
}

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


clip(1.0 - positionDS); // Clip value above one
DecalSurfaceData surfaceData;
float3x3 decalToWorld = (float3x3)UNITY_ACCESS_INSTANCED_PROP(matrix, normalToWorld);
float4x4 decalToWorld = UNITY_ACCESS_INSTANCED_PROP(matrix, normalToWorld);
uint mask = 0;
#if _COLORMAP
mask |= DBUFFERHTILEBIT_DIFFUSE;
#endif
#if _NORMALMAP
mask |= DBUFFERHTILEBIT_NORMAL;
#endif
#if _MASKMAP
mask |= DBUFFERHTILEBIT_MASK;
#endif
oldVal |= mask;
oldVal |= surfaceData.HTileMask;
_DecalHTile[posInput.positionSS.xy / 8] = PackByte(oldVal);
}
ENCODE_INTO_DBUFFER(surfaceData, outDBuffer);

17
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/GlobalDecalSettings.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
namespace UnityEngine.Experimental.Rendering.HDPipeline
{
// RenderRenderPipelineSettings represent settings that are immutable at runtime.
// There is a dedicated RenderRenderPipelineSettings for each platform
[Serializable]
public class GlobalDecalSettings
{
public int drawDistance = 1000;
public int atlasSize = 8192;
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Decal/GlobalDecalSettings.cs.meta


fileFormatVersion: 2
guid: 485a401e826e66d4fb7bc37f9562ad93
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

32
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalDecalSettingsUI.cs


using UnityEngine;
namespace UnityEditor.Experimental.Rendering
{
using _ = CoreEditorUtils;
using CED = CoreEditorDrawer<GlobalDecalSettingsUI, SerializedGlobalDecalSettings>;
class GlobalDecalSettingsUI : BaseUI<SerializedGlobalDecalSettings>
{
static GlobalDecalSettingsUI()
{
Inspector = CED.Group(SectionDecalSettings);
}
public static readonly CED.IDrawer Inspector;
public static readonly CED.IDrawer SectionDecalSettings = CED.Action(Drawer_SectionDecalSettings);
public GlobalDecalSettingsUI()
: base(0)
{
}
static void Drawer_SectionDecalSettings(GlobalDecalSettingsUI s, SerializedGlobalDecalSettings d, Editor o)
{
EditorGUILayout.LabelField(_.GetContent("Decals"), EditorStyles.boldLabel);
++EditorGUI.indentLevel;
EditorGUILayout.PropertyField(d.drawDistance, _.GetContent("Draw Distance"));
EditorGUILayout.PropertyField(d.atlasSize, _.GetContent("Atlas Size"));
--EditorGUI.indentLevel;
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/GlobalDecalSettingsUI.cs.meta


fileFormatVersion: 2
guid: cd7279651d591ea499d14ea8d77384ef
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

20
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalDecalSettings.cs


using UnityEngine.Experimental.Rendering.HDPipeline;
namespace UnityEditor.Experimental.Rendering
{
class SerializedGlobalDecalSettings
{
public SerializedProperty root;
public SerializedProperty drawDistance;
public SerializedProperty atlasSize;
public SerializedGlobalDecalSettings(SerializedProperty root)
{
this.root = root;
drawDistance = root.Find((GlobalDecalSettings s) => s.drawDistance);
atlasSize = root.Find((GlobalDecalSettings s) => s.atlasSize);
}
}
}

11
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Editor/RenderLoopSettings/SerializedGlobalDecalSettings.cs.meta


fileFormatVersion: 2
guid: dadcbfde34013be40a7e1162307cc677
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存