Jump to content
  • Advertisement
Sign in to follow this  

Glass Refraction Material from the book "PBR"

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

If you intended to correct an error in the post then please contact us.

Recommended Posts



i would like to implement glass material in my pathtracer. I tried to copy the code from "PBR - From Theorie to Implementation" but i am not sure if i did it right. My current approach looks like this:

The index of refraction outside glass is 1.0, inside it is 1.3. First i convert the direction vector to an angle called "cosThetaI":

    def getAngle(direction,normal):
        dotPr = direction.dot(normal)
        angle = math.acos(dotPr / (direction.length() * normal.length()))
        return angle

If cosThetaI is greater than 0, i switch the refractive indices.

        etaI = 1.0
        etaT = 1.3
        cosThetaI = Point3D.getAngle(ray.direction,normal)
        cosThetaI = Point3D.clamp(cosThetaI,-1,1)
        if(cosThetaI > 0.0):
            etaI = 1.3
            etaT = 1.0
        cosThetaT = Point3D.snellsLaw(cosThetaI,etaI,etaT)
        Rparl = ((etaT * cosThetaI) - (etaI * cosThetaT)) / ((etaT * cosThetaI) + (etaI * cosThetaT))
        Rperp = ((etaI * cosThetaI) - (etaT * cosThetaT)) / ((etaI * cosThetaI) + (etaT * cosThetaT))
        dir = Point3D.getPoint((Rparl * Rparl + Rperp * Rperp) / 2)
        reflectionRay = Ray(hitPoint,dir.normalize())
    def getPoint(angle):
        return Point3D(math.cos(angle),math.sin(angle),1)
    def snellsLaw(cosThetaI,etaI,etaT):
        sinThetaI = math.sqrt(max(0,1-cosThetaI*cosThetaI))
        sinThetaT = etaI / etaT * sinThetaI
        cosThetaT = math.sqrt(max(0,1-sinThetaT * sinThetaT))
        return cosThetaT

I am not quite sure how to convert an angle into an 3D vector though...

Share this post

Link to post
Share on other sites

Your code is authored such that it should be working in terms of cos(thetaI), but it's actually working with thetaI. cos(thetaI) is equal to the dot product between the direction vector and the normal vector (assuming both vectors are normalized), so there's no need for the acos() calculation.

Also, Rparl and Rperp are for computing the reflectance at the interface, not the reflected direction of the light. In other words it's computing how much light will reflect off of the surface, not the direction in which it will travel after reflecting. Computing that direction is computed later in that same chapter, in the section called "Specular Reflection" (section 8.2.2 if you're using the 3rd edition of the PBR book). Right after that it will cover how to compute the refracted direction in the "Specular Transmission" section.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!