Getting started
Getting Started
Using an Existing Unity Project
Samples & Examples
Core Concepts & Glossary
Unity Package Types
Spaces & Space Templates
Custom Avatars
Custom Avatar Animations
Avatar Attachments
Custom Prefab Objects
World Building
‣
‣
Quests and Rewards
Drivable Vehicles
Economy
Economy Overview
Items
Rewarding Items
World Currency
Selling Items
Scripting
‣
‣
Guidelines
Supported Features and Limitations
Performance Guidelines
Lighting
Publishing to Spatial
Finding Published Packages
Support
FAQs
Help and Community
Release Notes
Fixing Broken Shaders on Mobile & VR
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.
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
}
}
}