作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个用于教育目的的简单光线跟踪器,并希望为对象添加折射。使用斯内尔定律,我能够在交点处递归地创建一条新射线。光线追踪器目前仅支持球体,我使用了一个场景,其中多个球体相互嵌套并具有不同的折射率。
如果我从球体外部开始一条射线,一切似乎都很简单。您从场景的折射率开始,一旦碰到第一个球体,就使用之前的折射率和球体 Material 的折射率来折射光线,直到碰到下一个球体,依此类推。使用交叉点的法线,我可以确定我是进入还是离开球体。
但是,我不明白我应该如何处理球体叶子以及如果光线不在场景的外部开始该怎么办。
最佳答案
我有一个类似的光线追踪器(用 Python 编写)并偶然发现了同样的问题:为了正确计算物理,必须知道相交边界每一侧的折射率。这花了很长时间才优雅地解决,但最后我采用了这个解决方案/设计:
设计
1)场景——我有一个主场景对象(基本上是场景中所有对象的数组),你可能会有类似的东西。它存储几何对象。
方法:
intersection_points(ray)
- 返回所有交点的列表,按与射线的距离排序。 intersection_objects(ray)
- 返回所有相交对象的列表,按与射线的距离排序。 containing_object(ray)
- 返回包含射线的对象。 objects()
- 以任意顺序返回所有对象的列表。 contains(ray)
- 返回真射线原点在物体内部,假如果在表面上,假如果在外面ray_is_on_surface(ray)
- 如果光线仅在表面上,则返回 True,否则返回 False。 intersection_points(ray)
- 返回光线与物体的交点 surface_normal(ray)
- 返回光线撞击表面的表面法向量(这将有助于菲涅尔反射和折射)refractive_index
sphere # origin = (0,0,0), radius = 1
ray # origin = (0,0,0), direction = (0,0,1) Note: the ray is inside the sphere
scene.add_object(sphere)
ipoints = scene.intersection_points(ray) # [ (0,0,1), (0,0,10) ]
iobjects = scene.intersection_objects(ray) # [ Sphere, Scene_Boundary]
obj1 = scene.containing_object(ray) # Scene_Boundary
n1 = obj1.refractive_index() # n1 = 1. Scene_Boundary always has refractive index of Air
index = iobjects.index_of_object(obj1)
obj2 = iobjects[index+1]
n2 = obj2.refractive_index() # n2 = 1.5 e.g. Glass
normal = obj1.surface_normal(ray)
def reflect_vector(normal, vector):
d = numpy.dot(normal, vector)
return vector - 2 * d * normal
def fresnel_refraction(normal, vector, n1, n2):
n = n1/n2
dot = np.dot(norm(vector), norm(normal))
c = np.sqrt(1 - n**2 * (1 - dot**2))
sign = 1
if dot < 0.0:
sign = -1
refraction = n * vector + sign*(c - sign*n*dot) * normal
return norm(refraction)
def fresnel_reflection(angle, n1, n2):
assert 0.0 <= angle <= 0.5*np.pi, "The incident angle must be between 0 and 90 degrees to calculate Fresnel reflection."
# Catch TIR case
if n2 < n1:
if angle > np.arcsin(n2/n1):
return 1.0
Rs1 = n1 * np.cos(angle) - n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2)
Rs2 = n1 * np.cos(angle) + n2 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2)
Rs = (Rs1/Rs2)**2
Rp1 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) - n2 * np.cos(angle)
Rp2 = n1 * np.sqrt(1 - (n1/n2 * np.sin(angle))**2) + n2 * np.cos(angle)
Rp = (Rp1/Rp2)**2
return 0.5 * (Rs + Rp)
关于graphics - 当光线从嵌套对象内部开始时如何处理折射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3858662/
我正在编写一个 GLSL 着色器来模拟简单对象的色差。我保持 OpenGL 2.0 兼容,所以我使用内置的 OpenGL 矩阵堆栈。这是简单的顶点着色器: uniform vec3 cameraPos
Actually I'm not sure that Title of my question is 'correct', if you have any idea with it, you coul
我是一名优秀的程序员,十分优秀!