Refractive Material using Apple PBR?

I am trying to make a 3D objects that are refractive using just SceneKit and perhaps a bit of code in Swift and Metal.


There are examples made using Unity, however, I do not have access to Unity in my Mac. I decided to just try to make or source some kind of Metal material that does refraction.


The closest is this, but in Objective C and did not compile because the writer might need to update the book.

http://metalbyexample.com/reflection-and-refraction/


I am still searching through to find Apple example that actually hiting on refractive streaming background video plate.


Apple SceneKit Material PBR is actually pretty cool for Metalic and reflective surface. Even the Blinn and Phong works awesome with Fresnel edge highlight... it is the bubble shader that I wish can be done simply via material.

Replies

I used the following vertex shader back in the days of writing your OpenGL program yourself:

attribute highp   vec3  inVertex;
attribute mediump vec3  inNormal;

uniform highp   mat4  MVPMatrix;
uniform mediump vec3  LightDirModel;
uniform mediump vec3  EyePosModel;
uniform         bool  bSpecular;
uniform         bool  bRotate;

varying lowp    float  SpecularIntensity;
varying mediump vec2   RefractCoord;

const mediump float  cShininess = 3.0;
//const mediump float  cRIR = 1.055;//1.015
uniform mediump float  cRIR;

void main()
{
  // Transform position
    //inVertex.z = 10.0 * inVertex.z;
  gl_Position = MVPMatrix * vec4(inVertex, 1.0);

  // Eye direction in model space
  mediump vec3 eyeDirModel = normalize(inVertex - EyePosModel);

  // GLSL offers a nice built-in refaction function
  // Calculate refraction direction in model space
  mediump vec3 refractDir = refract(eyeDirModel, inNormal, cRIR);

  // Project refraction
  refractDir = (MVPMatrix * vec4(refractDir, 0.0)).xyw;

  // Map refraction direction to 2d coordinates
  RefractCoord = 0.5 * (refractDir.xy / refractDir.z) + 0.5;

  if(bRotate) // If the screen is rotated then rotate the uvs
  {
  RefractCoord.xy = 1.0 -RefractCoord.yx;
  }

  // Specular lighting
  // We ignore that N dot L could be negative (light coming 
  // from behind the surface)
  SpecularIntensity = 0.0;

  if (bSpecular)
  {
  mediump vec3 halfVector = normalize(LightDirModel + eyeDirModel);
  lowp float NdotH = max(dot(inNormal, halfVector), 0.0);
  SpecularIntensity = pow(NdotH, cShininess);
  }
}

Haven't managed to get this working in the Metal/Scenekit framework though. (the above example came from an example app by Khronos).
There's also this Khronos tutorial: https://en.wikibooks.org/wiki/GLSL_Programming/Unity/Curved_Glass
which could help as a foundation to a shader in Scenekit.