Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public static void Initialize(Shader blitPS, Shader blitColorAndDepthPS)
s_BlitTexArraySingleSlice.EnableKeyword("BLIT_SINGLE_SLICE");
}

if (SystemInfo.graphicsShaderLevel < 30)
if (SystemInfo.graphicsShaderLevel <= 30)
{
/*UNITY_NEAR_CLIP_VALUE*/
float nearClipZ = -1;
Expand Down Expand Up @@ -186,15 +186,15 @@ static public Material GetBlitMaterial(TextureDimension dimension, bool singleSl

static private void DrawTriangle(CommandBuffer cmd, Material material, int shaderPass)
{
if (SystemInfo.graphicsShaderLevel < 30)
if (SystemInfo.graphicsShaderLevel <= 30)
cmd.DrawMesh(s_TriangleMesh, Matrix4x4.identity, material, 0, shaderPass, s_PropertyBlock);
else
cmd.DrawProcedural(Matrix4x4.identity, material, shaderPass, MeshTopology.Triangles, 3, 1, s_PropertyBlock);
}

static internal void DrawQuad(CommandBuffer cmd, Material material, int shaderPass)
{
if (SystemInfo.graphicsShaderLevel < 30)
if (SystemInfo.graphicsShaderLevel <= 30)
cmd.DrawMesh(s_QuadMesh, Matrix4x4.identity, material, 0, shaderPass, s_PropertyBlock);
else
cmd.DrawProcedural(Matrix4x4.identity, material, shaderPass, MeshTopology.Quads, 4, 1, s_PropertyBlock);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,16 @@ void DoCommonSettingsGUI(ref Rect rect)
{
EditorGUI.PropertyField(rect, m_TargetDepthBuffer, Styles.targetDepthBuffer);
rect.y += Styles.defaultLineSpace;

CustomPass.TargetBuffer requestedDepth = m_TargetDepthBuffer.GetEnumValue<CustomPass.TargetBuffer>();
if (m_CustomPass.getConstrainedDepthBuffer() != requestedDepth)
{
Rect helpBoxRect = rect;
float helpBoxHeight = EditorGUIUtility.singleLineHeight * 2;
helpBoxRect.height = helpBoxHeight;
EditorGUI.HelpBox(helpBoxRect, "Camera depth isn't supported when dynamic scaling is on. We will automatically fall back to not doing depth-testing for this pass.", MessageType.Warning);
rect.y += helpBoxHeight;
}
}

if ((commonPassUIFlags & PassUIFlag.ClearFlags) != 0)
Expand Down Expand Up @@ -264,6 +274,13 @@ internal float GetPropertyHeight(SerializedProperty property, GUIContent label)
}

height += Styles.defaultLineSpace * lines;

// Add height for the help box if it will be shown
if ((commonPassUIFlags & PassUIFlag.TargetDepthBuffer) != 0 &&
m_CustomPass.getConstrainedDepthBuffer() != m_TargetDepthBuffer.GetEnumValue<CustomPass.TargetBuffer>())
{
height += EditorGUIUtility.singleLineHeight * 2; // Help box height
}
}

return height + GetPassHeight(property);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS
#if SHADEROPTIONS_AREA_LIGHTS
if (featureFlags & LIGHTFEATUREFLAGS_AREA)
{
uint lightCount, lightStart;
uint lightCount, lightStart; // Start is the offset specific to the tile (or cluster)

#ifndef LIGHTLOOP_DISABLE_TILE_AND_CLUSTER
GetCountAndStart(posInput, LIGHTCATEGORY_AREA, lightStart, lightCount);
Expand All @@ -652,43 +652,57 @@ void LightLoop( float3 V, PositionInputs posInput, PreLightData preLightData, BS
lightStart = _PunctualLightCount;
#endif

// COMPILER BEHAVIOR WARNING!
// If rectangle lights are before line lights, the compiler will duplicate light matrices in VGPR because they are used differently between the two types of lights.
// By keeping line lights first we avoid this behavior and save substantial register pressure.
// TODO: This is based on the current Lit.shader and can be different for any other way of implementing area lights, how to be generic and ensure performance ?
bool fastPath = false;
#if SCALARIZE_LIGHT_LOOP
uint lightStartLane0;
fastPath = IsFastPath(lightStart, lightStartLane0); // True if all pixels belong to the same tile (or cluster)

if (lightCount > 0)
if (fastPath)
{
i = 0;

uint last = lightCount - 1;
LightData lightData = FetchLight(lightStart, i);
lightStart = lightStartLane0;
}
#endif

while (i <= last && lightData.lightType == GPULIGHTTYPE_TUBE)
{
lightData.lightType = GPULIGHTTYPE_TUBE; // Enforce constant propagation
lightData.cookieMode = COOKIEMODE_NONE; // Enforce constant propagation
// Scalarized loop. All lights that are in a tile/cluster touched by any pixel in the wave are loaded (scalar load), only the one relevant to current thread/pixel are processed.
// For clarity, the following code will follow the convention: variables starting with s_ are meant to be wave uniform (meant for scalar register),
// v_ are variables that might have different value for each thread in the wave (meant for vector registers).
// This will perform more loads than it is supposed to, however, the benefits should offset the downside, especially given that light data accessed should be largely coherent.
// Note that the above is valid only if wave intriniscs are supported.
uint v_lightListOffset = 0;
uint v_lightIdx = lightStart;

if (IsMatchingLightLayer(lightData.lightLayers, builtinData.renderingLayers))
{
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, lightData, bsdfData, builtinData);
AccumulateDirectLighting(lighting, aggregateLighting);
}
#if NEED_TO_CHECK_HELPER_LANE
// On some platform helper lanes don't behave as we'd expect, therefore we prevent them from entering the loop altogether.
// IMPORTANT! This has implications if ddx/ddy is used on results derived from lighting, however given Lightloop is called in compute we should be
// sure it will not happen.
bool isHelperLane = WaveIsHelperLane();
while (!isHelperLane && v_lightListOffset < lightCount)
#else
while (v_lightListOffset < lightCount)
#endif
{
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
#if SCALARIZE_LIGHT_LOOP
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
#else
uint s_lightIdx = v_lightIdx;
#endif
if (s_lightIdx == -1)
break;

lightData = FetchLight(lightStart, min(++i, last));
}
LightData s_lightData = FetchLight(s_lightIdx);

while (i <= last) // GPULIGHTTYPE_RECTANGLE
// If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
// end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
if (s_lightIdx >= v_lightIdx)
{
lightData.lightType = GPULIGHTTYPE_RECTANGLE; // Enforce constant propagation

if (IsMatchingLightLayer(lightData.lightLayers, builtinData.renderingLayers))
v_lightListOffset++;
if (IsMatchingLightLayer(s_lightData.lightLayers, builtinData.renderingLayers))
{
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, lightData, bsdfData, builtinData);
DirectLighting lighting = EvaluateBSDF_Area(context, V, posInput, preLightData, s_lightData, bsdfData, builtinData);
AccumulateDirectLighting(lighting, aggregateLighting);
}

lightData = FetchLight(lightStart, min(++i, last));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,24 @@ internal ProfilingSampler profilingSampler
/// </summary>
public TargetBuffer targetDepthBuffer;

// The actual depth buffer has to follow some constraints, and thus may not be the same result as the target
// depth buffer that the user has requested. Apply these constraints and return a result.
internal TargetBuffer getConstrainedDepthBuffer()
{
TargetBuffer depth = targetDepthBuffer;
if (depth == TargetBuffer.Camera &&
HDRenderPipeline.currentAsset.currentPlatformRenderPipelineSettings.dynamicResolutionSettings.enabled &&
currentHDCamera.allowDynamicResolution &&
injectionPoint == CustomPassInjectionPoint.AfterPostProcess)
{
// This custom pass is injected after postprocessing, and Dynamic Resolution Scaling is enabled, which
// means an upscaler is active. In this case, the camera color buffer is the full display resolution,
// but the camera depth buffer is a lower, pre-upscale resolution. So we cannot do depth testing here.
depth = TargetBuffer.None;
}
return depth;
}

/// <summary>
/// What clear to apply when the color and depth buffer are bound
/// </summary>
Expand Down Expand Up @@ -272,7 +290,7 @@ virtual internal void ExecuteInternal(RenderGraph renderGraph, HDCamera hdCamera
customPass.isExecuting = false;

// Set back the camera color buffer if we were using a custom buffer as target
if (customPass.targetDepthBuffer != TargetBuffer.Camera)
if (customPass.getConstrainedDepthBuffer() != TargetBuffer.Camera)
CoreUtils.SetRenderTarget(ctx.cmd, outputColorBuffer);
});
}
Expand Down Expand Up @@ -309,16 +327,17 @@ bool IsMSAAEnabled(HDCamera hdCamera)
// This function must be only called from the ExecuteInternal method (requires current render target and current RT manager)
void SetCustomPassTarget(CommandBuffer cmd)
{
TargetBuffer depth = getConstrainedDepthBuffer();
// In case all the buffer are set to none, we can't bind anything
if (targetColorBuffer == TargetBuffer.None && targetDepthBuffer == TargetBuffer.None)
if (targetColorBuffer == TargetBuffer.None && depth == TargetBuffer.None)
return;

RTHandle colorBuffer = (targetColorBuffer == TargetBuffer.Custom) ? currentRenderTarget.customColorBuffer.Value : currentRenderTarget.colorBufferRG;
RTHandle depthBuffer = (targetDepthBuffer == TargetBuffer.Custom) ? currentRenderTarget.customDepthBuffer.Value : currentRenderTarget.depthBufferRG;
RTHandle depthBuffer = (depth == TargetBuffer.Custom) ? currentRenderTarget.customDepthBuffer.Value : currentRenderTarget.depthBufferRG;

if (targetColorBuffer == TargetBuffer.None && targetDepthBuffer != TargetBuffer.None)
if (targetColorBuffer == TargetBuffer.None && depth != TargetBuffer.None)
CoreUtils.SetRenderTarget(cmd, depthBuffer, clearFlags);
else if (targetColorBuffer != TargetBuffer.None && targetDepthBuffer == TargetBuffer.None)
else if (targetColorBuffer != TargetBuffer.None && depth == TargetBuffer.None)
CoreUtils.SetRenderTarget(cmd, colorBuffer, clearFlags);
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ private void ViewBatch(int index)

foreach (var obj in batch1.Lights)
{
if(obj != null)
if (obj != null)
lightBubble1.Add(MakePill(obj));
}

Expand Down Expand Up @@ -241,7 +241,7 @@ private void CompareBatch(int index1, int index2)
lightBubble1.Clear();
foreach (var obj in lightSet1)
{
if(obj != null)
if (obj != null)
lightBubble1.Add(MakePill(obj));
}

Expand All @@ -255,7 +255,7 @@ private void CompareBatch(int index1, int index2)
lightBubble2.Clear();
foreach (var obj in lightSet2)
{
if(obj != null)
if (obj != null)
lightBubble2.Add(MakePill(obj));
}

Expand Down Expand Up @@ -391,7 +391,7 @@ private void OnSelectionChanged()
var firstIndex = batchListView.selectedIndices.First();
var secondIndex = batchListView.selectedIndices.Last();

if(secondIndex > firstIndex + 1 || secondIndex < firstIndex - 1)
if (secondIndex > firstIndex + 1 || secondIndex < firstIndex - 1)
{
// Clamp since we do adjacent batch comparisons
secondIndex = Mathf.Clamp(secondIndex, firstIndex - 1, firstIndex + 1);
Expand All @@ -408,7 +408,7 @@ private void OnSelectionChanged()

default:
// Account for multiple select either with shift or ctrl keys
if(batchListView.selectedIndices.Count() > 2)
if (batchListView.selectedIndices.Count() > 2)
{
if (selectedIndices.Count == 1)
{
Expand Down Expand Up @@ -466,8 +466,12 @@ private bool IsDirty()
isDirty |= Light2DManager.GetCachedSortingLayer().Count() != batchList.Sum(x => x.LayerNames.Count());
isDirty |= cachedSceneHandle != SceneManager.GetActiveScene().handle;
isDirty |= cachedCamPos != Camera.main?.transform.position;
isDirty |= totalLightCount != lightCullResult.visibleLights.Count();
isDirty |= totalShadowCount != lightCullResult.visibleShadows.Count();

if (lightCullResult.IsGameView())
{
isDirty |= totalLightCount != lightCullResult.visibleLights.Count();
isDirty |= totalShadowCount != lightCullResult.visibleShadows.Count();
}

return isDirty;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ internal static void Place(GameObject go, GameObject parent)

static Light2D CreateLight(MenuCommand menuCommand, Light2D.LightType type, Vector3[] shapePath = null)
{
GameObject go = ObjectFactory.CreateGameObject("Light 2D", typeof(Light2D));
var lightName = type != Light2D.LightType.Point ? type.ToString() : "Spot";
GameObject go = ObjectFactory.CreateGameObject(lightName + " Light 2D", typeof(Light2D));
Light2D light2D = go.GetComponent<Light2D>();
light2D.lightType = type;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ Shader "Hidden/Universal Render Pipeline/ScreenSpaceShadows"
{
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

#if UNITY_REVERSED_Z
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, input.texcoord.xy).r;
#else
float deviceDepth = SAMPLE_TEXTURE2D_X(_CameraDepthTexture, sampler_PointClamp, input.texcoord.xy).r;
float deviceDepth = LoadSceneDepth(input.positionCS.xy);
#if !UNITY_REVERSED_Z
deviceDepth = deviceDepth * 2.0 - 1.0;
#endif

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace UnityEditor.ShaderGraph
[Title("UV", "Parallax Occlusion Mapping")]
[FormerName("UnityEditor.Experimental.Rendering.HDPipeline.ParallaxOcclusionMappingNode")]
[FormerName("UnityEditor.Rendering.HighDefinition.ParallaxOcclusionMappingNode")]
class ParallaxOcclusionMappingNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireViewDirection, IMayRequireMeshUV
class ParallaxOcclusionMappingNode : AbstractMaterialNode, IGeneratesBodyCode, IGeneratesFunction, IMayRequireViewDirection, IMayRequireMeshUV, IMayRequireTransform
{
public ParallaxOcclusionMappingNode()
{
Expand Down Expand Up @@ -220,6 +220,8 @@ public void GenerateNodeCode(ShaderStringBuilder sb, GenerationMode generationMo
");
}

public NeededTransform[] RequiresTransform(ShaderStageCapability stageCapability = ShaderStageCapability.All) => new[] { NeededTransform.WorldToObject };

public NeededCoordinateSpace RequiresViewDirection(ShaderStageCapability stageCapability = ShaderStageCapability.All)
{
return NeededCoordinateSpace.Tangent;
Expand Down
Loading