Getting Started
Package Types
Scene Setup
Custom Collision, Layers, and Tags
Key Differences from Standard Unity3D development
Economy
Scripting
Components
Environment Settings Overrides
Render Pipeline Settings Overrides
Guidelines
Supported Features and Limitations
Support
Before
After
Have you experienced shaders looking ugly on mobile and the Meta Quest? If your shader uses _CameraOpaqueTexture or _CameraDepthTexture, they will look broken on mobile and Quest as it's only available on web.
We added global shader keywords _USE_CAMERA_COLOR_TEXTURE
and _USE_CAMERA_DEPTH_TEXTURE
so you can make your shader variants across those platforms.
Click here to download example shaders as reference.
Shader "Examples/CameraTextureExample"
{
Properties
{
_BaseColor ("Base color", Color) = (0.6, 0.6, 0.6, 1)
_BaseMap ("Texture", 2D) = "white" {}
}
SubShader
{
Tags
{
"RenderType" = "Opaque"
"Queue" = "Transparent" // Render Queue must be set to later than "2500" for the camera texture to be visible
"RenderPipeline" = "UniversalPipeline"
}
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
// Global Keywords that Spatial provides
#pragma multi_compile _ _USE_CAMERA_COLOR_TEXTURE
#pragma multi_compile _ _USE_CAMERA_DEPTH_TEXTURE
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
float2 uv : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct Varying
{
float4 positionCS : SV_POSITION;
float2 uv : TEXCOORD0;
#if defined(_USE_CAMERA_COLOR_TEXTURE) || defined(_USE_CAMERA_DEPTH_TEXTURE)
float4 screenPos : TEXCOORD2;
#endif
float fogCoord : TEXCOORD1;
UNITY_VERTEX_OUTPUT_STEREO
};
TEXTURE2D(_BaseMap);
SAMPLER(sampler_BaseMap);
#if defined(_USE_CAMERA_COLOR_TEXTURE)
TEXTURE2D(_CameraOpaqueTexture);
SAMPLER(sampler_CameraOpaqueTexture);
#endif
#if defined(_USE_CAMERA_DEPTH_TEXTURE)
TEXTURE2D(_CameraDepthTexture);
SAMPLER(sampler_CameraDepthTexture);
#endif
CBUFFER_START(UnityPerMaterial)
float4 _BaseMap_ST;
half4 _BaseColor;
CBUFFER_END
Varying vert (Attributes IN)
{
UNITY_SETUP_INSTANCE_ID(IN);
Varying OUT = (Varying)0;
UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
VertexPositionInputs vertexInput = GetVertexPositionInputs(IN.positionOS.xyz);
OUT.positionCS = vertexInput.positionCS;
#if defined(_USE_CAMERA_COLOR_TEXTURE) || defined(_USE_CAMERA_DEPTH_TEXTURE)
OUT.screenPos = vertexInput.positionNDC;
#endif
OUT.uv = TRANSFORM_TEX(IN.uv, _BaseMap);
OUT.fogCoord = ComputeFogFactor(OUT.positionCS.z);
return OUT;
}
half4 frag (Varying IN) : SV_Target
{
half4 color = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, IN.uv) * _BaseColor;
#if defined(_USE_CAMERA_COLOR_TEXTURE)
float4 cameraColor = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, IN.screenPos.xy / IN.screenPos.w);
color.rgb *= cameraColor.rgb;
#endif
#if defined(_USE_CAMERA_DEPTH_TEXTURE)
float4 cameraDepth = LinearEyeDepth(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, IN.screenPos.xy / IN.screenPos.w), _ZBufferParams) * 0.005;
color.a *= 1 - saturate(cameraDepth.r);
#endif
color.rgb = MixFog(color.rgb, IN.fogCoord);
return color;
}
ENDHLSL
}
}
}