【简介与代码下载】

本节会在【OptiX】第5个示例 递归反射、抗锯齿的基础上加上折射。本文的代码如下:

链接:https://pan.baidu.com/s/1mAXoYBMbx_gWtCliUZ5o0Q 
提取码:20ba 
下载解压后,请使用VS2015打开工程,并把当前配置调整为Debug和x64。另需要在默认路径安装OptiX6.0与CUDA10.0,可以参考我的这篇博文:【Optix】Optix介绍与示例编译

运行效果如下:

【理论基础-折射】

折射非常简单,只要求出折射光线的方向就像反射一样递归计算就可以了。针对折射角有个定律叫做snell定律,它定义了光从一种材质射入到另一种材质入身角和折射角之间的关系:

其中n1和n2分别是两个介质的折射率,而折射率都是已知的。由此就可以求出折射方向了。在OptiX给我们提供了refract函数,它的原型如下:r是出参反射方向,i是入射光向,n是表面法线,ior则是折射率之比。

/**
*  Calculates refraction direction
*  r   : refraction vector
*  i   : incident vector
*  n   : surface normal
*  ior : index of refraction ( n2 / n1 )
*  returns false in case of total internal reflection, in that case r is
*          initialized to (0,0,0).
*/
OPTIXU_INLINE RT_HOSTDEVICE bool refract(float3& r, const float3& i, const float3& n, const float ior)
{float3 nn = n;float negNdotV = dot(i,nn);float eta;if (negNdotV > 0.0f){eta = ior;nn = -n;negNdotV = -negNdotV;}else{eta = 1.f / ior;}const float k = 1.f - eta*eta * (1.f - negNdotV * negNdotV);if (k < 0.0f) {// Initialize this value, so that r always leaves this function initialized.r = make_float3(0.f);return false;} else {r = normalize(eta*i - (eta*negNdotV + sqrtf(k)) * nn);return true;}
}

【理论基础-折射与反射比】

当光照射向物体时,究竟多少折射多少反射,此时又有个定律叫做fresnel定律,schlick使用入射光与法线的夹角这一主要项,辅助fresnel_exponent等来估算出折射与反射比,在OptiX中有如下函数:返回值就是[0, 1]的值,代表反射率,反射率与折射率的和为1。

/** Schlick approximation of Fresnel reflectance
*/
OPTIXU_INLINE RT_HOSTDEVICE float fresnel_schlick(const float cos_theta, const float exponent = 5.0f,const float minimum = 0.0f, const float maximum = 1.0f)
{/**Clamp the result of the arithmetic due to floating point precision:the result should lie strictly within [minimum, maximum]return clamp(minimum + (maximum - minimum) * powf(1.0f - cos_theta, exponent),minimum, maximum);*//** The max doesn't seem like it should be necessary, but without it you getannoying broken pixels at the center of reflective spheres where cos_theta ~ 1.*/return clamp(minimum + (maximum - minimum) * powf(fmaxf(0.0f,1.0f - cos_theta), exponent),minimum, maximum);
}

【射入物体的光线】

本例是计算了一个玻璃球,情况比没有折射的复杂了一点,也即光线的发生点可能在球体内部,当我们从球的外部观察球体时,发出的光线与球体相撞,相撞点叫做t_hit,而后以t_hit为起点,以折射光线与方向又在球内部发生光线与球相撞,以此类堆。光线在球外向球内传播时有折射率之比,从球内传向球外则折射率之比与球外向球内是互为倒数的。

我们来看代码:

float iSphereOutside(float3 ro, float3 rd)
{float3 oc = ro - make_float3(sphere);float b = dot(oc, rd);float c = dot(oc, oc) - sphere.w * sphere.w; float h = b*b - c; if (h < 0.0)return -1.0;float t = (-b - sqrt(h)); return t;
}float iSphereInside(float3 ro, float3 rd)
{float3 oc = ro - make_float3(sphere);float b1 = -dot(oc, rd);float c2 = dot(oc, oc) - b1 * b1;float b2 = sqrt(sphere.w*sphere.w - c2);return b1+b2;
}RT_PROGRAM void intersect_compute(int primIdx)
{float3 O = ray.origin - make_float3(sphere);float O_dot_O = dot(O, O);float refraction_index = 1.0;float t = -1;float3 n;if(O_dot_O > (sphere.w * sphere.w + scene_epsilon)){t = iSphereOutside(ray.origin, ray.direction);n = normalize(ray.origin + t*ray.direction - make_float3(sphere));//空气到玻璃prd_radiance.refraction_index = 1.46;}else{//起点在球内则有且只有一个交点t = iSphereInside(ray.origin, ray.direction);n = normalize(make_float3(sphere)-(ray.origin + t*ray.direction) );//玻璃到空气中prd_radiance.refraction_index = 0.684;}if (t > 0){if (rtPotentialIntersection(t)){float3 hit_p = ray.origin + t * ray.direction;//在法线方向上求出一个微小的偏移,得出该点的球内外近点geometric_normal = n;float3 offset = normalize(geometric_normal) * scene_epsilon;//球外点front_hit_point = hit_p + offset;//球内点back_hit_point = hit_p - offset;rtReportIntersection(0);}}
}

其中iSphereInside和iSphereOutside计算视点在球内和球外时与球的最近的交点。注意法线的方向也不相同,在球内的交点法线的方向是指向球心的,在上面代码中n的求解的不同反映到了这一点。沿法线的方向我们取一个极小的offset,用来计算撞击点球外和球内的点。球内的点用来做折射,球外的点可以用来做反射。有个偏移是避免再次与球相撞。

同样我们对球内和球外折射率也做了不同的设置。

最终我们在absGlass.cu中实现了玻璃的完全折射与反射的材质。以下图分另是代码做了拆分时不同的渲染效果。

上图左一是只有折射的效果。左二是:即有折射又有反射的效果。

第二行左一是对的折射赋了个颜色值,模拟有颜色的玻璃。左二是反射和折射都设置了颜色。

【OptiX】第6个示例 折射,玻璃材质相关推荐

  1. 虚幻4皮肤材质_虚幻4渲染编程(材质编辑器篇)【第六卷:各向异性材质amp;玻璃材质】...

    My blog directory: YivanLee:专题概述及目录​zhuanlan.zhihu.com Introduction: 各向异性材质 玻璃材质 材质编辑器篇的很多效果都非常简单,可以 ...

  2. unity和ue4里面的玻璃材质笔记

    unity直接做带模拟折射的材质需要写shader,比较麻烦 这里使用unity3d 使用shaderforge制作一个简单的玻璃材质 基本节点如下 还有一种方式是使用grab制作 也就是对于shad ...

  3. Unity3D中简单地应用玻璃材质

    最近在学习Unity3D.发现Unity3D中的玻璃效果要用到Shader才能实现.虽然简单学习了一下能看懂Shader的结构了,但要自己写一个实现自己想要的效果的Shader暂时还无能为力.这个要么 ...

  4. threeJS材质,添加透明材质、材质不拉伸、玻璃材质

    添加透明材质,比如玻璃, transparent: true, //纹理加载器const textureLoader = new THREE.TextureLoader();const menColo ...

  5. 在 3ds Max 中创建逼真的玻璃材质

    推荐: NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 尽管本教程基于 3ds Max,但相同的设置适用于许多其他 3D 产品. 注意:单击每个步骤中的缩略图可查看更大的屏幕截图,其中包括视口 ...

  6. ue4玻璃材质_UE4-材质

    本文中,我们将首先讨论基于物理的渲染,什么是材质域,什么是材质,什么是材质实例,什么是主材质,我们将讨论材质的一些建议和禁忌.最后,我们将了解一些材质概念,你可以将其用于各类项目中的材质. 1.什么是 ...

  7. 【猫猫的Unity Shader之旅】之玻璃材质

    今天我们用学过的Shader知识实现一个简单的玻璃材质. 首先,玻璃是半透明的 玻璃最主要的特点就是它是透明的,不同的玻璃有不同的不透明度,水杯的透明度比较低,而装药品的棕色玻璃瓶不透明度就比较高.当 ...

  8. CityEngine制作玻璃材质反光效果

    当我们走在城市的大街上,经常会看到很多栋写字楼,其外墙大多都是玻璃材质的,使得建筑更有质感.在本文中,我们利用CityEngine实现玻璃材质反光效果.首先,需要确定做什么样的效果?一是玻璃效果(即透 ...

  9. 揭秘:保养品包装有玄机 玻璃材质最安全

    导读:保养品装盛的容器,与质量.卫生.取用.保存皆息息相关.对消费者来说,除了欣赏品牌的美学与创意之外,更要知道怎么挑选最适合的包装材质来保障保养品的质量,还要学会怎么使用与保存,才能让擦在脸上的保养 ...

最新文章

  1. 论文被scoop(抢先发表)是怎样一种体验?
  2. 浅析 Servlet 执行原理
  3. python opencv 录制视频_OpenCV Python 录制视频
  4. SpringMVC中@ResponseBody的相关注意点
  5. 喜欢用Block的值得注意-Block的Retain Cycle的解决方法
  6. 百度贴吧10亿量级LAMP架构分享
  7. usbserialcontroller驱动安装不了_win10-有NVIDIA独显提示未安装控制面板的离线安装方式...
  8. CSS中的margin、border、padding区别 CSS padding margin border属性详解
  9. Geoserver 发布 shp文件
  10. OpenCV——无法打开“opencv2/opencv.hpp”文件
  11. 卡西欧函数计算机广告词,卡西欧函数计算器,终身学习如有神助!
  12. mysql开发技巧笔记
  13. 单词记忆 词根词缀记忆 总结
  14. RC / RL串联电路计算
  15. 【Java】Maven使用笔记
  16. 【Luat-esp32c3】4.3 文件系统——加载jpeg图片并拆包
  17. Linux设置自动关机
  18. 金蝶K3 WISE BOM多级展开_BOM成本表
  19. 【力扣动态规划基础专题】:509. 斐波那契数 70. 爬楼梯 746. 使用最小花费爬楼梯 62. 不同路径 63. 不同路径 II 343. 整数拆分 96. 不同的二叉搜索树
  20. 隆重纪念鲁宾逊诞辰,不走样,不离谱

热门文章

  1. 我跟Python的孽缘
  2. ClickHouse基本语法及常见存储引擎
  3. 什么是火起来的“宅经济”,重庆阿尔克互联网技能帮扶学习,进入互联网
  4. 抖音xlog算法解析
  5. 抽丝拨茧——EventBus源码解析
  6. 图片的增强之-裁剪、旋转、放缩
  7. (个人解题思路系列)五子棋
  8. 云耀服务器 NumPy安装 完整过程
  9. python分三行将你的学号姓名班级_python第三次作业——叶耀宗
  10. python乘法函数_乘积(python乘法函数)