#World Normals not displaying in fragment shader

1 messages · Page 1 of 1 (latest)

ornate bison
#

I have this line in my fragment shader:

float3 depthNormalWS = SampleSceneNormals(screenUV);
return half4(depthNormalWS, 1.0);

I've included this at the top of my shader

#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"

I sample the depth buffer and scene color and they work perfectly fine, so i know screenUV must be correct. Unless there is some weird difference for world normals?

I also know the normals texture is being generated, the SSAO is enabled with Depth Normals as its source. I'm using URP in deferred+, though my shader is transparent so its technically forward+

However my output is black, the grey cube is what i'm testing world normals with, which is standard urp lit shader.

Why might i be getting black here, seems to suggest the normals are all 0?

I get no compile errors also.

orchid knoll
#

Did you try using float instead of half?

ornate bison
#

yeah

#

seems like its just 0 everywhere

orchid knoll
ornate bison
#

The code just samples a texture but doesn't really say much else

orchid knoll
ornate bison
#

the hlsl script by unity has this:

#ifndef UNITY_DECLARE_NORMALS_TEXTURE_INCLUDED
#define UNITY_DECLARE_NORMALS_TEXTURE_INCLUDED
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/DynamicScalingClamping.hlsl"

TEXTURE2D_X_FLOAT(_CameraNormalsTexture);
float4 _CameraNormalsTexture_TexelSize;

// 2023.3 Deprecated. This is for backwards compatibility. Remove in the future.
#define sampler_CameraNormalsTexture sampler_PointClamp

float3 SampleSceneNormals(float2 uv, SAMPLER(samplerParam))
{
    uv = ClampAndScaleUVForBilinear(UnityStereoTransformScreenSpaceTex(uv), _CameraNormalsTexture_TexelSize.xy);
    float3 normal = SAMPLE_TEXTURE2D_X(_CameraNormalsTexture, samplerParam, uv).xyz;

    #if defined(_GBUFFER_NORMALS_OCT)
    float2 remappedOctNormalWS = Unpack888ToFloat2(normal); // values between [ 0,  1]
    float2 octNormalWS = remappedOctNormalWS.xy * 2.0 - 1.0;    // values between [-1, +1]
    normal = UnpackNormalOctQuadEncode(octNormalWS);
    #endif

    return normal;
}

float3 SampleSceneNormals(float2 uv)
{
    return SampleSceneNormals(uv, sampler_PointClamp);
}

float3 LoadSceneNormals(uint2 pixelCoords)
{
    float3 normal = LOAD_TEXTURE2D_X(_CameraNormalsTexture, pixelCoords).xyz;

    #if defined(_GBUFFER_NORMALS_OCT)
    float2 remappedOctNormalWS = Unpack888ToFloat2(normal); // values between [ 0,  1]
    float2 octNormalWS = remappedOctNormalWS.xy * 2.0 - 1.0;    // values between [-1, +1]
    normal = UnpackNormalOctQuadEncode(octNormalWS);
    #endif

    return normal;
}
#endif

https://github.com/Unity-Technologies/Graphics/blob/75a39ecda62bcbb6c5c5980d99696f7f3614e26c/Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl#L6

#

i tried this:

            #if defined(_CAMERA_NORMALS_TEXTURE)
                float3 depthNormalWS = SampleSceneNormals(screenUV);
                return half4(depthNormalWS, 1.0);
            #else
                return half4(0,1,1,1);
            #endif

i get cyan output so it suggests its not defined but that is confusing because unity's SSAO is working and that also uses camera normals

orchid knoll
ornate bison
#

nah i ditched shader graph

#

writing custom shader at this point

orchid knoll
#

So the issue happens in a normal shader? I think you might need some macros or something in the shader lab then.

ornate bison
#

probably, depth buffer and scene color buffer work fine

#

its just the camera normals that are problematic

orchid knoll
#

I don't know how truthful it is, but gpt o3 says:

HLSL shader

// URP will bind the texture as soon as you sample it
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"

float3 wsNormal = SampleSceneNormals(IN.screenUV);

Simply including DeclareNormalsTexture.hlsl (and using SampleSceneNormals) makes the compiled variant reference _CameraNormalsTexture; URP sees this in reflection and flags the pass as “needs camera normals”, so no extra keyword is required. 


---

If you’re driving the shader from a custom ScriptableRenderPass

// inside your RendererFeature
myPass.ConfigureInput(ScriptableRenderPassInput.Normal);

ConfigureInput tells the renderer to generate and bind the normals texture for the frame.

Though it seems like you're already including the correct header.
Is it a custom pass?

ornate bison
#

no its just regular urp lit shader though it is a transparent

#

rather than opaque so not sure if that matters

orchid knoll
#

Shouldn't really matter IMHO.
I guess what you could do is:

  1. Look at the generated shader code and check if it declares the camera normals texture property somewhere.
  2. Look at the frame debugger to see what textures are bound to the draw call.
  3. Check if the normals texture is actually rendered before this draw call.
ornate bison
#

for my transparents there are no textures bound - though isnt it a global buffer like depth and scene color so it wouldn't be bound to the draw call?

orchid knoll
orchid knoll
#

I'm talking about the state when you had it output black color, not the cyan one.

ornate bison
#

let me remove the define check and just output black and check frame debugger again

#

ok it is showing in there now i removed the define check

#

but even the thumbnail it looks black

#

but thats confusing because why does the define check give false when i do a check ?

orchid knoll
#

In your screenshot, it seems to be binding the gbuffer, which is what you'd expect in deferred renderer. Check if there are any draw calls that write to that gbuffer texture.

ornate bison
#

yeah i use deferred+ but i think transparents are used in forward+

#

what should i be looking for in frame debugger

#

GBuffer2?

#

found it here for SSAO

orchid knoll
# ornate bison yeah i use deferred+ but i think transparents are used in forward+

Well, yes and no. When we talk about rendering paths we usually refer to how opaque geometry is rendered. In deferred it is first rendered to the gbuffer and later assembled into the scene color texture in the lighting pass. Translucent is always rendered after that, so you can say that it's always is forward, but since it's always the same, there's no point mentioning that.

orchid knoll
orchid knoll
#

You should look for draw calls that have it in the Output/RenderTargets sections.

ornate bison
#

is this the opaques ?

orchid knoll
ornate bison
#

ok that has GBuffer0 render target

orchid knoll
#

Aha

ornate bison
#

also has no normals bound but also no scene color or depth

orchid knoll
#

Textures are the input textures used by the shader, not what it writes to.

ornate bison
#

aha like this

#

didnt realise there was a drop down to view different render textures

#

but that looks like a normal vector (0,1,0)

#

for the top of my cube

#

strange the sides are black though

orchid knoll
orchid knoll
ornate bison
#

its just default meshes though

orchid knoll
#

BTW, you should select the draw calls, as they are what actually represents your shader rendering. What you have selected now is just a marker of the category. If you had several draw calls, it wouldn't be clear which data it's showing you.

orchid knoll
# ornate bison aha like this

One thing that bothers me is that the skybox appears to be rendering after the opaques. I guess it could be for optimization, but can you check if it perhaps overrides whatever was rendered to the gbuffer?

ornate bison
#

im not sure what im looking for in the draw mesh output page to know for sure?

orchid knoll
#

As well as details showing the render target

ornate bison
orchid knoll
#

Ah ok, looks fine

orchid knoll
# ornate bison aha like this

Ok, so because your transparent plane is below that top surface, there is nothing. Can you test by placing it above the cube?

ornate bison
#

ah good thinking! so it is working

#

but it is odd the x and z axis is not working

#

thats why i was confused because i should see red and blue for the other faces, no ?

orchid knoll
#

Technically, yes.

#

I can't come up with a reason as to why this is happening at the moment. Gotta drink my cofee and think about it...

ornate bison
#

okay 🙂

#

oh i think its working

#

it seems restarting unity fixed it. maybe the shaders were not correctly compiling

#

ive noticed some times i get compile errors to do with code i deleted some times

orchid knoll
#

Interesting. Glad you got it solved.