I am trying to implement the Parallax Refraction effect explained by Jorge Jimenez on this presentation: http://www.iryoku.com/downloads/Next-Generation-Character-Rendering-v6.pptx and I am facing some difficulties. Here is a screenshot of the interesting part.


But this document lacks a bit of explanations especially the second part with the Physically based Refraction.

Here is what I've achieved for the moment.
This is the simple Parallax Refraction effect and, as you might notice in the screenshot, there is small glitch at grazing angles in the iris when the Parallax Scale value is too high.

This is caused by the parallax calculation but are there some tricks to avoid or minimize such issue ?

I don't want to go deeper with parallax mapping for the moment, so I don't want to use Steep Parallax Mapping or Parallax Occlusion Mapping.


Here is the code. Nothing really special.

// height value comes from a texture
float2 offset = height * viewDir;
offset.y = -offset.y;
texcoord -= ParallaxScale * offset;
// Next there is the texture sampling with the texcoord value

I also have another question about the Physically based Refraction part which is not really well explained and I am missing how some values are calculated such as refractedW, frontNormalW or heightW. If anyone could provide some explanations about those values.

Thanks a lot.


Here is the way I calculate the refraction vector according to Snell's law.

float cosine = dot(viewDir, worldNormal);
float sine = sqrt(1 - cosine * cosine);

float sine2 = (_IOR * sine);
float cosine2 = sqrt(1 - sine2 * sine2);

float3 x = -worldNormal;
float3 y = normalize(cross(cross(viewDir, worldNormal), worldNormal));
float3 refractedW = x * cosine2 + y * sine2;

This is integrated with the Physically based Refraction and it gives interesting results but I still don't know how to get rid of the high parallax scale issue which appear at grazing angles...

Any idea how to get rig of that ?

  • $\begingroup$ There might also be some ways to optimize the Snell's law calculations, any advice are also welcome on that. $\endgroup$
    – MaT
    Oct 17 '16 at 15:50

As I am working with Unity, I found an interesting way of calculating the parallax offset inside the engine. It's not physically based but it gives better results than the classic parallax refraction.

float2 ParallaxOffset(half h, half height, half3 viewDir)
    h = h * height - height / 2.0;
    float3 v = normalize(viewDir);
    v.z += 0.42;
    return h * (v.xy / v.z);

Your Answer

