kode80 / kode80SSR

An open source screen space reflections implementation for Unity3D 5.
BSD 2-Clause "Simplified" License
382 stars 92 forks source link

Distortions based on the angle #13

Open Rbn3D opened 9 years ago

Rbn3D commented 9 years ago

When the reflected ray angle is greater than 90º, and being increased as it comes close to 180º, the reflections start to distort (they grow infinitely on the reflecting surface).

If you bump (a lot) pixel stride, the ploblem is less appreciable, but still noticieable, and you lose a lot of quality, so is not a good workaround.

If you bump ssr downsample, surprisingly the problem is less appreciable too, but not a feasible solution.

Screens:

With a reflected angle of ~ 160º image

With a sightly lower angle image

As you can see there are also some artifacts, but could be related to the issue.

Here are my settings (Tweaking them doesn't alter the issue, excepting those I said above) image

I'm using a lot of iterations and low pixel stride because it introduces a lot of artifacts in my specific case.

Using latest code from master 253e08fca68a6d95f4908a6a0b1df24609ce12ba

Thank you so much for the amazing work.

kode80 commented 9 years ago

Those are artifacts related to the reflection angle. Use Eye Fade Start and Eye Fade End to hide them. Eye Fade Start is the Z value of the reflection angle where reflections start to fade out and Eye Fade End is the Z value of the reflection angle where reflections are completely invisible. Try setting End to around 0.8 and Start to around 0.5 and then tweak from there for what suits your scene.

Rbn3D commented 9 years ago

Followed your instructions, but still many distortions and artifacts, see screenshots and animated gifs below:

kode80test3

kode80test2

kode801

kode802

kode80 commented 9 years ago

What eye fade start/end values did you use for these?

Rbn3D commented 9 years ago

Start: 0.5, End: 0.8

It's less appreciable now, but still visible.

My thinking on this is that a reflection must not distort, regardless of the angle; if you raymarch a pixel, you sample that pixel, if no, just no contribute. Then you can fade these edges to make less noticeable that you cannot sample reflection on some areas, but not to hide distortions that shouldn't be there.

dnnkeeper commented 9 years ago

I managed to hide similar artifacts by adding an angle-based fading to SSR.shader fragment code

 float3 nvsRayOrigin = normalize(vsRayOrigin);
 decodedNormal = normalize(decodedNormal);
 float3 vsRayDirection = normalize( reflect(nvsRayOrigin, decodedNormal));
 float angle = saturate( dot(nvsRayOrigin, decodedNormal) + 1.0 );
 angle *= angle;
 ...
 return half4((tex2D(_MainTex, hitPixel)).rgb * specRoughPixel.rgb, alpha*angle);

it fades out ssr based on squared cos of the angle between view direction and surface normal