from ..utils.constants import * from ..utils.vector3 import vec3, rgb, extract from functools import reduce as reduce from ..ray import Ray, get_raycolor from .. import lights import numpy as np from . import Material class Refractive(Material): def __init__(self, n, **kwargs): super().__init__(**kwargs) self.n = n # index of refraction # Instead of defining a index of refraction (n) for each wavelenght (computationally expensive) we aproximate defining the index of refraction # using a vec3 for red = 630 nm, green 555 nm, blue 475 nm, the most sensitive wavelenghts of human eye. # Index a refraction is a complex number. # The real part is involved in how much light is reflected and model refraction direction via Snell Law. # The imaginary part of n is involved in how much light is reflected and absorbed. For non-transparent materials like metals is usually between (0.1j,3j) # and for transparent materials like glass is usually between (0.j , 1e-7j) def get_color(self, scene, ray, hit): hit.point = (ray.origin + ray.dir * hit.distance) # intersection point N = hit.material.get_Normal(hit) # normal color = rgb(0.,0.,0.) V = ray.dir*-1. # direction to ray origin nudged = hit.point + N * .000001 # M nudged to avoid itself # compute reflection and refraction # a paper explaining formulas used: # https://graphics.stanford.edu/courses/cs148-10-summer/docs/2006--degreve--reflection_refraction.pdf # reallistic refraction is expensive. (requires exponential complexity because each ray is divided in two) if ray.depth