Screen Space Reflections... Again?

This topic is 1370 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hello everyone! This is my first post on GameDev.net and I'm excited to be apart of this community! I'm a guy in high school who has found a love for shaders and I primarily use Unity3D. I still figured many people here would still be able to help me.

Method

I use the method outlined here from this video. I noticed in his example he normalized the View space position, but my results were.. strange to say the least. I also noticed that I'm not the first person here to implement that same technique. And I noticed that he goes straight from ViewSpace to ScreenSpace unlike the other methods that go from screenspace then view then back to screen space I think?

Problem?

The reflections are not in the proper place although I've checked and tried everything I'm certain the issue lies with the reflection ray ( R ), everything else seems to be proper, such as view space positions, matrices, screen space positions etc. I have actually had this problem all 5 or 6 times I've tried to implement SSR into Unity. Help is very much appreciated

If you would like to see more code than posted below then let me know I have no problem providing it. I'm pretty sure all the matrices math is correct though.

Code

half4 CameraSpaceToScreenSpace(half3 cameraSpace)
{
half4 clipSpace = mul(_ProjMatrix, half4(cameraSpace, 1));
half3 NDCSpace = clipSpace.xyz / clipSpace.w;
half3 screenSpace = 0.5 * NDCSpace + 0.5;
return half4(screenSpace, 1);
}

Shader "Custom/SSR"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
}

CGINCLUDE
#include "UnityCG.cginc"
#include "OcclusionUtilities.cginc"

#define REFLECT_SKY
#define REFLECTION_STRENGTH 1.0
#define REFLECTION_RANGE 1.0
#define F0 1.0

half4 SSR(v2f i) : COLOR
{
half2 coords = i.uv.xy;
half d = GetLinearDepth(coords);
half4 c = tex2D(_MainTex, coords);
half3 N = GetPerPixelNormal(coords) * 0.5 + 0.5;
half3 V = GetViewPos(coords).xyz;

Ray R = reflect(V, N);

//FIX: For some reason the x-values in the Ray are off center by this much
R.x *= -0.05;
//R.y *= 2.0;
//R.z *= 3.0;

//Fresnel is everywhere!
half NdotV = dot(N, V);
//TODO: Make physically-based [GGX Distibution]
half specular = F0 + (1.0 - F0) * exp2((-5.55473 * NdotV - 6.98316) * NdotV);

half3 viewPos = GetViewPos(coords).xyz;

uint steps = 0;
half4 samplePos = half4(0.0, 0.0, 0.0, 0.0);
uint refinementRays = MAX_STEPS;
half rayIncriment = 1.0 / MAX_RAYS * .7;

// Raymarch
if(d < 0.99) //No reflections on the sky, but the sky reflects if defined
{
while(steps < MAX_STEPS * REFLECTION_RANGE)
{
viewPos.xyz += R.xyz * rayIncriment;
samplePos = CameraSpaceToScreenSpace(viewPos);
half3 currentPos = GetViewPos(samplePos.xy).xyz;

if(currentPos.z <= viewPos.z)
{
refinementRays = steps;
steps = MAX_STEPS;
}
else
steps++;

if(refinementRays < MAX_STEPS * REFLECTION_RANGE)
{
steps = 0;

// Refine the raymarch
while(steps < MAX_RAYS)
{
viewPos.xyz -= R * rayIncriment / MAX_RAYS;
half4 samplePos = CameraSpaceToScreenSpace(viewPos);
half3 currentPos = GetViewPos(samplePos.xy).xyz;

if(currentPos.z > viewPos.z)
{
refinementRays = steps;
steps = MAX_STEPS;
}
else
steps++;
}

}

// Fade out reflection code will go here, use cheap algorithmic vigentte?

#ifdef REFLECT_SKY
specular *= 1.0;
#else
specular *= RangeCheck(currentPos.z - viewPos.z);
#endif

specular = saturate(specular);
half3 reflection = (tex2Dlod(_MainTex, half4(samplePos.xy, 0, 0)) * REFLECTION_STRENGTH);
c.rgb = lerp(c, reflection, specular);

return half4(c.rgb, 1);

}

}
else
{
return c;
}

}

ENDCG

{
ZTest Off Cull Off ZWrite Off
Fog { Mode off }

//Pass 0 SSR
Pass
{
CGPROGRAM
#pragma target 3.0
#pragma glsl
#pragma vertex vert
#pragma fragment SSR
ENDCG
}
}

}



Using: MAX_STEPS = 6; MAX_RAYS = 6. (Re-used some code from my HBAO).

Results?

With un-normalized V (View Space Position)

With normalized V - (disabled the normal map on the plane to see it better)

The normalized V has planar reflections only at extremely high grazing angles and the reflections on the objects look weird and wrong as opposed to the un-normalized V. I would like to have the reflections on the objects look like the ones in the unnormalized V pictures fixed in in the proper positions of course and the planar reflections upside down as they should be.

Debug

View Space Position

Reflection Ray ( R )

Reflection Ray ( R ) - NORMALIZED V

Sample Position xy

View Normals

Depth

Thank you for your time!

Edited by Willywill

Share on other sites

From the screen shot the reflection rays looks wrong. The colors should match those of the view normals.

The line

half3 N = GetPerPixelNormal(coords) * 0.5 + 0.5;

half3 N = GetPerPixelNormal(coords);

Henning

Share on other sites

From the screen shot the reflection rays looks wrong. The colors should match those of the view normals.

The line

half3 N = GetPerPixelNormal(coords) * 0.5 + 0.5;

half3 N = GetPerPixelNormal(coords);

Henning

Alright thanks, the Get Per Pixel Normals line there is just decoding the normals and samples the normals texture at the given coordinates, I could have thrown the (* 0.5 + 0.5) into the function but it appears to have no grand effect on the reflection.

Hopefully you can see it more clearly here but the reflection is way out of place. But I feel as though I'm using the correct matrices math.

In the code the original author provided, he multiplied the samplePos by ViewProj matrix. I have tried that but the results even more incorrect looking.

EDIT: Looking at other implementations, the way the Ray is calculated in the authors code seems very different from others. They reflect the normals and viewPosition but they also do a bit of conversion and subtraction of vectors before hand.

Share on other sites

Still you a turning you signed normalized normal into an unsigned normal when applying x * 0.5 + 0.5. And from the last screen shot this appears to still be the problem.

If you look at the screen shot with labeled "Reflection Ray ( R ) - NORMALIZED V" The colors clearly indicate that they are unsigned (colors get close to white). If they were correct they should look like the ones in screen shot labeled "View Normals"

Henning

Share on other sites

Still you a turning you signed normalized normal into an unsigned normal when applying x * 0.5 + 0.5. And from the last screen shot this appears to still be the problem.

If you look at the screen shot with labeled "Reflection Ray ( R ) - NORMALIZED V" The colors clearly indicate that they are unsigned (colors get close to white). If they were correct they should look like the ones in screen shot labeled "View Normals"

Henning

Thanks, I've made the changes previously but as a said its almost a non-issue as it doesn't solve the big glaring issue. However, what I will do is, I'll go ahead and try a slightly different approach and report back and tell if it helps or doesn't and I get stuck again.

1. 1
2. 2
Rutin
21
3. 3
A4L
15
4. 4
5. 5

• 13
• 26
• 10
• 11
• 44
• Forum Statistics

• Total Topics
633740
• Total Posts
3013621
×