How to sample reflection in URP shader (not graph!)

I’ve figured out most of the other stuff by combing through the unity graphics github repo and utilizing what little documentation there is so far, but the built-in shader code is extremely complicated and split across several confusing files that makes it quite difficult to reverse engineer.

Basically, all I’d like to know is the proper way to sample the reflection that is relevant (reflection probes, skybox if no reflection probes) properly in URP. If reflection probe blending and box projection is also implemented on a per-shader basis, it’d be great to know how that’s implemented too.

Add the node into a shader graph

View generated shader code

Search for the node in the huge wall of text

Enjoy the function that does it all!

1 Like

Sampling reflection probes is fortunately a one-liner in URP:

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/GlobalIllumination.hlsl"
//Occlusion is optional, set to 1.0h
float3 probes = GlossyEnvironmentReflection(reflectionVector.xyz, positionWS.xyz, smoothness, occlusion, normalizedScreenSpaceUV.xy).rgb;

To support the full range of features behind this function your shader needs these keywords:

//Reflection feature toggle			
#pragma shader_feature_local_fragment _ENVIRONMENTREFLECTIONS_OFF		

//URP 12+ only (2021.2+)
#pragma multi_compile_fragment _ _REFLECTION_PROBE_BLENDING
#pragma multi_compile_fragment _ _REFLECTION_PROBE_BOX_PROJECTION
//Unity 6.1+
 #if (UNITY_VERSION >= 60010000)
    #pragma multi_compile _ _CLUSTER_LIGHT_LOOP
    #pragma multi_compile_fragment _ _REFLECTION_PROBE_ATLAS
#endif
1 Like

Thanks for referring me to the function! Just worth noting, after having a look at GlobalIllumination.hlsl it seems like the smoothness value is actually meant to be perceptualRoughness. Not entirely sure if it’s irrelevant or not in this case.

half3 GlossyEnvironmentReflection(half3 reflectVector, float3 positionWS, half perceptualRoughness, half occlusion, float2 normalizedScreenSpaceUV)

Yes that is indeed the case. It’s been a long time since I’ve followed the breadcrumb trail towards that function, but I believe “perceptual roughness” is the final result of the BRDF with the material’s smoothness (map) incorporated.

For the function it, it acts as a linear blend between the lowest and highest mipmap, effectively controlling the amount of blurring.

1 Like