CG之菲涅尔效果简单实现

  菲涅尔效果,指当光到达两种材质的接触面时,一些光在接触面的表面被反射出去,而另一部分光将发生折射穿过接触面。

  现在要用shader来实现这种效果,如果要精确地描述这种底层的物理,其计算公式是非常复杂的,性能消耗也比较大。我们的目的是使创建的图像看上去真实,因此我们不使用菲涅尔公式本身,而是使用以下经验公式,它能够用非常少的计算获得很好的效果。

reflectionCoefficient = max(0, min(1, bias + scale * pow(1 + dot(I,N), power)))

finalColor = reflectionCoefficient * reflectedColor + (1 - reflectionCoefficient ) * refractedColor

在unity3d中的渲染效果如下:

如用shaderLab写的一个例子shader如下:

 1 Shader "Custom/Test"
 2 {
 3     Properties
 4     {
 5         _Cube("Cube", Cube) = "white" {}
 6         _EtaRatio("Eta ratio", float) = 0.8
 7         _FresnelPower("Fresnel power", float) = 2
 8         _FresnelScale("Fresnel scale", float) = 1
 9         _FresnelBias("Fresnel bias", float) = 0
10     }
11
12     SubShader
13     {
14         Tags
15         {
16             "RenderType" = "Opaque"
17         }
18
19         Pass
20         {
21             CGPROGRAM
22             #pragma vertex Vert
23             #pragma fragment Frag
24
25             uniform samplerCUBE _Cube;
26             uniform float _EtaRatio;
27             uniform float _FresnelPower;
28             uniform float _FresnelScale;
29             uniform float _FresnelBias;
30
31             struct AppData
32             {
33                 float4 pos : POSITION;
34                 float3 nor : NORMAL;
35             };
36
37             struct V2F
38             {
39                 float4 pos : SV_POSITION;
40                 float reflectionFactor : Color;
41                 float3 r : TEXCOORD0;
42                 float3 t : TEXCOORD1;
43             };
44
45             V2F Vert(AppData vi)
46             {
47                 V2F fi;
48                 fi.pos = mul(UNITY_MATRIX_MVP, vi.pos);
49
50                 float3 worldPos = mul(_Object2World, vi.pos.xyz);
51                 float3 n = mul(_Object2World, vi.nor);
52                 float3 i = worldPos - _WorldSpaceCameraPos.xyz;
53                 fi.r = reflect(i, n);
54
55                 i = normalize(i);
56                 n = normalize(n);
57                 fi.t = refract(i, n, _EtaRatio);
58
59                 fi.reflectionFactor = _FresnelBias + _FresnelScale * pow(1 + dot(i, n), _FresnelPower);
60
61                 return fi;
62             }
63
64             float4 Frag(V2F fi) : Color
65             {
66                 float4 reflectC = texCUBE(_Cube, fi.r);
67                 float4 refractC = texCUBE(_Cube, fi.t);
68                 return lerp(refractC, reflectC, fi.reflectionFactor);
69             }
70
71             ENDCG
72         }
73     }
74 }

转载请注明出处: http://www.cnblogs.com/jietian331/p/5564901.html

时间: 2024-09-28 02:49:11

CG之菲涅尔效果简单实现的相关文章

菲涅尔效应(Fresnel Effect)

当光从一种具有折射率为的介质向另一种具有折射率为的介质传播时,在两者的交界处(通常称作界面)可能会同时发生光的反射和折射.菲涅尔方程描述了不同光波分量被折射和反射的情况.也描述了波反射时的相变. 如果你站在湖边,低头看脚下的水,你会发现水是透明的,反射不是特别强烈:如果你看远处的湖面,你会发现水并不是透明的,但反射非常强烈.这就是"菲涅尔效应". 简单的讲,就是视线垂直于表面时,反射较弱,而当视线非垂直表面时,夹角越小,反射越明显.如果你看向一个圆球,那圆球中心的反射较弱,靠近边缘较强

迪菲.赫尔曼(Diffie–Hellman)密钥交换算法

迪菲.赫尔曼算法是通信线路不安全情况下,交换密钥的一个算法,应用于TLS协议中 首先说一下生成密钥的流程,我们有这样一种计算叫做求摸运算 mod, 比如:27 mod 17 = 10,也就是求余数的运算. 现在有两个通信者A和B,我们使用一种计算 假如我们这里选用 3 ^ x mod 17,A和B分别生成一个随机的整数,这个整数即为x,比如A是2,B是3,那么A使用2计算: 3^2 mod 17 = 9 ① B使用3计算: 3^3 mode 17 = 10 ② 然后A将9发送给B,B将10发送给

页面效果简单做(不断收集更新)

简介:有自己写的,也有网上看到的,即使是别人写的也会对其改动,或添加注释,并保持统一的编码风格,便于阅读.目标是不用库即可完成,简单做,能够阐述逻辑和原理清楚即可,因此可能考虑不是最周详的,包括跨浏览器的问题,如果你打算使用在项目中使用最好测试清楚,还可能要进一步修改之. 注意:打算提供在线例子的,但短时间内没有静态空间,所以例子的事情要稍等一阵子.已提供在线例子. 1.简易拖放效果 使用了 DOM 1 的方式登记事件,其实无必要 addEventListener,因为根据鼠标事件,同一时刻通常

Animation动画效果简单汇总

------------案例结构很复杂一步步来------------ 1.activity_main.xml(首先看启动界面布局文件,里面有2个button) <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width=&q

网页效果-简单的时间轴实现

之前在网上看到,有很多人写的时间轴效果,于是自己也模仿着写了写.以下贴出自己写的解决方法(横向轴与纵向轴). 简单的时间轴效果容易实现,但如果需要看起来有模有样,就需要对页面进行设计布置了. 1.利用Js加简单的界面布置,实现时间轴鼠标点击轮换图片效果(纵向). 实现思路:利用多个div加背景色做纵向时间轴的样式,用CSS进行定位布局(时间轴一般都相对于浏览器窗口位置进行定位,避免浮动),再加上相应的文字描述.(:after,:before等一样能实现其效果),最后在用Js添加一些简单的鼠标事件

毛玻璃效果简单实现

项目中需要运用到毛玻璃的效果.经过搜索查阅,踩了一些坑,找到了一条暂时可行的办法. 其中,核心的控件是使用RenderScript这个类,这个类属于jni类,在较低版本的Android系统中,是不具备它的相关方法的.所以我们只能使用support.v8里面的类.然而,support.v8并没有默认地放在新建工程中,因此我们需要自己去添加. 第一步:将D:\AndroidSdk\build-tools\23.0.1\renderscript\lib\packaged 目录下的armeabi-v7a

基于原生js的图片轮播效果简单实现

基本效果如下: 实现了三张图片自动轮播+按键点击切换的效果. 基本思想: 图片轮播的效果和老式电影院的胶片放映形式很相似,在老式的电影院放映中,使用长长的胶片记录影片,胶片上是按顺序排列的一系列图片,通过快速通过放映机放映口,使这些图片产生一个连贯的切换效果,形成了动态的影片.所以,这里图片轮播的形式也可以采用这种方式来形成动画效果. 形式如下图: (黑框即我们的最外层的容器,充当放映机的存在:绿框就是胶片,上面搭载着很多的图片:粉框内即我们要轮播的图片) 从上图出发,我们要做到图片轮播,那么只

仿淘宝分页按钮效果简单美观易使用的JS分页控件

分页按钮思想: 1.少于9页,全部显示 2.大于9页,1.2页显示,中间页码当前页为中心,前后各留两个页码 附件中有完整例子的压缩包下载.已更新到最新版本 先看效果图: 01输入框焦点效果 02效果 模仿淘宝的分页按钮效果控件kkpager  JS代码: Js代码   var kkpager = { //divID pagerid : 'div_pager', //当前页码 pno : 1, //总页码 total : 1, //总数据条数 totalRecords : 0, //是否显示总页数

jQuery效果 - 简单的手风琴效果

实现效果如图所示: html结构: <div class="item_box box10"> <div class="item_box_wp"> <div class="voice_2"> <ul> <li class="li1" id="li1"> <div class="fold" style="displa