Skip to content

Commit

Permalink
Merge pull request #8068 from Unity-Technologies/internal/2021.3/staging
Browse files Browse the repository at this point in the history
Internal/2021.3/staging
  • Loading branch information
UnityAljosha authored Apr 29, 2024
2 parents 58bbc1c + 62ea26a commit 02a3c85
Show file tree
Hide file tree
Showing 14 changed files with 569 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@
* [Using the RTHandle system](rthandle-system-using.md)
* [Custom Material Inspector](custom-material-inspector.md)
* [Synchronizing shader code and C#](generating-shader-includes.md)
* [Shaders](shaders.md)
* [Use shader methods from the SRP Core shader library](built-in-shader-methods.md)
* [Synchronizing shader code and C#](generating-shader-includes.md)
* [Look Dev](Look-Dev.md)
* [Environment Library](Look-Dev-Environment-Library.md)
* [Light Anchor](view-lighting-tool.md)
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Use shader methods from the SRP Core shader library

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.

To use the following methods, add `#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/SpaceTransforms.hlsl"` inside the `HLSLPROGRAM` in your shader file.

### Get matrices

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `CreateTangentToWorld` | `real3x3 CreateTangentToWorld(real3 normal, real3 tangent, real flipSign)` | Returns the matrix that converts tangents to world space. |
| `GetObjectToWorldMatrix()` | `float4x4 GetObjectToWorldMatrix()` | Returns the matrix that converts positions in object space to world space. |
| `GetViewToHClipMatrix()` | `float4x4 GetViewToHClipMatrix()` | Returns the matrix that converts positions in view space to clip space. |
| `GetViewToWorldMatrix()` | `float4x4 GetViewToWorldMatrix()` | Returns the matrix that converts positions in view space to world space. |
| `GetWorldToHClipMatrix()` | `float4x4 GetWorldToHClipMatrix()` | Returns the matrix that converts positions in world space to clip space. |
| `GetWorldToObjectMatrix()` | `float4x4 GetWorldToObjectMatrix()` | Returns the matrix that converts positions in world space to object space. |
| `GetWorldToViewMatrix()` | `float4x4 GetWorldToViewMatrix()` | Returns the matrix that converts positions in world space to view space. |

### Transform positions

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `TransformObjectToHClip` | `float4 TransformObjectToHClip(float3 positionInObjectSpace)` | Converts a position in object space to clip space. |
| `TransformObjectToWorld` | `float3 TransformObjectToWorld(float3 positionInObjectSpace)` | Converts a position in object space to world space. |
| `TransformWorldToHClip` | `float4 TransformWorldToHClip(float3 positionInWorldSpace)` | Converts a position in world space to clip space. |
| `TransformWorldToObject` | `float3 TransformWorldToObject(float3 positionInWorldSpace)` | Converts a position in world space to object space. |
| `TransformWorldToView` | `float3 TransformWorldToView(float3 positionInWorldSpace)` | Converts a position in world space to view space. |
| `TransformWViewToHClip` | `float4 TransformWViewToHClip(float3 positionInViewSpace)` | Converts a position in view space to clip space. |

### Transform directions

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `TransformObjectToTangent` | `real3 TransformObjectToTangent(real3 directionInObjectSpace, real3x3 tangentToWorldMatrix)` | Converts a direction in object space to tangent space, using a tangent-to-world matrix. |
| `TransformObjectToWorldDir` | `float3 TransformObjectToWorldDir(float3 directionInObjectSpace, bool normalize = true)` | Converts a direction in object space to world space. |
| `TransformTangentToObject` | `real3 TransformTangentToObject(real3 dirTS, real3x3 tangentToWorldMatrix)` | Converts a direction in tangent space to object space, using a tangent-to-world matrix. |
| `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. |
| `TransformViewToWorldDir` | `real3 TransformViewToWorldDir(real3 directionInViewSpace, bool normalize = false)` | Converts a direction in view space to world space. |
| `TransformWorldToHClipDir` | `real3 TransformWorldToHClipDir(real3 directionInWorldSpace, bool normalize = false)` | Converts a direction in world space to clip space. |
| `TransformWorldToObjectDir` | `float3 TransformWorldToObjectDir(float3 directionInWorldSpace, bool normalize = true)` | Converts a direction in world space to object space. |
| `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. |
| `TransformWorldToViewDir` | `real3 TransformWorldToViewDir(real3 directionInWorldSpace, bool normalize = false)` | Converts a direction in world space to view space. |

### Transform surface normals

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `TransformObjectToWorldNormal` | `float3 TransformObjectToWorldNormal(float3 normalInObjctSpace, bool normalize = true)` | Converts a normal in object space to world space. |
| `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. |
| `TransformViewToWorldNormal` | `real3 TransformViewToWorldNormal(real3 normalInViewSpace, bool normalize = false)` | Converts a normal in view space to world space. |
| `TransformWorldToObjectNormal` | `float3 TransformWorldToObjectNormal(float3 normalInWorldSpace, bool normalize = true)` | Converts a normal in world space to object space. |
| `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. |
| `TransformWorldToViewNormal` | `real3 TransformWorldToViewNormal(real3 normalInWorldSpace, bool normalize = false)` | Converts a normal in world space to view space. |

## Additional resources

- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)


12 changes: 12 additions & 0 deletions Packages/com.unity.render-pipelines.core/Documentation~/shaders.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Shaders

Work with shader code in the Scriptable Render Pipeline (SRP).

|**Page**|**Description**|
|-|-|
|[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.|
|[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#.|

## Additional resources

- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
Original file line number Diff line number Diff line change
Expand Up @@ -567,9 +567,8 @@ float2 Unpack888ToFloat2(float3 x)
// Pack 2 float values from the [0, 1] range, to an 8 bits float from the [0, 1] range
float PackFloat2To8(float2 f)
{
float x_expanded = f.x * 15.0; // f.x encoded over 4 bits, can have 2^4 = 16 distinct values mapped to [0, 1, ..., 15]
float y_expanded = f.y * 15.0; // f.y encoded over 4 bits, can have 2^4 = 16 distinct values mapped to [0, 1, ..., 15]
float x_y_expanded = x_expanded * 16.0 + y_expanded; // f.x encoded over higher bits, f.y encoded over the lower bits - x_y values in range [0, 1, ..., 255]
float2 i = floor(f * 15.0); // f.x & f.y encoded over 4 bits, can have 2^4 = 16 distinct values mapped to [0, 1, ..., 15]
float x_y_expanded = i.x * 16.0 + i.y; // f.x encoded over higher bits, f.y encoded over the lower bits - x_y values in range [0, 1, ..., 255]
return x_y_expanded / 255.0;

// above 4 lines equivalent to:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@
* [Drawing a texture](writing-shaders-urp-unlit-texture.md)
* [Visualizing normal vectors](writing-shaders-urp-unlit-normals.md)
* [Reconstruct the world space positions](writing-shaders-urp-reconstruct-world-position.md)
* [Shader methods in URP](use-built-in-shader-methods.md)
* [Import a file from the URP shader library](use-built-in-shader-methods-import.md)
* [Transform positions in a custom URP shader](use-built-in-shader-methods-transformations.md)
* [Use the camera in a custom URP shader](use-built-in-shader-methods-camera.md)
* [Use lighting in a custom URP shader](use-built-in-shader-methods-lighting.md)
* [Use shadows in a custom URP shader](use-built-in-shader-methods-shadows.md)
* [URP ShaderLab Pass tags](urp-shaders/urp-shaderlab-pass-tags.md)
* [Custom rendering and post-processing](customizing-urp.md)
* [Custom render passes](renderer-features/custom-rendering-passes.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Use the camera in a custom URP shader

To use the camera in a custom Universal Render Pipeline (URP) shader, follow these steps:

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.
2. Use one of the following methods from the `ShaderVariablesFunction.hlsl` file.

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `GetCameraPositionWS` | `float3 GetCameraPositionWS()` | Returns the world space position of the camera. |
| `GetScaledScreenParams` | `float4 GetScaledScreenParams()` | Returns the width and height of the screen in pixels. |
| `GetViewForwardDir` | `float3 GetViewForwardDir()` | Returns the forward direction of the view in world space. |
| `IsPerspectiveProjection` | `bool IsPerspectiveProjection()` | Returns `true` if the camera projection is set to perspective. |
| `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. |
| `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. |

## Example

The following URP shader draws object surfaces with colors that represent the direction from the surface to the camera.

```hlsl
Shader "Custom/DirectionToCamera"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv: TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv: TEXCOORD0;
float3 viewDirection : TEXCOORD2;
};
Varyings vert(Attributes IN)
{
Varyings OUT;
// Get the positions of the vertex in different coordinate spaces
VertexPositionInputs positions = GetVertexPositionInputs(IN.positionOS);
OUT.positionCS = positions.positionCS;
// Get the direction from the vertex to the camera, in world space
OUT.viewDirection = GetCameraPositionWS() - positions.positionWS.xyz;
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
// Set the fragment color to the direction vector
return float4(IN.viewDirection, 1);
}
ENDHLSL
}
}
}
```

## Additional resources

- [Cameras in URP](cameras/camera-differences-in-urp.md)
- [Writing custom shaders](writing-custom-shaders-urp.md)
- [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md)
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Import a file from the URP shader library

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.

To import a shader file into a custom shader file, add an `#include` directive inside the `HLSLPROGRAM` in your shader file. For example:

```hlsl
HLSLPROGRAM
...
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
...
ENDHLSL
```

You can then use the helper methods from the file. For example:

```hlsl
float3 cameraPosition = GetCameraPositionWS();
```

Refer to [Shader methods in URP](use-built-in-shader-methods.md) for more information about the different shader files.

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).

## Examples

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.

## Additional resources

- [include and include_with_pragmas directives in HLSL](https://docs.unity3d.com/Manual/shader-include-directives.html)
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Use lighting in a custom URP shader

To use lighting in a custom Universal Render Pipeline (URP) shader, follow these steps:

1. Add `#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"` inside the `HLSLPROGRAM` in your shader file.
2. Use any of the methods from the following sections.

## Get light data

The `Lighting.hlsl` file imports the `RealtimeLights.hlsl` file, which contains the following methods.

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `GetMainLight` | `Light GetMainLight()` | Returns the main light in the scene. |
| `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. |
| `GetAdditionalLightsCount` | `int GetAdditionalLightsCount()` | Returns the number of additional lights. |

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.

### Calculate lighting for a surface normal

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `LightingLambert` | `half3 LightingLambert(half3 lightColor, half3 lightDirection, half3 surfaceNormal)` | Returns the diffuse lighting for the surface normal, calculated using the Lambert model. |
| `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). |

## Calculate ambient occlusion

The `Lighting.hlsl` file imports the `AmbientOcclusion.hlsl` file, which contains the following methods.

| **Method** | **Syntax** | **Description** |
|-|-|-|
| `SampleAmbientOcclusion` | `half SampleAmbientOcclusion(float2 normalizedScreenSpaceUV)` | Returns the ambient occlusion value at the position in screen space, where 0 means occluded and 1 means unoccluded. |
| `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. |

Refer to [Ambient occlusion](post-processing-ssao.md) for more information.

## Structs

### AmbientOcclusionFactor

Use the `GetScreenSpaceAmbientOcclusion` method to return this struct.

| **Field** | **Description** |
|-|-|
| `half indirectAmbientOcclusion` | The amount the object is in shadow from ambient occlusion caused by objects blocking indirect light. |
| `half directAmbientOcclusion` | The amount the object is in shadow from ambient occlusion caused by objects blocking direct light. |

### Light

Use the `GetMainLight` and `GetAdditionalLight` methods to return this struct.

| **Field** | **Description** |
|-|-|
| `half3 direction` | The direction of the light. |
| `half3 color` | The color of the light. |
| `float distanceAttenuation` | The strength of the light, based on its distance from the object. |
| `half shadowAttenuation` | The strength of the light, based on whether the object is in shadow. |
| `uint layerMask` | The layer mask of the light. |

## Example

The following URP shader draws object surfaces with the amount of light they receive from the main directional light.

```hlsl
Shader "Custom/LambertLighting"
{
SubShader
{
Tags { "RenderType" = "Opaque" "RenderPipeline" = "UniversalPipeline" }
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float2 uv: TEXCOORD0;
};
struct Varyings
{
float4 positionCS : SV_POSITION;
float2 uv: TEXCOORD0;
half3 lightAmount : TEXCOORD2;
};
Varyings vert(Attributes IN)
{
Varyings OUT;
OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
// Get the VertexNormalInputs of the vertex, which contains the normal in world space
VertexNormalInputs positions = GetVertexNormalInputs(IN.positionOS);
// Get the properties of the main light
Light light = GetMainLight();
// Calculate the amount of light the vertex receives
OUT.lightAmount = LightingLambert(light.color, light.direction, positions.normalWS.xyz);
return OUT;
}
half4 frag(Varyings IN) : SV_Target
{
// Set the fragment color to the interpolated amount of light
return float4(IN.lightAmount, 1);
}
ENDHLSL
}
}
}
```

## Additional resources

- [Writing custom shaders](writing-custom-shaders-urp.md)
- [Upgrade custom shaders for URP compatibility](urp-shaders/birp-urp-custom-shader-upgrade-guide.md)
- [HLSL in Unity](https://docs.unity3d.com/Manual/SL-ShaderPrograms.html)
- [Diffuse](https://docs.unity3d.com/Manual/shader-NormalDiffuse.html)
- [Specular](https://docs.unity3d.com/Manual/shader-NormalSpecular.html)



Loading

0 comments on commit 02a3c85

Please sign in to comment.