//10.1.5,菲尼尔反射
Shader "Unlit/Chapter10-Fresnel"
{Properties{//物体颜色_Color("Color Tint",Color) = (1,1,1,1)//菲尼尔反射强度_FresnelScale("Fresnel Scale",Range(0,1))=0.5//模拟反射的环境映射纹理_Cubemap("Reflection Cubemap",Cube) = "_Skybox"{}}SubShader{//渲染类型=不透明  队列=几何Tags{ "RenderType" = "Opaque" "Queue" = "Geometry" }Pass{//光照模式=向前渲染Tags{ "LightMode" = "ForwardBase" }CGPROGRAM//定义顶点片元
#pragma vertex vert
#pragma fragment frag//确保光照衰减等光照变量可以被正确赋值
#pragma multi_compile_fwdbase//包含引用的内置文件
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"//声明属性变量fixed4 _Color;fixed4 _ReflectColor;float _FresnelScale;//cube 属性用 samplerCUBE 来声明samplerCUBE _Cubemap;//定义输入结构体struct a2v{float4 vertex : POSITION;float3 normal:NORMAL;};//定义输出结构体struct v2f{float4 pos:SV_POSITION;fixed3 worldNormal : TEXCOORD0;float3 worldPos:TEXCOORD1;fixed3 worldViewDir : TEXCOORD2;fixed3 worldRefl : TEXCOORD3;//添加内置宏,声明一个用于阴影纹理采集的坐标,参数是下一个可用的插值寄存器的索引值SHADOW_COORDS(4)};//顶点着色器v2f vert(a2v v) {v2f o;//转换顶点坐标到裁剪空间o.pos = UnityObjectToClipPos(v.vertex);//转换法线到世界空间o.worldNormal = UnityObjectToWorldNormal(v.normal);//转换顶点坐标到世界空间o.worldPos = mul(unity_ObjectToWorld, v.vertex);//获取世界空间下的视角方向o.worldViewDir = UnityWorldSpaceViewDir(o.worldPos);//compute the reflect dir in world space(计算世界空间中的反射方向)//用CG的reflect函数来计算该处顶点的反射方向       reflect(物体反射到摄像机的光线方向,法线方向)//物体反射到摄像机的的光线方向,可以由光路可逆的原则反向求得,o.worldRefl = reflect(-o.worldViewDir, o.worldNormal);//o.worldRefl = reflect(-normalize(o.worldViewDir), normalize(o.worldNormal));//内置宏,计算上一步中声明的阴影纹理坐标TRANSFER_SHADOW(o);return o;}//片元着色器fixed4 frag(v2f i) :SV_Target{//获取归一化的法线fixed3 worldNormal = normalize(i.worldNormal);//获取归一化的光线方向//fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);//获取归一化的视角方向//fixed3 worldViewDir = normalize(i.worldViewDir);fixed3 worldViewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);//获取环境光fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;//漫反射计算  =光照颜色*物体颜色*大于零的 法线和光照方向的点积fixed3 diffuse = _LightColor0.rgb*_Color.rgb*max(0, dot(worldNormal, worldLightDir));//在世界空间中使用折射方向访问立方体贴图fixed3 reflection = texCUBE(_Cubemap, i.worldRefl).rgb;//光照衰减程度UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);//使用Schlick菲尼尔近似式计算fresnel变量fixed fresnel = _FresnelScale + (1 - _FresnelScale)*pow(1 - dot(worldViewDir, worldNormal), 5);//环境光+插值(漫反射,反射,0到1之间的菲尼尔)*光照衰减程度return fixed4(ambient + lerp(diffuse, reflection, saturate(fresnel))*atten, 1.0);}ENDCG}}FallBack "Reflective/VertexLit"
}

实时渲染中,会用 菲尼尔反射(Fresnel reflection)来根据视角方向控制反射程度

Schlick菲尼尔近似式:

其中是一个反射系数,用于控制反射的强度,v是视角方向,n是表面法线。

Empricial菲尼尔近似式:

其中 bias scale power 是控制项。

使用上面的菲尼尔近似式可以在外边界模拟反射光强和折射光强/漫反射光强之间的变化。

在上面的代码中使用的是Schlick 菲尼尔来计算,使用它来混合漫反射和反射,一些实现也会直接把frensnel和反射光照相乘后叠加到漫反射光照上,模拟边缘光效果。

菲尼尔反射 【Unity Shader 入门精要10.1.5】相关推荐

  1. 《Unity Shader入门精要》笔记:高级篇(3)以及扩展

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  2. Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照

    转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...

  3. Unity Shader入门精要第七章 基础纹理之遮罩纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.实践 参考 前言 遮罩纹理(mask texture)是本章要介绍的最后一种纹理,它非常有用,在很多商业游戏中 都可以见到它的身影. ...

  4. 《Unity Shader 入门精要》读书笔记

    <Unity Shader 入门精要>读书笔记 --记录一下自己看书时遇到的一下困惑的地方和自己的一些想法,愿明天的我更加强大 1.要正确获得阴影和光照衰减效果,需要#pragma mul ...

  5. Unity Shader入门精要学习笔记 - 第7章 基础纹理

    转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图"黏"在模型表面,逐纹素地控制 ...

  6. Unity Shader入门精要学习笔记 - 第14章 非真实感渲染

    Unity Shader入门精要学习笔记 - 第14章 非真实感渲染 本系列为UnityShader入门精要读书笔记总结, 原作者博客链接:http://blog.csdn.net/candycat1 ...

  7. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  8. 《Unity Shader入门精要》笔记:初级篇(2)

    本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...

  9. Unity Shader入门精要第七章 基础纹理渐变纹理

    Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.渐变纹理是什么 参考 前言 尽管在一开始,我们在渲染中使用纹理是为了定义一个物体的颜色,但后来人们发现,纹理 其实可以用于存储任何表 ...

最新文章

  1. Java反射,从0开始
  2. 在xml文件中使用typeAliases标签报错The content of element type “configuration“ must match “(properties?,setting
  3. java.lang.IllegalArgumentException: URLDecoder异常解决
  4. 求两个数组中不同的元素
  5. 3: Java虚拟机体系结构
  6. Java 并发编程之内置锁 synchronized
  7. ASP.NET页面生命周期概述(转载)
  8. Unity游戏画面品质增强,shader和贴图
  9. linux命令行彩蛋,技术|11个无用而有趣的Linux终端彩蛋
  10. linux服务器开启公网访问_如何在外网用SSH访问内网LINUX服务器?
  11. [转][darkbaby]任天堂传——失落的泰坦王朝(下)
  12. 七夕到了 —— 属于 Java 的浪漫,拿去吧~ 祝表白成功
  13. 4399怎么修复游戏服务器,[ 服务器 ]4399官方服务器(改ip了)
  14. OLED显示字符的大小与PCtoLCD2002生成字模
  15. 使用Echarts将Excel数据转换成色彩地图HTML小工具
  16. HTML Table之展开收起
  17. 如何设计一个简单的网页
  18. 高级计算机维修员+职业资格证书查询,国家职业资格证书查询(全国联网)
  19. 普通交换机能否改成PoE供电的?
  20. 【实用工具】技术人如何写好英文论文?

热门文章

  1. 2013-BIT程序设计 14.古罗马的加法
  2. centos-linux 查看网关
  3. 微信小程序开发工具调试界面鼠标看不见
  4. vue-element页面说明文档
  5. python-restful-02-组件(序列化\认证)
  6. 【雕爷学编程】Arduino动手做(137)---MT8870语音解码
  7. mysql日期隐式转换_MySQL 隐式转换 | 剑花烟雨江南
  8. Python SimpleITK提取三维Canny Sobel边界代码
  9. 10分钟 GET 新技能 - 正则表达式
  10. html 上传图片,拖拽图片,并在页面显示