菲尼尔反射 【Unity Shader 入门精要10.1.5】
//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】相关推荐
- 《Unity Shader入门精要》笔记:高级篇(3)以及扩展
本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...
- Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...
- Unity Shader入门精要第七章 基础纹理之遮罩纹理
Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.实践 参考 前言 遮罩纹理(mask texture)是本章要介绍的最后一种纹理,它非常有用,在很多商业游戏中 都可以见到它的身影. ...
- 《Unity Shader 入门精要》读书笔记
<Unity Shader 入门精要>读书笔记 --记录一下自己看书时遇到的一下困惑的地方和自己的一些想法,愿明天的我更加强大 1.要正确获得阴影和光照衰减效果,需要#pragma mul ...
- Unity Shader入门精要学习笔记 - 第7章 基础纹理
转自 冯乐乐的 <Unity Shader 入门精要> 纹理最初的目的就是使用一张图片来控制模型的外观.使用纹理映射技术,我们可以把一张图"黏"在模型表面,逐纹素地控制 ...
- Unity Shader入门精要学习笔记 - 第14章 非真实感渲染
Unity Shader入门精要学习笔记 - 第14章 非真实感渲染 本系列为UnityShader入门精要读书笔记总结, 原作者博客链接:http://blog.csdn.net/candycat1 ...
- Unity Shader入门精要学习笔记 - 第14章非真实感渲染
转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...
- 《Unity Shader入门精要》笔记:初级篇(2)
本篇博客主要为个人学习所编写读书笔记,不用于任何商业用途,以及不允许任何人以任何形式进行转载. 本篇博客会补充一些扩展内容(例如其他博客链接). 本篇博客还会提供一些边读边做的效果截图.文章内所有数学 ...
- Unity Shader入门精要第七章 基础纹理渐变纹理
Unity系列文章目录 文章目录 Unity系列文章目录 前言 一.渐变纹理是什么 参考 前言 尽管在一开始,我们在渲染中使用纹理是为了定义一个物体的颜色,但后来人们发现,纹理 其实可以用于存储任何表 ...
最新文章
- Java反射,从0开始
- 在xml文件中使用typeAliases标签报错The content of element type “configuration“ must match “(properties?,setting
- java.lang.IllegalArgumentException: URLDecoder异常解决
- 求两个数组中不同的元素
- 3: Java虚拟机体系结构
- Java 并发编程之内置锁 synchronized
- ASP.NET页面生命周期概述(转载)
- Unity游戏画面品质增强,shader和贴图
- linux命令行彩蛋,技术|11个无用而有趣的Linux终端彩蛋
- linux服务器开启公网访问_如何在外网用SSH访问内网LINUX服务器?
- [转][darkbaby]任天堂传——失落的泰坦王朝(下)
- 七夕到了 —— 属于 Java 的浪漫,拿去吧~ 祝表白成功
- 4399怎么修复游戏服务器,[ 服务器 ]4399官方服务器(改ip了)
- OLED显示字符的大小与PCtoLCD2002生成字模
- 使用Echarts将Excel数据转换成色彩地图HTML小工具
- HTML Table之展开收起
- 如何设计一个简单的网页
- 高级计算机维修员+职业资格证书查询,国家职业资格证书查询(全国联网)
- 普通交换机能否改成PoE供电的?
- 【实用工具】技术人如何写好英文论文?