Jump to content

refract() vex node, breakdown


Recommended Posts

Hey Guys! I've been experimenting with the refract node in vopsop context as well as the refract() function in vex. I'm curious if anyone has been able to break that node down to it's raw form? I would essentially like to know how it actually evaluates it's inputs. Can anyone shed some light on that? I would like to know the math behind it.


The refract function takes three inputs, a direction vector, a normalized normal and an index of refraction.




Link to comment
Share on other sites



The direction vector is the incident vector, "i" in the above image.  The normalized normal is the surface normal "n".  Index of refraction controls the amount that the incident ray will be refracted, a value of 1 will leave "i" unchanged.  A value of 1.33 will refract the ray similar to water.

The red arrow in the image above represents the output vector of the refract() function.


Hope that helps!

Link to comment
Share on other sites

thanks for the diagram! however I was really looking for an explanation of the math that is going on within the refract() function. How does the refract() function generate the angle of refraction, given the angle of incidence, the normalized normal and an index of refraction? 

Link to comment
Share on other sites

Not tested but this looks fine (eta is IOR):

inline void Refract(
  VEC3 &out, const VEC3 &incidentVec, const VEC3 &normal, float eta)
  float N_dot_I = Dot(normal, incidentVec);
  float k = 1.f - eta * eta * (1.f - N_dot_I * N_dot_I);
  if (k < 0.f)
    out = VEC3(0.f, 0.f, 0.f);
    out = eta * incidentVec - (eta * N_dot_I + sqrtf(k)) * N;

Source: http://asawicki.info/news_1301_reflect_and_refract_functions.html

  • Like 1
Link to comment
Share on other sites

thank you guys, my goal is to implement a "raw" version of the refract node for the purpose of using it in other contexts such as python, where the refract() function would not be accessible. In other words I'm writing a python equivalent of the refract() vex, but I want to be sure the calculation is correct and produces the exact same results.

Edited by rhussain
Link to comment
Share on other sites

I've found that the results are not the same between the provided code and the refract vex function. Thats because the refract() function performs a few additional calculations than the code you provided. If there is total internal reflection then the calculation is changed to reflect() instead of returning {0,0,0}. Also if the incident ray is already under the normals direction :inside to inside relationship then the normal must be flipped and the value of eta needs to be changed from n1 / n2 to n2 / n1. It's all making sense now!

Edited by rhussain
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...