Unity Shader漫反射光照模型与半兰伯特光照模型
文章目录
- 一、基础光照模型中漫反射部分的计算公式
- 二、逐顶点光照实现
- 逐顶点代码
- 逐顶点效果图
- 三、逐像素光照模型实现
- 逐像素代码
- 逐像素效果图
- 四、半兰伯特光照模型实现
- 广义半兰伯特光照模型公式
- 半兰伯特光照模型代码实现
- 半兰伯特效果图
上一次我们学习了如何实现一个简单的顶点/片元着色器,今天来学习一下漫反射光照模型以及半兰伯特光照模型的实现。
一、基础光照模型中漫反射部分的计算公式
其中n为模型表面法线,l为光源方向
二、逐顶点光照实现
在unity中的操作步骤与上一次相同
逐顶点代码
Shader "Unity Shader Book/Chapter6-DiffuseVertexLevel"
{Properties{_Diffuse("Diffuse",Color)=(1,1,1,1)}SubShader{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag #include "Lighting.cginc"fixed4 _Diffuse;struct a2v {float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f {float4 pos:SV_POSITION;fixed3 color:COLOR;};v2f vert(a2v v) {v2f o;//利用MVP矩阵将顶点位置从模型空间转换到裁剪空间o.pos = UnityObjectToClipPos(v.vertex);//获取环境光fixed3 Ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;//将顶点法线坐标从模型空间转到世界空间坐标下fixed3 worldNormal=normalize(mul(v.normal,(float3x3)unity_WorldToObject));//获取光源方向fixed3 worldLight=normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse=_LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLight));o.color=Ambient+diffuse;return o; }fixed4 frag(v2f i) : SV_Target{return fixed4(i.color,1.0);}ENDCG} }FallBack "Diffuse"
}
逐顶点效果图
从该效果图中我们可以看出,虽然整体效果还不错,但是一旦我们仔细观察就会发现在暗面与亮面的交汇处有一些明细的锯齿,接下来我们可以使用逐像素的方式来实现该光照模型,这一方法能够很好改善模型的锯齿效果。
三、逐像素光照模型实现
要实现逐像素光照模型,我们只需在逐顶点的代码中进行修改
逐像素代码
Shader "Unity Shader Book/Chapter6-DiffusePixelLevel"
{Properties{_Diffuse("Diffuse",Color)=(1,1,1,1)}SubShader{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag #include "Lighting.cginc"fixed4 _Diffuse;struct a2v {float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f {float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);return o;}fixed4 frag(v2f i) : SV_Target{fixed3 Ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse=_LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal,worldLightDir));fixed3 color=Ambient+diffuse;return fixed4(color,1.0);}ENDCG}}FallBack "Diffuse"
}
逐像素效果图
通过该效果图,我们可以明显看出在亮面与暗面的交界处明显平滑了许多,但同样的逐像素光照同样也有一些缺点,就是它的阴影部分几乎是全黑的,没有亮度的变化,为此我们可以使用一种新的模型,半兰伯特光照模型。
四、半兰伯特光照模型实现
广义半兰伯特光照模型公式
通过该公式我们可以看出该模型没有用max操作来防止nl的点积为负值,而是对点积的结果进行α倍的缩放再加上一个β值的偏移,其中在大多数情况下α和β的值均为0.5.
半兰伯特光照模型代码实现
Shader "Unity Shader Book/Chapter6-DiffuseHalfLambertLevel"
{Properties{_Diffuse("Diffuse",Color)=(1,1,1,1)}SubShader{Pass{Tags{"LightMode"="ForwardBase"}CGPROGRAM#pragma vertex vert#pragma fragment frag #include "Lighting.cginc"fixed4 _Diffuse;struct a2v {float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f {float4 pos:SV_POSITION;float3 worldNormal:TEXCOORD0;};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.worldNormal=mul(v.normal,(float3x3)unity_WorldToObject);return o;}fixed4 frag(v2f i) : SV_Target{fixed3 Ambient=UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal=normalize(i.worldNormal);fixed3 worldLightDir=normalize(_WorldSpaceLightPos0.xyz);fixed halfLambert=dot(worldNormal,worldLightDir)*0.5+0.5;fixed3 diffuse = _LightColor0.rgb*_Diffuse.rgb*halfLambert;fixed3 color=Ambient+diffuse;return fixed4(color,1.0);}ENDCG}}FallBack "Diffuse"
}
半兰伯特效果图
半兰伯特光照模型的阴影部分是由亮逐渐变暗具有层次感,该光照模型的效果相对于上面两种模型更加贴近于真实关照模型。
Unity Shader漫反射光照模型与半兰伯特光照模型相关推荐
- Unity shader学习-漫反射-兰伯特光照模型和半兰伯特光照模型
兰伯特漫反射公式:Diffuse = 直射光颜色 *物体颜色* max(0,cos夹角(光和法线的夹角) ) 下面给出顶点漫反射代码: Shader "Unlit/005" { ...
- 9.半兰伯特光照模型
前情提要:前面一节的漫反射实际上是根据兰伯特光照模型来进行实现的 但这种做法有个缺点就是顶点法线和光的夹角大于90度的时候的成色是完全黑的这和我们生活中见到的事物是不一样的.所以就有了新的光照模型-- ...
- 庄懂老师TA学习笔记 - 半兰伯特光照模型
先看一下兰伯特光照模型的公式 Max(0, nDir ·lDir) 通过公式我们知道,当法线方向和光照方向的反方向的角度大于90度时,点乘就会出现负数的结果,所以我们使用与0取最大值来排除掉这些没有实 ...
- 兰伯特光照模型(Lambert Lighting)和半兰伯特光照模型(Half-Lanbert)
关于漫反射 光打到凹凸不平的平面上,光线会被反射到四面八方,被称为漫反射 关于这种模型,由于光线由于分散,所以进入人眼的光线强度和观察角度没有区别 在A点和B点接收到的光线强度是一样的 在漫反射下,光 ...
- 【Unity Shader】(2)半兰伯特模型 构建光照
在unity的Shader中使用半兰伯特模型来构建光照 在认识半兰伯特模型之前,建议查看一下我之前的兰伯特模型构建光照 兰伯特光照模型 半兰伯特光照模型 由于兰伯特模型的计算公式仅截取了[0,1]的光 ...
- shader基础学习摘要(二) 兰伯特光照模型
在第6.4节中,书中给出了计算基本光照模型中漫反射光部分的计算公式分别表示为: 目录 漫反射模型 逐像素光照(逐顶点光照改进版) 逐顶点光照(兰伯特原版) 半兰伯特光照模型 漫反射模型 兰伯特定律:反 ...
- Shader学习3——半兰伯特
半兰伯特其实就是把暗的地方提亮了一些,在数值上就是获取到的光源强度* 0.5 + 0.5,也就是原来是0的会变成0.5,原来是1的还是1. 半兰伯特:漫反射颜色 = 光源颜色 x 材质的漫反射颜色 x ...
- U3D Shader半兰伯特模型
兰伯特光照模型--在平面某点漫反射光的光强与该反射点的法向量和入射光角度的余弦值成正比.逐像素光照可以得到更加哦平滑的光照效果.但是,即便使用了逐像素漫反射光照,有一个问题仍然存在.在光照无法达到的区 ...
- 标准光照模型-半兰伯特模型
Valve公司在<半条命>中提出了一种技术,叫做半兰伯特光照模型 通过这个方式,可以把点积的结果从[-1,1]到[0,1]范围内,也就是说,对于模型的背光面,从原模型中点积结果会映射到同一 ...
最新文章
- 【uni-app】uParse 富文本解析插件遇到长图、大图宽高比异常问题
- javascript --- Sortable一个拖拽的接口
- python爬虫豆瓣250_python爬虫二 爬取豆瓣Top250上
- yii mysql gii_Yii Gii使用
- java异常处理方式推荐做法_谈谈Java异常处理这件事儿
- Recyclerview 显示多种布局 demo
- hexeditor 复制二进制值_MySQL并发复制演进
- 1.[精通Hibernate笔记]Hibernate简介
- 有感于乐清老村长惨死轮下
- JVM性能调优监控工具详解
- 基于pytorch训练的VGG16神经网络模型完成手写数字的分割与识别
- 方差分析表和回归分析表的那些浆糊糊
- 10x 程序员工作法 - 划重点 | “自动化”主题的重点内容回顾汇总
- 《财富》推荐的75本必读书 !!推荐看看!受益匪浅
- 赛元SC92F7250单片机开发
- vs code语言模式自动检测设置
- 大数据平台架构实战(二)IntelliJ IDEA搭建hadoop
- 采集页面之后css布局混乱之rem适配布局
- python从后面删除重复项_如何从Python列表中删除重复项
- Unity3D 2021.1.1F1。更新与下载。