浏览代码

Merge pull request #1870 from Unity-Technologies/HDRP/staging

Merge Hdrp/staging
/main
GitHub 6 年前
当前提交
3e6c15b0
共有 15 个文件被更改,包括 856 次插入97 次删除
  1. 15
      com.unity.render-pipelines.core/CoreRP/CoreResources/TexturePadding.cs
  2. 2
      com.unity.render-pipelines.core/CoreRP/Textures/RTHandleSystem.cs
  3. 2
      com.unity.render-pipelines.high-definition/CHANGELOG.md
  4. 2
      com.unity.render-pipelines.high-definition/HDRP/Debug/DebugDisplay.cs
  5. 2
      com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs
  6. 4
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Light/HDAdditionalLightData.cs
  7. 313
      com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs
  8. 8
      com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs
  9. 14
      com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs
  10. 1
      com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset
  11. 6
      com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/RenderPipelineResources.cs
  12. 506
      com.unity.render-pipelines.core/CoreRP/Debugging/DebugShapes.cs
  13. 11
      com.unity.render-pipelines.core/CoreRP/Debugging/DebugShapes.cs.meta
  14. 58
      com.unity.render-pipelines.high-definition/HDRP/Debug/DebugLightVolume.shader
  15. 9
      com.unity.render-pipelines.high-definition/HDRP/Debug/DebugLightVolume.shader.meta

15
com.unity.render-pipelines.core/CoreRP/CoreResources/TexturePadding.cs


int m_KMainTop;
int m_KMainRight;
// Avoid garbage generated by .SetComputeIntParams methods (using params int[] will generate an array on the fly)
int[] m_IntParams = new int[2];
public TexturePadding(ComputeShader cs)
{
m_CS = cs;

{
if (from.width < to.width)
{
cmd.SetComputeIntParams(m_CS, _RectOffset, from.width, 0);
m_IntParams[0] = from.width;
m_IntParams[1] = 0;
cmd.SetComputeIntParams(m_CS, _RectOffset, m_IntParams);
cmd.SetComputeIntParams(m_CS, _RectOffset, 0, from.height);
m_IntParams[0] = 0;
m_IntParams[1] = from.height;
cmd.SetComputeIntParams(m_CS, _RectOffset, m_IntParams);
cmd.SetComputeIntParams(m_CS, _RectOffset, from.width, from.height);
m_IntParams[0] = from.width;
m_IntParams[1] = from.height;
cmd.SetComputeIntParams(m_CS, _RectOffset, m_IntParams);
cmd.SetComputeTextureParam(m_CS, m_KMainTopRight, _InOutTexture, inOutTexture);
cmd.DispatchCompute(m_CS, m_KMainTopRight, to.width - from.width, to.height - from.height, 1);
}

2
com.unity.render-pipelines.core/CoreRP/Textures/RTHandleSystem.cs


public void DemandResize(RTHandle rth)
{
Assert.IsTrue(m_ResizeOnDemandRTs.Contains(rth), string.Format("The RTHandle {0} is not an resize on demand handle in this RTHandleSystem. Please call SwitchToResizeOnDemand(rth, true) before resizing on demand.", rth));
Assert.IsTrue(m_ResizeOnDemandRTs.Contains(rth), "The RTHandle is not an resize on demand handle in this RTHandleSystem. Please call SwitchToResizeOnDemand(rth, true) before resizing on demand.");
for (int i = 0, c = (int)RTCategory.Count; i < c; ++i)
{

2
com.unity.render-pipelines.high-definition/CHANGELOG.md


### Added
- Added an error message to say to use Metal or Vulkan when trying to use OpenGL API
- Added a new Fabric shader model that supports Silk and Cotton/Wool
- Added a new HDRP Lighting Debug mode to visualize Light Volumes for Point, Spot, Line, Rectangular and Reflection Probes
### Fixed
- Fix an issue where the screen where darken when rendering camera preview

- Changed default reflection probe to be 256x256x6 and array size to be 64
- Removed dependence on the NdotL for thickness evaluation for translucency (based on artist's input)
- Increased the precision when comparing Planar or HD reflection probe volumes
- Remove various GC alloc in C#. Slightly better performance
## [3.2.0-preview]

2
com.unity.render-pipelines.high-definition/HDRP/Debug/DebugDisplay.cs


});
}
list.Add(new DebugUI.BoolField { displayName = "Display Light Volumes", getter = () => lightingDebugSettings.displayLightVolumes, setter = value => lightingDebugSettings.displayLightVolumes = value, onValueChanged = RefreshLightingDebug });
if (DebugNeedsExposure())
list.Add(new DebugUI.FloatField { displayName = "Debug Exposure", getter = () => lightingDebugSettings.debugExposure, setter = value => lightingDebugSettings.debugExposure = value });

2
com.unity.render-pipelines.high-definition/HDRP/Debug/LightingDebug.cs


public bool displaySkyReflection = false;
public float skyReflectionMipmap = 0.0f;
public bool displayLightVolumes = false;
public float environmentProxyDepthScale = 20;
public float debugExposure = 0.0f;

4
com.unity.render-pipelines.high-definition/HDRP/Lighting/Light/HDAdditionalLightData.cs


// This function return a mask of light layers as uint and handle the case of Everything as being 0xFF and not -1
public uint GetLightLayers()
{
int value = Convert.ToInt32(lightLayers);
int value = (int)(lightLayers);
return value < 0 ? (uint)LightLayerEnum.Everything : (uint)value;
}

m_Version = currentVersion;
version = currentVersion;
#pragma warning restore 0618
}
}

313
com.unity.render-pipelines.high-definition/HDRP/Lighting/LightLoop/LightLoop.cs


namespace UnityEngine.Experimental.Rendering.HDPipeline
{
public static class VisibleLightExtensionMethods
{
public static Vector3 GetPosition(this VisibleLight value)
{
return value.localToWorld.GetColumn(3);
}
public static Vector3 GetForward(this VisibleLight value)
{
return value.localToWorld.GetColumn(2);
}
public static Vector3 GetUp(this VisibleLight value)
{
return value.localToWorld.GetColumn(1);
}
public static Vector3 GetRight(this VisibleLight value)
{
return value.localToWorld.GetColumn(0);
}
}
class ShadowSetup : IDisposable
{

// For now we don't use shadow cascade borders.
static public readonly bool s_UseCascadeBorders = false;
// Keep sorting array around to avoid garbage
uint[] m_SortKeys = null;
void UpdateSortKeysArray(int count)
{
if (m_SortKeys == null ||count > m_SortKeys.Length)
{
m_SortKeys = new uint[count];
}
}
// Matrix used for Light list building
// Keep them around to avoid allocations
Matrix4x4[] m_LightListProjMatrices = new Matrix4x4[2];
Matrix4x4[] m_LightListProjscrMatrices = new Matrix4x4[2];
Matrix4x4[] m_LightListInvProjscrMatrices = new Matrix4x4[2];
Matrix4x4[] m_LightListProjHMatrices = new Matrix4x4[2];
Matrix4x4[] m_LightListInvProjHMatrices = new Matrix4x4[2];
public class LightList
{
public List<DirectionalLightData> directionalLights;

ContactShadows m_ContactShadows = null;
bool m_EnableContactShadow = false;
IndirectLightingController m_indirectLightingController = null;
// Following is an array of material of size eight for all combination of keyword: OUTPUT_SPLIT_LIGHTING - LIGHTLOOP_TILE_PASS - SHADOWS_SHADOWMASK - USE_FPTL_LIGHTLIST/USE_CLUSTERED_LIGHTLIST - DEBUG_DISPLAY

Material m_DebugLightVolumeMaterial;
Material m_CubeToPanoMaterial;
Light m_CurrentSunLight;

m_DebugViewTilesMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugViewTilesShader);
m_DebugShadowMapMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugShadowMapShader);
m_DebugLightVolumeMaterial = CoreUtils.CreateEngineMaterial(m_Resources.debugLightVolumeShader);
m_CubeToPanoMaterial = CoreUtils.CreateEngineMaterial(m_Resources.cubeToPanoShader);
m_lightList = new LightList();

{
s_GenListPerTileKernel = buildPerTileLightListShader.FindKernel(m_FrameSettings.lightLoopSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags" : "TileLightListGen_FeatureFlags");
s_GenListPerTileKernel_Oblique = buildPerTileLightListShader.FindKernel(m_FrameSettings.lightLoopSettings.enableBigTilePrepass ? "TileLightListGen_SrcBigTile_FeatureFlags_Oblique" : "TileLightListGen_FeatureFlags_Oblique");
}
else
{

return new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
}
bool GetDominantLightWithShadows(AdditionalShadowData additionalShadowData, VisibleLight light, int lightIndex = -1)
bool GetDominantLightWithShadows(AdditionalShadowData additionalShadowData, VisibleLight light, Light lightComponent, int lightIndex = -1)
// Can happen for particle lights (where we don't support shadows anyway)
if (lightComponent == null)
return false;
float lightDominanceValue = light.screenRect.size.magnitude * light.light.intensity;
float lightDominanceValue = light.screenRect.size.magnitude * lightComponent.intensity;
if (additionalShadowData == null || !additionalShadowData.contactShadows || light.light.shadows == LightShadows.None)
if (additionalShadowData == null || !additionalShadowData.contactShadows || lightComponent.shadows == LightShadows.None)
return false;
if (lightDominanceValue <= m_DominantLightValue || m_DominantLightValue == Single.PositiveInfinity)
return false;

return true;
}
public bool GetDirectionalLightData(CommandBuffer cmd, ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, HDAdditionalLightData additionalData, AdditionalShadowData additionalShadowData, int lightIndex, DebugDisplaySettings debugDisplaySettings)
public bool GetDirectionalLightData(CommandBuffer cmd, ShadowSettings shadowSettings, GPULightType gpuLightType, VisibleLight light, Light lightComponent, HDAdditionalLightData additionalData, AdditionalShadowData additionalShadowData, int lightIndex, DebugDisplaySettings debugDisplaySettings)
{
var directionalLightData = new DirectionalLightData();

return false;
// Discard light if disabled in debug display settings
if (!debugDisplaySettings.lightingDebugSettings.showDirectionalLight)
return false;

// Light direction for directional is opposite to the forward direction
directionalLightData.forward = light.light.transform.forward;
directionalLightData.forward = light.GetForward();
directionalLightData.right = light.light.transform.right * 2 / Mathf.Max(additionalData.shapeWidth, 0.001f);
directionalLightData.up = light.light.transform.up * 2 / Mathf.Max(additionalData.shapeHeight, 0.001f);
directionalLightData.positionRWS = light.light.transform.position;
directionalLightData.right = light.GetRight() * 2 / Mathf.Max(additionalData.shapeWidth, 0.001f);
directionalLightData.up = light.GetUp() * 2 / Mathf.Max(additionalData.shapeHeight, 0.001f);
directionalLightData.positionRWS = light.GetPosition();
directionalLightData.color = GetLightColor(light);
// Caution: This is bad but if additionalData == HDUtils.s_DefaultHDAdditionalLightData it mean we are trying to promote legacy lights, which is the case for the preview for example, so we need to multiply by PI as legacy Unity do implicit divide by PI for direct intensity.

directionalLightData.volumetricDimmer = additionalData.volumetricDimmer;
directionalLightData.shadowIndex = directionalLightData.cookieIndex = -1;
if (light.light.cookie != null)
if (lightComponent != null && lightComponent.cookie != null)
directionalLightData.tileCookie = light.light.cookie.wrapMode == TextureWrapMode.Repeat ? 1 : 0;
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(cmd, light.light.cookie);
directionalLightData.tileCookie = lightComponent.cookie.wrapMode == TextureWrapMode.Repeat ? 1 : 0;
directionalLightData.cookieIndex = m_CookieTexArray.FetchSlice(cmd, lightComponent.cookie);
}
// fix up shadow information
int shadowIdx;

m_CurrentSunLight = light.light;
m_CurrentSunLight = lightComponent;
if (IsBakedShadowMaskLight(light.light))
if (IsBakedShadowMaskLight(lightComponent))
directionalLightData.shadowMaskSelector[light.light.bakingOutput.occlusionMaskChannel] = 1.0f;
directionalLightData.nonLightmappedOnly = light.light.lightShadowCasterMode == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0;
directionalLightData.shadowMaskSelector[lightComponent.bakingOutput.occlusionMaskChannel] = 1.0f;
directionalLightData.nonLightmappedOnly = lightComponent.lightShadowCasterMode == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0;
}
else
{

}
// Fallback to the first non shadow casting directional light.
m_CurrentSunLight = m_CurrentSunLight == null ? light.light : m_CurrentSunLight;
m_CurrentSunLight = m_CurrentSunLight == null ? lightComponent : m_CurrentSunLight;
if (GetDominantLightWithShadows(additionalShadowData, light))
if (GetDominantLightWithShadows(additionalShadowData, light, lightComponent))
directionalLightData.contactShadowIndex = 0;
m_lightList.directionalLights.Add(directionalLightData);

}
public bool GetLightData(CommandBuffer cmd, ShadowSettings shadowSettings, Camera camera, GPULightType gpuLightType,
VisibleLight light, HDAdditionalLightData additionalLightData, AdditionalShadowData additionalshadowData,
VisibleLight light, Light lightComponent, HDAdditionalLightData additionalLightData, AdditionalShadowData additionalshadowData,
int lightIndex, ref Vector3 lightDimensions, DebugDisplaySettings debugDisplaySettings)
{
var lightData = new LightData();

lightData.lightType = gpuLightType;
lightData.positionRWS = light.light.transform.position;
lightData.positionRWS = light.GetPosition();
bool applyRangeAttenuation = additionalLightData.applyRangeAttenuation && (gpuLightType != GPULightType.ProjectorBox);

lightData.color = GetLightColor(light);
lightData.forward = light.light.transform.forward;
lightData.up = light.light.transform.up;
lightData.right = light.light.transform.right;
lightData.forward = light.GetForward();
lightData.up = light.GetUp();
lightData.right = light.GetRight();
lightDimensions.x = additionalLightData.shapeWidth;
lightDimensions.y = additionalLightData.shapeHeight;

lightData.cookieIndex = -1;
lightData.shadowIndex = -1;
if (light.light.cookie != null)
if (lightComponent != null && lightComponent.cookie != null)
lightData.cookieIndex = m_CookieTexArray.FetchSlice(cmd, light.light.cookie);
lightData.cookieIndex = m_CookieTexArray.FetchSlice(cmd, lightComponent.cookie);
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(cmd, light.light.cookie);
lightData.cookieIndex = m_CubeCookieTexArray.FetchSlice(cmd, lightComponent.cookie);
break;
}
}

lightData.shadowMaskSelector = Vector4.zero;
if (IsBakedShadowMaskLight(light.light))
if (IsBakedShadowMaskLight(lightComponent))
lightData.shadowMaskSelector[light.light.bakingOutput.occlusionMaskChannel] = 1.0f;
lightData.shadowMaskSelector[lightComponent.bakingOutput.occlusionMaskChannel] = 1.0f;
lightData.nonLightmappedOnly = light.light.lightShadowCasterMode == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0;
lightData.nonLightmappedOnly = lightComponent.lightShadowCasterMode == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0;
}
else
{

// Check if the current light is dominant and store it's index to change it's property later,
// as we can't know which one will be dominant before checking all the lights
GetDominantLightWithShadows(additionalshadowData, light, m_lightList.lights.Count -1);
GetDominantLightWithShadows(additionalshadowData, light, lightComponent, m_lightList.lights.Count -1);
return true;
}

const float pi = 3.1415926535897932384626433832795f;
const float degToRad = (float)(pi / 180.0);
var sa = light.light.spotAngle;
var sa = light.spotAngle;
var cs = Mathf.Cos(0.5f * sa * degToRad);
var si = Mathf.Sin(0.5f * sa * degToRad);

// Unfortunately we don't have this information at the moment.
if (probe.mode == ReflectionProbeMode.Realtime && camera.cameraType == CameraType.Reflection)
return false;
// Discard probe if disabled in debug menu
if (!debugDisplaySettings.lightingDebugSettings.showReflectionProbe)
return false;

public bool IsBakedShadowMaskLight(Light light)
{
// This can happen for particle lights.
if (light == null)
return false;
return light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed &&
light.bakingOutput.mixedLightingMode == MixedLightingMode.Shadowmask &&
light.bakingOutput.occlusionMaskChannel != -1; // We need to have an occlusion mask channel assign, else we have no shadow mask

for (int i = 0; i < lcnt; ++i)
{
VisibleLight vl = cullResults.visibleLights[i];
if (vl.light.shadows == LightShadows.None)
var lightComponent = vl.light;
// This can happen for particle light which don't have a proper game object. We don't support shadows for them.
if (lightComponent == null)
AdditionalShadowData asd = vl.light.GetComponent<AdditionalShadowData>();
if (lightComponent.shadows == LightShadows.None)
continue;
AdditionalShadowData asd = lightComponent.GetComponent<AdditionalShadowData>();
if (asd != null && asd.shadowDimmer > 0.0f)
{
m_ShadowRequests.Add(i);

int areaLightCount = 0;
int lightCount = Math.Min(cullResults.visibleLights.Count, k_MaxLightsOnScreen);
var sortKeys = new uint[lightCount];
UpdateSortKeysArray(lightCount);
var lightComponent = light.light;
var additionalData = GetHDAdditionalLightData(light);
var additionalData = GetHDAdditionalLightData(lightComponent);
LightCategory lightCategory = LightCategory.Count;
GPULightType gpuLightType = GPULightType.Point;

uint shadow = m_ShadowIndices.ContainsKey(lightIndex) ? 1u : 0;
// 5 bit (0x1F) light category, 5 bit (0x1F) GPULightType, 5 bit (0x1F) lightVolume, 1 bit for shadow casting, 16 bit index
sortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
m_SortKeys[sortCount++] = (uint)lightCategory << 27 | (uint)gpuLightType << 22 | (uint)lightVolumeType << 17 | shadow << 16 | (uint)lightIndex;
CoreUtils.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
CoreUtils.QuickSort(m_SortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
// TODO: Refactor shadow management
// The good way of managing shadow:

for (int sortIndex = 0; sortIndex < sortCount; ++sortIndex)
{
// In 1. we have already classify and sorted the light, we need to use this sorted order here
uint sortKey = sortKeys[sortIndex];
uint sortKey = m_SortKeys[sortIndex];
LightCategory lightCategory = (LightCategory)((sortKey >> 27) & 0x1F);
GPULightType gpuLightType = (GPULightType)((sortKey >> 22) & 0x1F);
LightVolumeType lightVolumeType = (LightVolumeType)((sortKey >> 17) & 0x1F);

var lightComponent = light.light;
m_enableBakeShadowMask = m_enableBakeShadowMask || IsBakedShadowMaskLight(light.light);
m_enableBakeShadowMask = m_enableBakeShadowMask || IsBakedShadowMaskLight(lightComponent);
var additionalLightData = GetHDAdditionalLightData(light);
var additionalShadowData = light.light.GetComponent<AdditionalShadowData>(); // Can be null
var additionalLightData = GetHDAdditionalLightData(lightComponent);
var additionalShadowData = lightComponent != null ? lightComponent.GetComponent<AdditionalShadowData>() : null; // Can be null
if (GetDirectionalLightData(cmd, shadowSettings, gpuLightType, light, additionalLightData, additionalShadowData, lightIndex, debugDisplaySettings))
if (GetDirectionalLightData(cmd, shadowSettings, gpuLightType, light, lightComponent, additionalLightData, additionalShadowData, lightIndex, debugDisplaySettings))
{
directionalLightcount++;

Vector3 lightDimensions = new Vector3(); // X = length or width, Y = height, Z = range (depth)
// Punctual, area, projector lights - the rendering side.
if (GetLightData(cmd, shadowSettings, camera, gpuLightType, light, additionalLightData, additionalShadowData, lightIndex, ref lightDimensions, debugDisplaySettings))
if (GetLightData(cmd, shadowSettings, camera, gpuLightType, light, lightComponent, additionalLightData, additionalShadowData, lightIndex, ref lightDimensions, debugDisplaySettings))
{
switch (lightCategory)
{

var totalProbes = cullResults.visibleReflectionProbes.Count + reflectionProbeCullResults.visiblePlanarReflectionProbeCount;
int probeCount = Math.Min(totalProbes, k_MaxEnvLightsOnScreen);
sortKeys = new uint[probeCount];
UpdateSortKeysArray(probeCount);
sortCount = 0;
for (int probeIndex = 0, numProbes = totalProbes; (probeIndex < numProbes) && (sortCount < probeCount); probeIndex++)

var logVolume = CalculateProbeLogVolume(probe.bounds);
sortKeys[sortCount++] = PackProbeKey(logVolume, lightVolumeType, 0u, probeIndex); // Sort by volume
m_SortKeys[sortCount++] = PackProbeKey(logVolume, lightVolumeType, 0u, probeIndex); // Sort by volume
}
else
{

var logVolume = CalculateProbeLogVolume(probe.bounds);
sortKeys[sortCount++] = PackProbeKey(logVolume, lightVolumeType, 1u, planarProbeIndex); // Sort by volume
m_SortKeys[sortCount++] = PackProbeKey(logVolume, lightVolumeType, 1u, planarProbeIndex); // Sort by volume
CoreUtils.QuickSort(sortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
CoreUtils.QuickSort(m_SortKeys, 0, sortCount - 1); // Call our own quicksort instead of Array.Sort(sortKeys, 0, sortCount) so we don't allocate memory (note the SortCount-1 that is different from original call).
uint sortKey = sortKeys[sortIndex];
uint sortKey = m_SortKeys[sortIndex];
LightVolumeType lightVolumeType;
int probeIndex;
int listType;

bool isOrthographic = camera.orthographic;
// camera to screen matrix (and it's inverse)
var projArr = new Matrix4x4[2];
var projscrArr = new Matrix4x4[2];
var invProjscrArr = new Matrix4x4[2];
if (m_FrameSettings.enableStereo)
{
// XRTODO: If possible, we could generate a non-oblique stereo projection

// Once we generate this non-oblique projection matrix, it can be shared across both eyes (un-array)
for (int eyeIndex = 0; eyeIndex < 2; eyeIndex++)
{
projArr[eyeIndex] = CameraProjectionStereoLHS(hdCamera.camera, (Camera.StereoscopicEye)eyeIndex);
projscrArr[eyeIndex] = temp * projArr[eyeIndex];
invProjscrArr[eyeIndex] = projscrArr[eyeIndex].inverse;
m_LightListProjMatrices[eyeIndex] = CameraProjectionStereoLHS(hdCamera.camera, (Camera.StereoscopicEye)eyeIndex);
m_LightListProjscrMatrices[eyeIndex] = temp * m_LightListProjMatrices[eyeIndex];
m_LightListInvProjscrMatrices[eyeIndex] = m_LightListProjscrMatrices[eyeIndex].inverse;
projArr[0] = GeometryUtils.GetProjectionMatrixLHS(hdCamera.camera);
projscrArr[0] = temp * projArr[0];
invProjscrArr[0] = projscrArr[0].inverse;
m_LightListProjMatrices[0] = GeometryUtils.GetProjectionMatrixLHS(hdCamera.camera);
m_LightListProjscrMatrices[0] = temp * m_LightListProjMatrices[0];
m_LightListInvProjscrMatrices[0] = m_LightListProjscrMatrices[0].inverse;
var isProjectionOblique = GeometryUtils.IsProjectionMatrixOblique(projArr[0]);
var isProjectionOblique = GeometryUtils.IsProjectionMatrixOblique(m_LightListProjMatrices[0]);
// generate screen-space AABBs (used for both fptl and clustered).
if (m_lightCount != 0)

temp.SetRow(2, new Vector4(0.0f, 0.0f, 0.5f, 0.5f));
temp.SetRow(3, new Vector4(0.0f, 0.0f, 0.0f, 1.0f));
var projhArr = new Matrix4x4[2];
var invProjhArr = new Matrix4x4[2];
projhArr[eyeIndex] = temp * projArr[eyeIndex];
invProjhArr[eyeIndex] = projhArr[eyeIndex].inverse;
m_LightListProjHMatrices[eyeIndex] = temp * m_LightListProjMatrices[eyeIndex];
m_LightListInvProjHMatrices[eyeIndex] = m_LightListProjHMatrices[eyeIndex].inverse;
projhArr[0] = temp * projArr[0];
invProjhArr[0] = projhArr[0].inverse;
m_LightListProjHMatrices[0] = temp * m_LightListProjMatrices[0];
m_LightListInvProjHMatrices[0] = m_LightListProjHMatrices[0].inverse;
}
var genAABBKernel = isProjectionOblique ? s_GenAABBKernel_Oblique : s_GenAABBKernel;

cmd.SetComputeIntParam(buildScreenAABBShader, HDShaderIDs.g_iNrVisibLights, m_lightCount);
cmd.SetComputeBufferParam(buildScreenAABBShader, genAABBKernel, HDShaderIDs.g_data, s_ConvexBoundsBuffer);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mProjectionArr, projhArr);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mInvProjectionArr, invProjhArr);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mProjectionArr, m_LightListProjHMatrices);
cmd.SetComputeMatrixArrayParam(buildScreenAABBShader, HDShaderIDs.g_mInvProjectionArr, m_LightListInvProjHMatrices);
// In stereo, we output two sets of AABB bounds
cmd.SetComputeBufferParam(buildScreenAABBShader, genAABBKernel, HDShaderIDs.g_vBoundsBuffer, s_AABBBoundsBuffer);

cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs._EnvLightIndexShift, m_lightList.lights.Count);
cmd.SetComputeIntParam(buildPerBigTileLightListShader, HDShaderIDs._DecalIndexShift, m_lightList.lights.Count + m_lightList.envLights.Count);
cmd.SetComputeMatrixArrayParam(buildPerBigTileLightListShader, HDShaderIDs.g_mScrProjectionArr, projscrArr);
cmd.SetComputeMatrixArrayParam(buildPerBigTileLightListShader, HDShaderIDs.g_mInvScrProjectionArr, invProjscrArr);
cmd.SetComputeMatrixArrayParam(buildPerBigTileLightListShader, HDShaderIDs.g_mScrProjectionArr, m_LightListProjscrMatrices);
cmd.SetComputeMatrixArrayParam(buildPerBigTileLightListShader, HDShaderIDs.g_mInvScrProjectionArr, m_LightListInvProjscrMatrices);
cmd.SetComputeFloatParam(buildPerBigTileLightListShader, HDShaderIDs.g_fNearPlane, camera.nearClipPlane);
cmd.SetComputeFloatParam(buildPerBigTileLightListShader, HDShaderIDs.g_fFarPlane, camera.farClipPlane);

cmd.SetComputeBufferParam(buildPerTileLightListShader, genListPerTileKernel, HDShaderIDs._LightVolumeData, s_LightVolumeDataBuffer);
cmd.SetComputeBufferParam(buildPerTileLightListShader, genListPerTileKernel, HDShaderIDs.g_data, s_ConvexBoundsBuffer);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mScrProjection, projscrArr[0]);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mInvScrProjection, invProjscrArr[0]);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mScrProjection, m_LightListProjscrMatrices[0]);
cmd.SetComputeMatrixParam(buildPerTileLightListShader, HDShaderIDs.g_mInvScrProjection, m_LightListInvProjscrMatrices[0]);
cmd.SetComputeTextureParam(buildPerTileLightListShader, genListPerTileKernel, HDShaderIDs.g_depth_tex, cameraDepthBufferRT);
cmd.SetComputeBufferParam(buildPerTileLightListShader, genListPerTileKernel, HDShaderIDs.g_vLightList, s_LightList);

}
// Cluster
VoxelLightListGeneration(cmd, hdCamera, projscrArr, invProjscrArr, cameraDepthBufferRT);
VoxelLightListGeneration(cmd, hdCamera, m_LightListProjscrMatrices, m_LightListInvProjscrMatrices, cameraDepthBufferRT);
if (enableFeatureVariants)
{

s_LightVolumeDataBuffer.SetData(m_lightList.lightVolumes);
}
HDAdditionalLightData GetHDAdditionalLightData(VisibleLight light)
HDAdditionalLightData GetHDAdditionalLightData(Light light)
var add = light.light.GetComponent<HDAdditionalLightData>();
// Light reference can be null for particle lights.
var add = light != null ? light.GetComponent<HDAdditionalLightData>() : null;
if (add == null)
{
add = HDUtils.s_DefaultHDAdditionalLightData;

}
}
public void RenderDebugOverlay(HDCamera hdCamera, CommandBuffer cmd, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width)
public void RenderDebugOverlay(HDCamera hdCamera, CommandBuffer cmd, DebugDisplaySettings debugDisplaySettings, ref float x, ref float y, float overlaySize, float width, CullResults cullResults)
{
LightingDebugSettings lightingDebug = debugDisplaySettings.lightingDebugSettings;

{
m_ShadowMgr.DisplayShadowMap(cmd, m_DebugShadowMapMaterial, lightingDebug.shadowAtlasIndex, lightingDebug.shadowSliceIndex, x, y, overlaySize, overlaySize, lightingDebug.shadowMinValue, lightingDebug.shadowMaxValue, hdCamera.camera.cameraType != CameraType.SceneView);
HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, hdCamera.actualWidth);
}
}
if (lightingDebug.displayLightVolumes)
{
// First of all let's do the regions for the light sources (we only support Poncutal and Area)
int numLights = cullResults.visibleLights.Count;
for (int lightIdx = 0; lightIdx < numLights; ++lightIdx)
{
// Let's build the light's bounding sphere matrix
Light currentLegacyLight = cullResults.visibleLights[lightIdx].light;
if (currentLegacyLight == null) continue;
HDAdditionalLightData currentHDRLight = currentLegacyLight.GetComponent<HDAdditionalLightData>();
if (currentHDRLight == null) continue;
MaterialPropertyBlock materialBlock = new MaterialPropertyBlock();
Matrix4x4 positionMat = Matrix4x4.Translate(currentLegacyLight.transform.position);
if(currentLegacyLight.type == LightType.Point || currentLegacyLight.type == LightType.Area)
{
materialBlock.SetVector("_Range", new Vector3(currentLegacyLight.range, currentLegacyLight.range, currentLegacyLight.range));
switch (currentHDRLight.lightTypeExtent)
{
case LightTypeExtent.Punctual:
{
materialBlock.SetColor("_Color", new Color(0.0f, 1.0f, 0.0f, 0.5f));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
cmd.DrawMesh(DebugShapes.instance.RequestSphereMesh(), positionMat, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
break;
case LightTypeExtent.Rectangle:
{
materialBlock.SetColor("_Color", new Color(0.0f, 1.0f, 1.0f, 0.5f));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
cmd.DrawMesh(DebugShapes.instance.RequestSphereMesh(), positionMat, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
break;
case LightTypeExtent.Line:
{
materialBlock.SetColor("_Color", new Color(1.0f, 0.0f, 0.5f, 0.5f));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
cmd.DrawMesh(DebugShapes.instance.RequestSphereMesh(), positionMat, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
break;
default:
break;
}
}
else if(currentLegacyLight.type == LightType.Spot)
{
if(currentHDRLight.spotLightShape == SpotLightShape.Cone)
{
float bottomRadius = Mathf.Tan(currentLegacyLight.spotAngle * Mathf.PI / 360.0f) * currentLegacyLight.range;
materialBlock.SetColor("_Color", new Color(1.0f, 0.5f, 0.0f, 0.5f));
materialBlock.SetVector("_Range", new Vector3(bottomRadius, bottomRadius, currentLegacyLight.range));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
cmd.DrawMesh(DebugShapes.instance.RequestConeMesh(), currentLegacyLight.gameObject.transform.localToWorldMatrix, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
else if(currentHDRLight.spotLightShape == SpotLightShape.Box)
{
materialBlock.SetColor("_Color", new Color(1.0f, 0.5f, 0.0f, 0.5f));
materialBlock.SetVector("_Range", new Vector3(currentHDRLight.shapeWidth, currentHDRLight.shapeHeight, currentLegacyLight.range));
materialBlock.SetVector("_Offset", new Vector3(0, 0, currentLegacyLight.range / 2.0f));
cmd.DrawMesh(DebugShapes.instance.RequestBoxMesh(), currentLegacyLight.gameObject.transform.localToWorldMatrix, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
else if (currentHDRLight.spotLightShape == SpotLightShape.Pyramid)
{
float bottomWidth = Mathf.Tan(currentLegacyLight.spotAngle * Mathf.PI / 360.0f) * currentLegacyLight.range;
materialBlock.SetColor("_Color", new Color(1.0f, 0.5f, 0.0f, 0.5f));
materialBlock.SetVector("_Range", new Vector3(currentHDRLight.aspectRatio * bottomWidth * 2, bottomWidth * 2 , currentLegacyLight.range));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
cmd.DrawMesh(DebugShapes.instance.RequestPyramidMesh(), currentLegacyLight.gameObject.transform.localToWorldMatrix, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
}
}
// Now let's do the same but for reflection probes
int numProbes = cullResults.visibleReflectionProbes.Count;
for (int probeIdx = 0; probeIdx < numProbes; ++probeIdx)
{
// Let's build the light's bounding sphere matrix
ReflectionProbe currentLegacyProbe = cullResults.visibleReflectionProbes[probeIdx].probe;
HDAdditionalReflectionData currentHDProbe = currentLegacyProbe.GetComponent<HDAdditionalReflectionData>();
MaterialPropertyBlock materialBlock = new MaterialPropertyBlock();
Mesh targetMesh = null;
if (currentHDProbe.influenceVolume.shape == InfluenceShape.Sphere)
{
materialBlock.SetVector("_Range", new Vector3(currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius));
targetMesh = DebugShapes.instance.RequestSphereMesh();
}
else
{
materialBlock.SetVector("_Range", new Vector3(currentHDProbe.influenceVolume.boxSize.x, currentHDProbe.influenceVolume.boxSize.y, currentHDProbe.influenceVolume.boxSize.z));
targetMesh = DebugShapes.instance.RequestBoxMesh();
}
materialBlock.SetColor("_Color", new Color(1.0f, 1.0f, 0.0f, 0.5f));
materialBlock.SetVector("_Offset", new Vector3(0, 0, 0));
Matrix4x4 positionMat = Matrix4x4.Translate(currentLegacyProbe.transform.position);
cmd.DrawMesh(targetMesh, positionMat, m_DebugLightVolumeMaterial, 0, -1, materialBlock);
}
}
}

8
com.unity.render-pipelines.high-definition/HDRP/Lighting/Volumetrics/VolumetricLighting.cs


// VisualEnvironment sets global fog parameters: _GlobalAnisotropy, _GlobalScattering, _GlobalExtinction.
if (!hdCamera.frameSettings.enableVolumetrics || visualEnvironment.fogType != FogType.Volumetric)
if (!hdCamera.frameSettings.enableVolumetrics || visualEnvironment.fogType.value != FogType.Volumetric)
{
// Set the neutral black texture.
cmd.SetGlobalTexture(HDShaderIDs._VBufferLighting, CoreUtils.blackVolumeTexture);

return densityVolumes;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric)
if (visualEnvironment.fogType.value != FogType.Volumetric)
return densityVolumes;
using (new ProfilingSample(cmd, "Prepare Visible Density Volume List"))

return;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric)
if (visualEnvironment.fogType.value != FogType.Volumetric)
return;
using (new ProfilingSample(cmd, "Volume Voxelization"))

return;
var visualEnvironment = VolumeManager.instance.stack.GetComponent<VisualEnvironment>();
if (visualEnvironment.fogType != FogType.Volumetric)
if (visualEnvironment.fogType.value != FogType.Volumetric)
return;
using (new ProfilingSample(cmd, "Volumetric Lighting"))

14
com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/HDRenderPipeline.cs


{
currentFrameSettings.enablePostprocess = false;
}
// Disable SSS if luxmeter is enabled
if (debugDisplaySettings.lightingDebugSettings.debugLightingMode == DebugLightingMode.LuxMeter)
{

{
VolumeManager.instance.Update(hdCamera.volumeAnchor, hdCamera.volumeLayerMask);
}
// Do anything we need to do upon a new frame.
// The NewFrame must be after the VolumeManager update and before Resize because it uses properties set in NewFrame
m_LightLoop.NewFrame(currentFrameSettings);

#endif
PushFullScreenDebugTexture(hdCamera, cmd, m_CameraColorBuffer, FullScreenDebugMode.ScreenSpaceTracing);
// Caution: RenderDebug need to take into account that we have flip the screen (so anything capture before the flip will be flipped)
RenderDebug(hdCamera, cmd);
RenderDebug(hdCamera, cmd, m_CullResults);
#if UNITY_EDITOR
// We need to make sure the viewport is correctly set for the editor rendering. It might have been changed by debug overlay rendering just before.

m_SkyManager.RenderSky(hdCamera, m_LightLoop.GetCurrentSunLight(), m_CameraColorBuffer, m_CameraDepthStencilBuffer, m_CurrentDebugDisplaySettings, cmd);
if (visualEnv.fogType != FogType.None)
if (visualEnv.fogType.value != FogType.None)
m_SkyManager.RenderOpaqueAtmosphericScattering(cmd);
}

public void ApplyDebugDisplaySettings(HDCamera hdCamera, CommandBuffer cmd)
{
// See ShaderPassForward.hlsl: for forward shaders, if DEBUG_DISPLAY is enabled and no DebugLightingMode or DebugMipMapMod
// See ShaderPassForward.hlsl: for forward shaders, if DEBUG_DISPLAY is enabled and no DebugLightingMode or DebugMipMapMod
// modes have been set, lighting is automatically skipped (To avoid some crashed due to lighting RT not set on console).
// However debug mode like colorPickerModes and false color don't need DEBUG_DISPLAY and must work with the lighting.
// So we will enabled DEBUG_DISPLAY independently

}
}
void RenderDebug(HDCamera hdCamera, CommandBuffer cmd)
void RenderDebug(HDCamera hdCamera, CommandBuffer cmd, CullResults cullResults)
{
// We don't want any overlay for these kind of rendering
if (hdCamera.camera.cameraType == CameraType.Reflection || hdCamera.camera.cameraType == CameraType.Preview)

HDUtils.NextOverlayCoord(ref x, ref y, overlaySize, overlaySize, hdCamera.actualWidth);
}
m_LightLoop.RenderDebugOverlay(hdCamera, cmd, m_CurrentDebugDisplaySettings, ref x, ref y, overlaySize, hdCamera.actualWidth);
m_LightLoop.RenderDebugOverlay(hdCamera, cmd, m_CurrentDebugDisplaySettings, ref x, ref y, overlaySize, hdCamera.actualWidth, cullResults);
DecalSystem.instance.RenderDebugOverlay(hdCamera, cmd, m_CurrentDebugDisplaySettings, ref x, ref y, overlaySize, hdCamera.actualWidth);

1
com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/HDRenderPipelineResources.asset


debugViewTilesShader: {fileID: 4800000, guid: c7c2bd17b06ceb4468e14081aaf1b96f, type: 3}
debugFullScreenShader: {fileID: 4800000, guid: e874aca2df8300a488258738c31f85cf, type: 3}
debugColorPickerShader: {fileID: 4800000, guid: 8137b807709e178498f22ed710864bb0, type: 3}
debugLightVolumeShader: {fileID: 4800000, guid: f62fc49f20e79e64ba43db3cfd447d80, type: 3}
deferredShader: {fileID: 4800000, guid: 00dd221e34a6ab349a1196b0f2fab693, type: 3}
colorPyramidCS: {fileID: 7200000, guid: 4e3267a1135742441a14298d8dcac04a, type: 3}
depthPyramidCS: {fileID: 7200000, guid: 64a553bb564274041906f78ffba955e4, type: 3}

6
com.unity.render-pipelines.high-definition/HDRP/RenderPipelineResources/RenderPipelineResources.cs


{
public class RenderPipelineResources : ScriptableObject
{
const int currentVersion = 2;
const int currentVersion = 3;
[SerializeField]
[FormerlySerializedAs("version")]
int m_Version = 1;

public Shader debugViewTilesShader;
public Shader debugFullScreenShader;
public Shader debugColorPickerShader;
public Shader debugLightVolumeShader;
// Lighting resources
public Shader deferredShader;

debugViewTilesShader = Load<Shader>(HDRenderPipelinePath + "Debug/DebugViewTiles.Shader");
debugFullScreenShader = Load<Shader>(HDRenderPipelinePath + "Debug/DebugFullScreen.Shader");
debugColorPickerShader = Load<Shader>(HDRenderPipelinePath + "Debug/DebugColorPicker.Shader");
debugLightVolumeShader = Load<Shader>(HDRenderPipelinePath + "Debug/DebugLightVolume.Shader");
deferredShader = Load<Shader>(HDRenderPipelinePath + "Lighting/Deferred.Shader");
colorPyramidCS = Load<ComputeShader>(HDRenderPipelinePath + "RenderPipelineResources/ColorPyramid.compute");

// Material
preIntegratedFGD_GGXDisneyDiffuse = Load<Shader>(HDRenderPipelinePath + "Material/PreIntegratedFGD/PreIntegratedFGD_GGXDisneyDiffuse.shader");
preIntegratedFGD_CharlieFabricLambert = Load<Shader>(HDRenderPipelinePath + "Material/PreIntegratedFGD/PreIntegratedFGD_CharlieClothLambert.shader");
preIntegratedFGD_CharlieFabricLambert = Load<Shader>(HDRenderPipelinePath + "Material/PreIntegratedFGD/PreIntegratedFGD_CharlieFabricLambert.shader");
// Utilities / Core
encodeBC6HCS = Load<ComputeShader>(CorePath + "CoreResources/EncodeBC6H.compute");

506
com.unity.render-pipelines.core/CoreRP/Debugging/DebugShapes.cs


namespace UnityEngine.Experimental.Rendering
{
public partial class DebugShapes
{
// Singleton
static DebugShapes s_Instance = null;
static public DebugShapes instance
{
get
{
if (s_Instance == null)
{
s_Instance = new DebugShapes();
}
return s_Instance;
}
}
Mesh m_sphereMesh = null;
Mesh m_boxMesh = null;
Mesh m_coneMesh = null;
Mesh m_pyramidMesh = null;
// This code has been grabbed from http://wiki.unity3d.com/index.php/ProceduralPrimitives
void BuildSphere(ref Mesh outputMesh, float radius, uint longSubdiv, uint latSubdiv)
{
// Make sure it is empty before pushing anything to it
outputMesh.Clear();
// Build the vertices array
Vector3[] vertices = new Vector3[(longSubdiv + 1) * latSubdiv + 2];
float _pi = Mathf.PI;
float _2pi = _pi * 2f;
vertices[0] = Vector3.up * radius;
for (int lat = 0; lat < latSubdiv; lat++)
{
float a1 = _pi * (float)(lat + 1) / (latSubdiv + 1);
float sin1 = Mathf.Sin(a1);
float cos1 = Mathf.Cos(a1);
for (int lon = 0; lon <= longSubdiv; lon++)
{
float a2 = _2pi * (float)(lon == longSubdiv ? 0 : lon) / longSubdiv;
float sin2 = Mathf.Sin(a2);
float cos2 = Mathf.Cos(a2);
vertices[lon + lat * (longSubdiv + 1) + 1] = new Vector3(sin1 * cos2, cos1, sin1 * sin2) * radius;
}
}
vertices[vertices.Length - 1] = Vector3.up * -radius;
// Build the normals array
Vector3[] normals = new Vector3[vertices.Length];
for (int n = 0; n < vertices.Length; n++)
{
normals[n] = vertices[n].normalized;
}
// Build the UV array
Vector2[] uvs = new Vector2[vertices.Length];
uvs[0] = Vector2.up;
uvs[uvs.Length - 1] = Vector2.zero;
for (int lat = 0; lat < latSubdiv; lat++)
{
for (int lon = 0; lon <= longSubdiv; lon++)
{
uvs[lon + lat * (longSubdiv + 1) + 1] = new Vector2((float)lon / longSubdiv, 1f - (float)(lat + 1) / (latSubdiv + 1));
}
}
// Build the index array
int nbFaces = vertices.Length;
int nbTriangles = nbFaces * 2;
int nbIndexes = nbTriangles * 3;
int[] triangles = new int[nbIndexes];
// Top Cap
int i = 0;
for (int lon = 0; lon < longSubdiv; lon++)
{
triangles[i++] = lon + 2;
triangles[i++] = lon + 1;
triangles[i++] = 0;
}
//Middle
for (uint lat = 0; lat < latSubdiv - 1; lat++)
{
for (uint lon = 0; lon < longSubdiv; lon++)
{
uint current = lon + lat * (longSubdiv + 1) + 1;
uint next = current + longSubdiv + 1;
triangles[i++] = (int)current;
triangles[i++] = (int)current + 1;
triangles[i++] = (int)next + 1;
triangles[i++] = (int)current;
triangles[i++] = (int)next + 1;
triangles[i++] = (int)next;
}
}
// Bottom Cap
for (int lon = 0; lon < longSubdiv; lon++)
{
triangles[i++] = vertices.Length - 1;
triangles[i++] = vertices.Length - (lon + 2) - 1;
triangles[i++] = vertices.Length - (lon + 1) - 1;
}
// Assign them to
outputMesh.vertices = vertices;
outputMesh.normals = normals;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildBox(ref Mesh outputMesh, float length, float width, float height)
{
outputMesh.Clear();
Vector3 p0 = new Vector3(-length * .5f, -width * .5f, height * .5f);
Vector3 p1 = new Vector3(length * .5f, -width * .5f, height * .5f);
Vector3 p2 = new Vector3(length * .5f, -width * .5f, -height * .5f);
Vector3 p3 = new Vector3(-length * .5f, -width * .5f, -height * .5f);
Vector3 p4 = new Vector3(-length * .5f, width * .5f, height * .5f);
Vector3 p5 = new Vector3(length * .5f, width * .5f, height * .5f);
Vector3 p6 = new Vector3(length * .5f, width * .5f, -height * .5f);
Vector3 p7 = new Vector3(-length * .5f, width * .5f, -height * .5f);
Vector3[] vertices = new Vector3[]
{
// Bottom
p0, p1, p2, p3,
// Left
p7, p4, p0, p3,
// Front
p4, p5, p1, p0,
// Back
p6, p7, p3, p2,
// Right
p5, p6, p2, p1,
// Top
p7, p6, p5, p4
};
Vector3 up = Vector3.up;
Vector3 down = Vector3.down;
Vector3 front = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
Vector3[] normales = new Vector3[]
{
// Bottom
down, down, down, down,
// Left
left, left, left, left,
// Front
front, front, front, front,
// Back
back, back, back, back,
// Right
right, right, right, right,
// Top
up, up, up, up
};
Vector2 _00 = new Vector2(0f, 0f);
Vector2 _10 = new Vector2(1f, 0f);
Vector2 _01 = new Vector2(0f, 1f);
Vector2 _11 = new Vector2(1f, 1f);
Vector2[] uvs = new Vector2[]
{
// Bottom
_11, _01, _00, _10,
// Left
_11, _01, _00, _10,
// Front
_11, _01, _00, _10,
// Back
_11, _01, _00, _10,
// Right
_11, _01, _00, _10,
// Top
_11, _01, _00, _10,
};
int[] triangles = new int[]
{
// Bottom
3, 1, 0,
3, 2, 1,
// Left
3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
// Front
3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
// Back
3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
// Right
3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
// Top
3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5,
};
outputMesh.vertices = vertices;
outputMesh.normals = normales;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildCone(ref Mesh outputMesh, float height, float topRadius, float bottomRadius, int nbSides)
{
outputMesh.Clear();
int nbVerticesCap = nbSides + 1;
// bottom + top + sides
Vector3[] vertices = new Vector3[nbVerticesCap + nbVerticesCap + nbSides * 2 + 2];
int vert = 0;
float _2pi = Mathf.PI * 2f;
// Bottom cap
vertices[vert++] = new Vector3(0f, 0f, 0f);
while (vert <= nbSides)
{
float rad = (float)vert / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * bottomRadius, Mathf.Cos(rad) * bottomRadius, 0f);
vert++;
}
// Top cap
vertices[vert++] = new Vector3(0f, 0f , height);
while (vert <= nbSides * 2 + 1)
{
float rad = (float)(vert - nbSides - 1) / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * topRadius, Mathf.Cos(rad) * topRadius, height);
vert++;
}
// Sides
int v = 0;
while (vert <= vertices.Length - 4)
{
float rad = (float)v / nbSides * _2pi;
vertices[vert] = new Vector3(Mathf.Sin(rad) * topRadius, Mathf.Cos(rad) * topRadius, height);
vertices[vert + 1] = new Vector3(Mathf.Sin(rad) * bottomRadius, Mathf.Cos(rad) * bottomRadius, 0);
vert += 2;
v++;
}
vertices[vert] = vertices[nbSides * 2 + 2];
vertices[vert + 1] = vertices[nbSides * 2 + 3];
// bottom + top + sides
Vector3[] normales = new Vector3[vertices.Length];
vert = 0;
// Bottom cap
while (vert <= nbSides)
{
normales[vert++] = new Vector3(0, 0, -1);
}
// Top cap
while (vert <= nbSides * 2 + 1)
{
normales[vert++] = new Vector3(0, 0, 1);
}
// Sides
v = 0;
while (vert <= vertices.Length - 4)
{
float rad = (float)v / nbSides * _2pi;
float cos = Mathf.Cos(rad);
float sin = Mathf.Sin(rad);
normales[vert] = new Vector3(sin, cos, 0f);
normales[vert + 1] = normales[vert];
vert += 2;
v++;
}
normales[vert] = normales[nbSides * 2 + 2];
normales[vert + 1] = normales[nbSides * 2 + 3];
Vector2[] uvs = new Vector2[vertices.Length];
// Bottom cap
int u = 0;
uvs[u++] = new Vector2(0.5f, 0.5f);
while (u <= nbSides)
{
float rad = (float)u / nbSides * _2pi;
uvs[u] = new Vector2(Mathf.Cos(rad) * .5f + .5f, Mathf.Sin(rad) * .5f + .5f);
u++;
}
// Top cap
uvs[u++] = new Vector2(0.5f, 0.5f);
while (u <= nbSides * 2 + 1)
{
float rad = (float)u / nbSides * _2pi;
uvs[u] = new Vector2(Mathf.Cos(rad) * .5f + .5f, Mathf.Sin(rad) * .5f + .5f);
u++;
}
// Sides
int u_sides = 0;
while (u <= uvs.Length - 4)
{
float t = (float)u_sides / nbSides;
uvs[u] = new Vector3(t, 1f);
uvs[u + 1] = new Vector3(t, 0f);
u += 2;
u_sides++;
}
uvs[u] = new Vector2(1f, 1f);
uvs[u + 1] = new Vector2(1f, 0f);
int nbTriangles = nbSides + nbSides + nbSides * 2;
int[] triangles = new int[nbTriangles * 3 + 3];
// Bottom cap
int tri = 0;
int i = 0;
while (tri < nbSides - 1)
{
triangles[i] = 0;
triangles[i + 1] = tri + 1;
triangles[i + 2] = tri + 2;
tri++;
i += 3;
}
triangles[i] = 0;
triangles[i + 1] = tri + 1;
triangles[i + 2] = 1;
tri++;
i += 3;
// Top cap
//tri++;
while (tri < nbSides * 2)
{
triangles[i] = tri + 2;
triangles[i + 1] = tri + 1;
triangles[i + 2] = nbVerticesCap;
tri++;
i += 3;
}
triangles[i] = nbVerticesCap + 1;
triangles[i + 1] = tri + 1;
triangles[i + 2] = nbVerticesCap;
tri++;
i += 3;
tri++;
// Sides
while (tri <= nbTriangles)
{
triangles[i] = tri + 2;
triangles[i + 1] = tri + 1;
triangles[i + 2] = tri + 0;
tri++;
i += 3;
triangles[i] = tri + 1;
triangles[i + 1] = tri + 2;
triangles[i + 2] = tri + 0;
tri++;
i += 3;
}
outputMesh.vertices = vertices;
outputMesh.normals = normales;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildPyramid(ref Mesh outputMesh, float width, float height, float depth)
{
outputMesh.Clear();
// Allocate the buffer
Vector3[] vertices = new Vector3[16];
// Top Face
vertices[0] = new Vector3(0f, 0f, 0f);
vertices[1] = new Vector3(-width/2.0f, height / 2.0f, depth);
vertices[2] = new Vector3( width / 2.0f, height / 2.0f, depth);
// Left Face
vertices[3] = new Vector3(0f, 0f, 0f);
vertices[4] = new Vector3(width / 2.0f, height / 2.0f, depth);
vertices[5] = new Vector3(width / 2.0f, -height / 2.0f, depth);
// Bottom Face
vertices[6] = new Vector3(0f, 0f, 0f);
vertices[7] = new Vector3(width / 2.0f, -height / 2.0f, depth);
vertices[8] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
// Right Face
vertices[9] = new Vector3(0f, 0f, 0f);
vertices[10] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
vertices[11] = new Vector3(-width / 2.0f, height / 2.0f, depth);
// Cap
vertices[12] = new Vector3(-width / 2.0f, height / 2.0f, depth);
vertices[13] = new Vector3(-width / 2.0f, -height / 2.0f, depth);
vertices[14] = new Vector3(width / 2.0f, -height / 2.0f, depth);
vertices[15] = new Vector3(width / 2.0f, height / 2.0f, depth);
// TODO: support the uv/normals
Vector3[] normals = new Vector3[vertices.Length];
Vector2[] uvs = new Vector2[vertices.Length];
// The indexes for the side part is simple
int[] triangles = new int[18];
for(int idx = 0; idx < 12; ++idx)
{
triangles[idx] = idx;
}
// Cap indexes
triangles[12] = 12;
triangles[13] = 13;
triangles[14] = 14;
triangles[15] = 12;
triangles[16] = 14;
triangles[17] = 15;
outputMesh.vertices = vertices;
outputMesh.normals = normals;
outputMesh.uv = uvs;
outputMesh.triangles = triangles;
outputMesh.RecalculateBounds();
}
void BuildShapes()
{
m_sphereMesh = new Mesh();
BuildSphere(ref m_sphereMesh, 1.0f, 24, 16);
m_boxMesh = new Mesh();
BuildBox(ref m_boxMesh, 1.0f, 1.0f, 1.0f);
m_coneMesh = new Mesh();
BuildCone(ref m_coneMesh, 1.0f, 1.0f, 0.0f, 16);
m_pyramidMesh = new Mesh();
BuildPyramid(ref m_pyramidMesh, 1.0f, 1.0f, 1.0f);
}
public void CheckResources()
{
if (m_sphereMesh == null || m_boxMesh == null || m_coneMesh == null || m_pyramidMesh == null)
{
BuildShapes();
}
}
public Mesh RequestSphereMesh()
{
CheckResources();
return m_sphereMesh;
}
public Mesh RequestBoxMesh()
{
CheckResources();
return m_boxMesh;
}
public Mesh RequestConeMesh()
{
CheckResources();
return m_coneMesh;
}
public Mesh RequestPyramidMesh()
{
CheckResources();
return m_pyramidMesh;
}
}
}

11
com.unity.render-pipelines.core/CoreRP/Debugging/DebugShapes.cs.meta


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

58
com.unity.render-pipelines.high-definition/HDRP/Debug/DebugLightVolume.shader


Shader "Hidden/HDRenderPipeline/DebugLightVolume"
{
Properties
{
_Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)
_Range("Range", Vector) = (1.0, 1.0, 1.0, 1.0)
_Offset("Offset", Vector) = (1.0, 1.0, 1.0, 1.0)
}
SubShader
{
Tags { "Queue" = "Transparent" }
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
Cull Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "CoreRP/ShaderLibrary/Common.hlsl"
#include "HDRP/ShaderVariables.hlsl"
struct AttributesDefault
{
float4 positionOS : POSITION;
};
struct VaryingsDefault
{
float4 positionCS : SV_POSITION;
};
float3 _Range;
float3 _Offset;
float4 _Color;
VaryingsDefault vert(AttributesDefault att)
{
VaryingsDefault output;
float3 positionRWS = TransformObjectToWorld(att.positionOS * _Range + _Offset);
output.positionCS = TransformWorldToHClip(positionRWS);
return output;
}
float4 frag(VaryingsDefault varying) : SV_TARGET0
{
return _Color;
}
ENDHLSL
}
}
}

9
com.unity.render-pipelines.high-definition/HDRP/Debug/DebugLightVolume.shader.meta


fileFormatVersion: 2
guid: f62fc49f20e79e64ba43db3cfd447d80
ShaderImporter:
externalObjects: {}
defaultTextures: []
nonModifiableTextures: []
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存