Skip to content

Commit 8f70e1c

Browse files
markg-unityEvergreen
authored andcommitted
DOCG-1019 Add documentation for URP shader library and methods
Adds documentation for some of the helper methods in the URP shader library (and some methods from Core SRP shader library files that URP includes) To avoid this documentation task getting too large, I've focused on methods from: - Core.hlsl - Lighting.hlsl - Shadows.hlsl - ShaderVariablesFunction.hlsl - SpaceTransforms.hlsl (from SRP Core) I've aimed to cover methods/needs that are mentioned in our existing BiRP basic shaders documentation, so that users no longer accidentally find and use BiRP methods that don't work in URP. Preview site: https://docs-internal-preview.prd.it.unity3d.com/markg/urp-shader-methods/manual/use-built-in-shader-methods.html (needs VPN) Jira ticket: https://jira.unity3d.com/browse/DOCG-1019
1 parent 948a433 commit 8f70e1c

11 files changed

+559
-1
lines changed

Packages/com.unity.render-pipelines.core/Documentation~/TableOfContents.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@
1919
* [Add custom graphics settings](add-custom-graphics-settings.md)
2020
* [Get custom graphics settings](get-custom-graphics-settings.md)
2121
* [Include or excude a setting in your build](choose-whether-unity-includes-a-graphics-setting-in-your-build.md)
22-
* [Synchronizing shader code and C#](generating-shader-includes.md)
22+
* [Shaders](shaders.md)
23+
* [Use shader methods from the SRP Core shader library](built-in-shader-methods.md)
24+
* [Synchronizing shader code and C#](generating-shader-includes.md)
2325
* [Look Dev](Look-Dev.md)
2426
* [Environment Library](Look-Dev-Environment-Library.md)
2527
* [Rendering Debugger](Rendering-Debugger.md)
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Use shader methods from the SRP Core shader library
2+
3+
SRP Core has a library of High-Level Shader Language (HLSL) shader files that contain helper methods. You can import these files into your custom shader files and use the helper methods.
4+
5+
To use the following methods, add `#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"` inside the `HLSLPROGRAM` in your shader file.
6+
7+
### Get matrices
8+
9+
| **Method** | **Syntax** | **Description** |
10+
|-|-|-|
11+
| `CreateTangentToWorld` | `real3x3 CreateTangentToWorld(real3 normal, real3 tangent, real flipSign)` | Returns the matrix that converts tangents to world space. |
12+
| `GetObjectToWorldMatrix()` | `float4x4 GetObjectToWorldMatrix()` | Returns the matrix that converts positions in object space to world space. |
13+
| `GetViewToHClipMatrix()` | `float4x4 GetViewToHClipMatrix()` | Returns the matrix that converts positions in view space to clip space. |
14+
| `GetViewToWorldMatrix()` | `float4x4 GetViewToWorldMatrix()` | Returns the matrix that converts positions in view space to world space. |
15+
| `GetWorldToHClipMatrix()` | `float4x4 GetWorldToHClipMatrix()` | Returns the matrix that converts positions in world space to clip space. |
16+
| `GetWorldToObjectMatrix()` | `float4x4 GetWorldToObjectMatrix()` | Returns the matrix that converts positions in world space to object space. |
17+
| `GetWorldToViewMatrix()` | `float4x4 GetWorldToViewMatrix()` | Returns the matrix that converts positions in world space to view space. |
18+
19+
### Transform positions
20+
21+
| **Method** | **Syntax** | **Description** |
22+
|-|-|-|
23+
| `TransformObjectToHClip` | `float4 TransformObjectToHClip(float3 positionInObjectSpace)` | Converts a position in object space to clip space. |
24+
| `TransformObjectToWorld` | `float3 TransformObjectToWorld(float3 positionInObjectSpace)` | Converts a position in object space to world space. |
25+
| `TransformViewToWorld` | `float3 TransformViewToWorld(float3 positionInViewSpace)` | Converts a position in view space to world space. |
26+
| `TransformWorldToHClip` | `float4 TransformWorldToHClip(float3 positionInWorldSpace)` | Converts a position in world space to clip space. |
27+
| `TransformWorldToObject` | `float3 TransformWorldToObject(float3 positionInWorldSpace)` | Converts a position in world space to object space. |
28+
| `TransformWorldToView` | `float3 TransformWorldToView(float3 positionInWorldSpace)` | Converts a position in world space to view space. |
29+
| `TransformWViewToHClip` | `float4 TransformWViewToHClip(float3 positionInViewSpace)` | Converts a position in view space to clip space. |
30+
31+
### Transform directions
32+
33+
| **Method** | **Syntax** | **Description** |
34+
|-|-|-|
35+
| `TransformObjectToTangent` | `real3 TransformObjectToTangent(real3 directionInObjectSpace, real3x3 tangentToWorldMatrix)` | Converts a direction in object space to tangent space, using a tangent-to-world matrix. |
36+
| `TransformObjectToWorldDir` | `float3 TransformObjectToWorldDir(float3 directionInObjectSpace, bool normalize = true)` | Converts a direction in object space to world space. |
37+
| `TransformTangentToObject` | `real3 TransformTangentToObject(real3 dirTS, real3x3 tangentToWorldMatrix)` | Converts a direction in tangent space to object space, using a tangent-to-world matrix. |
38+
| `TransformTangentToWorldDir` | `real3 TransformTangentToWorldDir(real3 directionInWorldSpace, real3x3 tangentToWorldMatrix, bool normalize = false)` | Converts a direction in tangent space to world space, using a tangent-to-world matrix. |
39+
| `TransformViewToWorldDir` | `real3 TransformViewToWorldDir(real3 directionInViewSpace, bool normalize = false)` | Converts a direction in view space to world space. |
40+
| `TransformWorldToHClipDir` | `real3 TransformWorldToHClipDir(real3 directionInWorldSpace, bool normalize = false)` | Converts a direction in world space to clip space. |
41+
| `TransformWorldToObjectDir` | `float3 TransformWorldToObjectDir(float3 directionInWorldSpace, bool normalize = true)` | Converts a direction in world space to object space. |
42+
| `TransformWorldToTangentDir` | `real3 TransformWorldToTangentDir(real3 directionInWorldSpace, real3x3 tangentToWorldMatrix, bool normalize = false)` | Converts a direction in world space to tangent space, using a tangent-to-world matrix. |
43+
| `TransformWorldToViewDir` | `real3 TransformWorldToViewDir(real3 directionInWorldSpace, bool normalize = false)` | Converts a direction in world space to view space. |
44+
45+
### Transform surface normals
46+
47+
| **Method** | **Syntax** | **Description** |
48+
|-|-|-|
49+
| `TransformObjectToWorldNormal` | `float3 TransformObjectToWorldNormal(float3 normalInObjctSpace, bool normalize = true)` | Converts a normal in object space to world space. |
50+
| `TransformTangentToWorld` | `float3 TransformTangentToWorld(float3 normalInTangentSpace, real3x3 tangentToWorldMatrix, bool normalize = false)` | Converts a normal in tangent space to world space, using a tangent-to-world matrix. |
51+
| `TransformViewToWorldNormal` | `real3 TransformViewToWorldNormal(real3 normalInViewSpace, bool normalize = false)` | Converts a normal in view space to world space. |
52+
| `TransformWorldToObjectNormal` | `float3 TransformWorldToObjectNormal(float3 normalInWorldSpace, bool normalize = true)` | Converts a normal in world space to object space. |
53+
| `TransformWorldToTangent` | `float3 TransformWorldToTangent(float3 normalInWorldSpace, real3x3 tangentToWorldMatrix, bool normalize = true)` | Converts a normal in world space to tangent space using a tangent-to-world matrix. |
54+
| `TransformWorldToViewNormal` | `real3 TransformWorldToViewNormal(real3 normalInWorldSpace, bool normalize = false)` | Converts a normal in world space to view space. |
55+
56+
## Additional resources
57+
58+
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
59+
60+
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Shaders
2+
3+
Work with shader code in the Scriptable Render Pipeline (SRP).
4+
5+
|**Page**|**Description**|
6+
|-|-|
7+
|[Use shader methods from the SRP Core shader library](built-in-shader-methods.md)|SRP Core has a library of High-Level Shader Language (HLSL) shader files that contain helper methods. You can import these files into your custom shader files and use the helper methods.|
8+
|[Synchronizing shader code and C#](generating-shader-includes.md)|Generate HLSL code based on C# structs to synchronize data and constants between shaders and C#.|
9+
10+
## Additional resources
11+
12+
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)

Packages/com.unity.render-pipelines.universal/Documentation~/TableOfContents.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,12 @@
154154
* [Drawing a texture](writing-shaders-urp-unlit-texture.md)
155155
* [Visualizing normal vectors](writing-shaders-urp-unlit-normals.md)
156156
* [Reconstruct the world space positions](writing-shaders-urp-reconstruct-world-position.md)
157+
* [Shader methods in URP](use-built-in-shader-methods.md)
158+
* [Import a file from the URP shader library](use-built-in-shader-methods-import.md)
159+
* [Transform positions in a custom URP shader](use-built-in-shader-methods-transformations.md)
160+
* [Use the camera in a custom URP shader](use-built-in-shader-methods-camera.md)
161+
* [Use lighting in a custom URP shader](use-built-in-shader-methods-lighting.md)
162+
* [Use shadows in a custom URP shader](use-built-in-shader-methods-shadows.md)
157163
* [URP ShaderLab Pass tags](urp-shaders/urp-shaderlab-pass-tags.md)
158164
* [Custom rendering and post-processing](customizing-urp.md)
159165
* [Custom render pass workflow in URP](renderer-features/custom-rendering-pass-workflow-in-urp.md)
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Use the camera in a custom URP shader
2+
3+
To use the camera in a custom Universal Render Pipeline (URP) shader, follow these steps:
4+
5+
1. Add `#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"` inside the `HLSLPROGRAM` in your shader file. The `Core.hlsl` file imports the `ShaderVariablesFunction.hlsl` file.
6+
2. Use one of the following methods from the `ShaderVariablesFunction.hlsl` file.
7+
8+
| **Method** | **Syntax** | **Description** |
9+
|-|-|-|
10+
| `GetCameraPositionWS` | `float3 GetCameraPositionWS()` | Returns the world space position of the camera. |
11+
| `GetScaledScreenParams` | `float4 GetScaledScreenParams()` | Returns the width and height of the screen in pixels. |
12+
| `GetViewForwardDir` | `float3 GetViewForwardDir()` | Returns the forward direction of the view in world space. |
13+
| `IsPerspectiveProjection` | `bool IsPerspectiveProjection()` | Returns `true` if the camera projection is set to perspective. |
14+
| `LinearDepthToEyeDepth` | `half LinearDepthToEyeDepth(half linearDepth)` | Converts a linear depth buffer value to view depth. Refer to [Cameras and depth textures](https://docs.unity3d.com/Manual/SL-CameraDepthTexture.html) for more information. |
15+
| `TransformScreenUV` | `void TransformScreenUV(inout float2 screenSpaceUV)` | Flips the y coordinate of the screen space position, if Unity uses an upside-down coordinate space. You can also input both a `uv`, and the screen height as a `float`, so the method outputs the position scaled to the screen size in pixels. |
16+
17+
## Example
18+
19+
The following URP shader draws object surfaces with colors that represent the direction from the surface to the camera.
20+
21+
```hlsl
22+
Shader "Custom/DirectionToCamera"
23+
{
24+
SubShader
25+
{
26+
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
27+
28+
Pass
29+
{
30+
HLSLPROGRAM
31+
32+
#pragma vertex vert
33+
#pragma fragment frag
34+
35+
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
36+
37+
struct Attributes
38+
{
39+
float4 positionOS : POSITION;
40+
float2 uv: TEXCOORD0;
41+
};
42+
43+
struct Varyings
44+
{
45+
float4 positionCS : SV_POSITION;
46+
float2 uv: TEXCOORD0;
47+
float3 viewDirection : TEXCOORD2;
48+
};
49+
50+
Varyings vert(Attributes IN)
51+
{
52+
Varyings OUT;
53+
54+
// Get the positions of the vertex in different coordinate spaces
55+
VertexPositionInputs positions = GetVertexPositionInputs(IN.positionOS);
56+
OUT.positionCS = positions.positionCS;
57+
58+
// Get the direction from the vertex to the camera, in world space
59+
OUT.viewDirection = GetCameraPositionWS() - positions.positionWS.xyz;
60+
61+
return OUT;
62+
}
63+
64+
half4 frag(Varyings IN) : SV_Target
65+
{
66+
// Set the fragment color to the direction vector
67+
return float4(IN.viewDirection, 1);
68+
}
69+
ENDHLSL
70+
}
71+
}
72+
}
73+
```
74+
75+
## Additional resources
76+
77+
- [Cameras in URP](cameras/camera-differences-in-urp.md)
78+
- [Writing custom shaders](writing-custom-shaders-urp.md)
79+
- [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md)
80+
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Import a file from the URP shader library
2+
3+
The High-Level Shader Language (HLSL) shader files for the Universal Render Pipeline (URP) are in the `Packages/com.unity.render-pipelines.universal/ShaderLibrary/` folder in your project.
4+
5+
To import a shader file into a custom shader file, add an `#include` directive inside the `HLSLPROGRAM` in your shader file. For example:
6+
7+
```hlsl
8+
HLSLPROGRAM
9+
...
10+
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
11+
...
12+
ENDHLSL
13+
```
14+
15+
You can then use the helper methods from the file. For example:
16+
17+
```hlsl
18+
float3 cameraPosition = GetCameraPositionWS();
19+
```
20+
21+
Refer to [Shader methods in URP](use-built-in-shader-methods.md) for more information about the different shader files.
22+
23+
You can also import shader files from the core Scriptable Render Pipeline (SRP). Refer to [Shader methods in Scriptable Render Pipeline (SRP) Core](https://docs.unity3d.com/Packages/[email protected]/manual/built-in-shader-methods.html).
24+
25+
## Examples
26+
27+
Refer to [Writing custom shaders](writing-custom-shaders-urp.md) for examples of using variables and helper methods from the files in the URP shader library.
28+
29+
## Additional resources
30+
31+
- [include and include_with_pragmas directives in HLSL](https://docs.unity3d.com/Manual/shader-include-directives.html)
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# Use lighting in a custom URP shader
2+
3+
To use lighting in a custom Universal Render Pipeline (URP) shader, follow these steps:
4+
5+
1. Add `#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"` inside the `HLSLPROGRAM` in your shader file.
6+
2. Use any of the methods from the following sections.
7+
8+
## Get light data
9+
10+
The `Lighting.hlsl` file imports the `RealtimeLights.hlsl` file, which contains the following methods.
11+
12+
| **Method** | **Syntax** | **Description** |
13+
|-|-|-|
14+
| `GetMainLight` | `Light GetMainLight()` | Returns the main light in the scene. |
15+
| `GetAdditionalLight` | `Light GetAdditionalLight(uint lightIndex, float3 positionInWorldSpace)` | Returns the `lightIndex` additional light that affects `positionWS`. For example, if `lightIndex` is `0`, this method returns the first additional light. |
16+
| `GetAdditionalLightsCount` | `int GetAdditionalLightsCount()` | Returns the number of additional lights. |
17+
18+
Refer to [Use shadows in a custom URP shader](use-built-in-shader-methods-shadows.md) for information on versions of these methods you can use to calculate shadows.
19+
20+
### Calculate lighting for a surface normal
21+
22+
| **Method** | **Syntax** | **Description** |
23+
|-|-|-|
24+
| `LightingLambert` | `half3 LightingLambert(half3 lightColor, half3 lightDirection, half3 surfaceNormal)` | Returns the diffuse lighting for the surface normal, calculated using the Lambert model. |
25+
| `LightingSpecular` | `half3 LightingSpecular(half3 lightColor, half3 lightDirection, half3 surfaceNormal, half3 viewDirection, half4 specularAmount, half smoothnessAmount)` | Returns the specular lighting for the surface normal, using [simple shading](shading-model.md#simple-shading). |
26+
27+
## Calculate ambient occlusion
28+
29+
The `Lighting.hlsl` file imports the `AmbientOcclusion.hlsl` file, which contains the following methods.
30+
31+
| **Method** | **Syntax** | **Description** |
32+
|-|-|-|
33+
| `SampleAmbientOcclusion` | `half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV)` | Returns the ambient occlusion value at the position in screen space, where 0 means occluded and 1 means unoccluded. |
34+
| `GetScreenSpaceAmbientOcclusion` | `AmbientOcclusionFactor GetScreenSpaceAmbientOcclusion(float2 normalizedScreenSpaceUV)` | Returns the indirect and direct ambient occlusion values at the position in screen space, where 0 means occluded and 1 means unoccluded. |
35+
36+
Refer to [Ambient occlusion](post-processing-ssao.md) for more information.
37+
38+
## Structs
39+
40+
### AmbientOcclusionFactor
41+
42+
Use the `GetScreenSpaceAmbientOcclusion` method to return this struct.
43+
44+
| **Field** | **Description** |
45+
|-|-|
46+
| `half indirectAmbientOcclusion` | The amount the object is in shadow from ambient occlusion caused by objects blocking indirect light. |
47+
| `half directAmbientOcclusion` | The amount the object is in shadow from ambient occlusion caused by objects blocking direct light. |
48+
49+
### Light
50+
51+
Use the `GetMainLight` and `GetAdditionalLight` methods to return this struct.
52+
53+
| **Field** | **Description** |
54+
|-|-|
55+
| `half3 direction` | The direction of the light. |
56+
| `half3 color` | The color of the light. |
57+
| `float distanceAttenuation` | The strength of the light, based on its distance from the object. |
58+
| `half shadowAttenuation` | The strength of the light, based on whether the object is in shadow. |
59+
| `uint layerMask` | The layer mask of the light. |
60+
61+
## Example
62+
63+
The following URP shader draws object surfaces with the amount of light they receive from the main directional light.
64+
65+
```hlsl
66+
Shader "Custom/LambertLighting"
67+
{
68+
SubShader
69+
{
70+
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
71+
72+
Pass
73+
{
74+
HLSLPROGRAM
75+
76+
#pragma vertex vert
77+
#pragma fragment frag
78+
79+
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
80+
81+
struct Attributes
82+
{
83+
float4 positionOS : POSITION;
84+
float2 uv: TEXCOORD0;
85+
};
86+
87+
struct Varyings
88+
{
89+
float4 positionCS : SV_POSITION;
90+
float2 uv: TEXCOORD0;
91+
half3 lightAmount : TEXCOORD2;
92+
};
93+
94+
Varyings vert(Attributes IN)
95+
{
96+
Varyings OUT;
97+
98+
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
99+
100+
// Get the VertexNormalInputs of the vertex, which contains the normal in world space
101+
VertexNormalInputs positions = GetVertexNormalInputs(IN.positionOS);
102+
103+
// Get the properties of the main light
104+
Light light = GetMainLight();
105+
106+
// Calculate the amount of light the vertex receives
107+
OUT.lightAmount = LightingLambert(light.color, light.direction, positions.normalWS.xyz);
108+
109+
return OUT;
110+
}
111+
112+
half4 frag(Varyings IN) : SV_Target
113+
{
114+
// Set the fragment color to the interpolated amount of light
115+
return float4(IN.lightAmount, 1);
116+
}
117+
ENDHLSL
118+
}
119+
}
120+
}
121+
```
122+
123+
## Additional resources
124+
125+
- [Writing custom shaders](writing-custom-shaders-urp.md)
126+
- [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md)
127+
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
128+
- [Diffuse](https://docs.unity3d.com/Manual/shader-NormalDiffuse.html)
129+
- [Specular](https://docs.unity3d.com/Manual/shader-NormalSpecular.html)
130+
131+
132+

0 commit comments

Comments
 (0)