包含此页的版本:
不含此页的版本:
团结着色器在 GPU 上运行的程序。更多信息
请参阅术语表在此示例中,重建像素计算机图像中的最小单位。像素大小取决于您的屏幕分辨率。像素光照是在每个屏幕像素下计算的。更多信息
请参阅术语表使用深度纹理和屏幕空间UV坐标。着色器在meshUnity 的主要图形原语。网格体构成了 3D 世界的很大一部分。Unity 支持三角或四边形多边形网格。Nurbs、Nurms、Subdiv 曲面必须转换为多边形。更多信息
请参阅术语表以可视化位置。
下图显示了最终结果:
此页面包含以下部分:
创建示例场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表要按照本节中的步骤作:
将 URP 安装到现有 Unity 项目中,或使用通用项目模板创建新项目。
在示例场景中,创建一个平面游戏对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息
请参阅术语表并放置它,使其遮挡一些游戏对象。
创建一个新材质并将其分配给平面。
创建一个新的着色器并将其分配给材质。从 URP unlit 基本着色器页面复制并粘贴 Unity 着色器源代码。
选择 URP 资产。
在URP资产的 常规(General) 分段中,启用Depth Texture.
打开您在步骤 4 中创建的着色器。
本部分假定你从URP unlit basic shader页面复制了源代码。
对ShaderLabUnity 用于定义 Shader 对象结构的语言。更多信息
请参阅术语表法典:
在HLSLPROGRAM块中,为深度纹理着色器标头添加 include 声明。例如,将其放在Core.hlsl.
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// The DeclareDepthTexture.hlsl file contains utilities for sampling the Camera
// depth texture.
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
这DeclareDepthTexture.hlsl文件包含用于对相机在场景中创建特定视点图像的组件。输出要么绘制到屏幕上,要么作为纹理捕获。更多信息
请参阅术语表深度纹理。此示例使用SampleSceneDepth函数,用于对像素的 Z 坐标进行采样。
在片段着色器定义中,将Varyings IN作为输入。
half4 frag(Varyings IN) : SV_Target
在此示例中,片段着色器使用positionHCS属性Varyingsstruct 来获取像素的位置。
在片段着色器中,要计算用于采样的 UV 坐标深度缓冲区 保存图像中每个像素的 z 值深度的内存存储,其中 z 值是投影平面中每个呈现像素的深度。更多信息
请参阅术语表,将像素位置除以渲染目标分辨率_ScaledScreenParams.该物业_ScaledScreenParams.xy考虑渲染目标的任何缩放,例如动态分辨率(Dynamic Resolution)摄像机设置,允许你动态缩放单个渲染目标,以减少GPU上的工作负载。更多信息
请参阅术语表.
float2 UV = IN.positionHCS.xy / _ScaledScreenParams.xy;
在片段着色器中,使用SampleSceneDepth函数对深度缓冲区进行采样。
#if UNITY_REVERSED_Z
real depth = SampleSceneDepth(UV);
#else
// Adjust z to match NDC for OpenGL
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
#endif
这SampleSceneDepth函数来自DeclareDepthTexture.hlsl文件。它返回范围内的 Z 值[0, 1].
对于重建函数 (ComputeWorldSpacePosition) 才能工作,深度值必须位于规范化设备坐标 (NDC) 空间中。在 D3D 中,Z 在范围内[0,1],在 OpenGL 中,Z 在范围内[-1, 1].
此示例使用UNITY_REVERSED_Z常量来确定平台并调整 Z 值范围。查看此示例中的步骤 6 以获取更多说明。
这UNITY_NEAR_CLIP_VALUEvariable 是一个独立于平台的 near剪切平面限制摄像机从当前位置可以看到的距离或距离的平面。摄像机的可视范围介于远裁剪平面和近裁剪平面之间。查看远剪切平面和近剪切平面。更多信息
请参阅术语表值。
有关更多信息,请参阅特定于平台的渲染差异。
从像素的 UV 和 Z 坐标重建世界空间位置。
float3 worldPos = ComputeWorldSpacePosition(UV, depth, UNITY_MATRIX_I_VP);
ComputeWorldSpacePosition是一个实用函数,它根据 UV 和深度 (Z) 值计算世界空间位置。此函数在Common.hlslSRP Core 包的文件。
UNITY_MATRIX_I_VP是一个逆视图投影矩阵,用于将点从裁剪空间转换为世界空间。
要可视化像素的世界空间位置,请创建检查板效果。
uint scale = 10;
uint3 worldIntPos = uint3(abs(worldPos.xyz * scale));
bool white = (worldIntPos.x & 1) ^ (worldIntPos.y & 1) ^ (worldIntPos.z & 1);
half4 color = white ? half4(1,1,1,1) : half4(0,0,0,1);
这scale是棋盘图案大小的反比例。
这abs函数将图案镜像到负坐标侧。
这uint3声明worldIntPos变量将坐标位置捕捉到整数。
这AND运算符<integer value> & 1检查值是偶数 (0) 还是奇数 (1)。该表达式允许代码将表面划分为正方形。
这XOR运算符<integer value> ^ <integer value>翻转方形颜色。
深度缓冲区可能没有用于未呈现几何图形的区域的有效值。以下代码在此类区域中绘制黑色。
#if UNITY_REVERSED_Z
if(depth < 0.0001)
return half4(0,0,0,1);
#else
if(depth > 0.9999)
return half4(0,0,0,1);
#endif
不同的平台使用不同的 Z 值远剪切平面相机的最大绘制距离。超出此值定义的平面的几何体不会被渲染。该平面垂直于摄像机的前向 (Z) 方向。
请参阅术语表(0 == far,或 1 == far)。这UNITY_REVERSED_Zconstant 允许代码正确处理所有平台。
保存着色器代码,示例就准备好了。
下图显示了最终结果:
以下是此示例的完整 ShaderLab 代码。
// This Unity shader reconstructs the world space positions for pixels using a depth
// texture and screen space UV coordinates. The shader draws a checkerboard pattern
// on a mesh to visualize the positions.
Shader "Example/URPReconstructWorldPos"
{
Properties
{ }
// The SubShader block containing the Shader code.
SubShader
{
// SubShader Tags define when and under which conditions a SubShader block or
// a pass is executed.
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
// This line defines the name of the vertex shader.
#pragma vertex vert
// This line defines the name of the fragment shader.
#pragma fragment frag
// The Core.hlsl file contains definitions of frequently used HLSL
// macros and functions, and also contains #include references to other
// HLSL files (for example, Common.hlsl, SpaceTransforms.hlsl, etc.).
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
// The DeclareDepthTexture.hlsl file contains utilities for sampling the
// Camera depth texture.
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareDepthTexture.hlsl"
// This example uses the Attributes structure as an input structure in
// the vertex shader.
struct Attributes
{
// The positionOS variable contains the vertex positions in object
// space.
float4 positionOS : POSITION;
};
struct Varyings
{
// The positions in this struct must have the SV_POSITION semantic.
float4 positionHCS : SV_POSITION;
};
// The vertex shader definition with properties defined in the Varyings
// structure. The type of the vert function must match the type (struct)
// that it returns.
Varyings vert(Attributes IN)
{
// Declaring the output object (OUT) with the Varyings struct.
Varyings OUT;
// The TransformObjectToHClip function transforms vertex positions
// from object space to homogenous clip space.
OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
// Returning the output.
return OUT;
}
// The fragment shader definition.
// The Varyings input structure contains interpolated values from the
// vertex shader. The fragment shader uses the `positionHCS` property
// from the `Varyings` struct to get locations of pixels.
half4 frag(Varyings IN) : SV_Target
{
// To calculate the UV coordinates for sampling the depth buffer,
// divide the pixel location by the render target resolution
// _ScaledScreenParams.
float2 UV = IN.positionHCS.xy / _ScaledScreenParams.xy;
// Sample the depth from the Camera depth texture.
#if UNITY_REVERSED_Z
real depth = SampleSceneDepth(UV);
#else
// Adjust Z to match NDC for OpenGL ([-1, 1])
real depth = lerp(UNITY_NEAR_CLIP_VALUE, 1, SampleSceneDepth(UV));
#endif
// Reconstruct the world space positions.
float3 worldPos = ComputeWorldSpacePosition(UV, depth, UNITY_MATRIX_I_VP);
// The following part creates the checkerboard effect.
// Scale is the inverse size of the squares.
uint scale = 10;
// Scale, mirror and snap the coordinates.
uint3 worldIntPos = uint3(abs(worldPos.xyz * scale));
// Divide the surface into squares. Calculate the color ID value.
bool white = ((worldIntPos.x) & 1) ^ (worldIntPos.y & 1) ^ (worldIntPos.z & 1);
// Color the square based on the ID value (black or white).
half4 color = white ? half4(1,1,1,1) : half4(0,0,0,1);
// Set the color to black in the proximity to the far clipping
// plane.
#if UNITY_REVERSED_Z
// Case for platforms with REVERSED_Z, such as D3D.
if(depth < 0.0001)
return half4(0,0,0,1);
#else
// Case for platforms without REVERSED_Z, such as OpenGL.
if(depth > 0.9999)
return half4(0,0,0,1);
#endif
return color;
}
ENDHLSL
}
}
}