Shader学习第六篇:Lambert (兰伯特)光照模型
漫反射的定义
漫反射是投射在粗糙表面上的光向各个方向反射的现象。当一束平行的入射光线射到粗糙的表面时,表面会把光线向着四面八方反射,所以入射线虽然互相平行,由于各点的法线方向不一致,造成反射光线向不同的方向无规则地反射,这种反射称之为“漫反射”或“漫射”。这种反射的光称为漫射光。
Lambert定律
漫反射光的强度近似地服从于Lambert定律,即漫反射光的光强与表面法线和光源方向之间的夹角的余弦成正比。
原理公式:diffuse = I*cosθ;
diffuse:反射光线的的光强;
I:入射光线的光强,方向如上图所示;
cosθ:光源方向和该顶点法线的余弦,光源方向 · 法线方向,cosθ = dot(L,N);
在Unity中当颜色值小0时会按0处理,所以我们最后的数学表达式为:diffuse = I*max(0,dot(L,N));
在Unity Shader
Shader "My/03_1 shader"{Properties{_Diffuse("Diffuse",Color) = (1,1,1,1)}SubShader{Pass{CGPROGRAM#include "Lighting.cginc"//引入灯光库#pragma vertex vert#pragma fragment fragfixed4 _Diffuse;//application to vertexstruct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 position:SV_POSITION;float3 color:COLOR;};v2f vert(a2v v){v2f f;f.position = UnityObjectToClipPos(v.vertex);//顶点转为裁剪空间fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//环境光fixed3 light_dir = normalize(_WorldSpaceLightPos0.xyz);//归一化光源的方向fixed3 normal_dir = normalize(mul(v.normal,(float3x3)unity_WorldToObject));//先把法线方向转为世界空间,归一化法线方向//兰伯特光照模型,直射光颜色*max(0,cosƟ(光和法线的夹角)),cosƟ = 光源的方向(向量)点乘法线方向fixed3 diffuse = _LightColor0.rgb*max(0,dot(light_dir,normal_dir))*_Diffuse.xyz;//点成求cos,然后灯光颜色矩阵相乘获取漫反射光f.color = diffuse+ambient;return f;}fixed4 frag(v2f f):SV_Target{return fixed4(f.color,1);}ENDCG}}}
半兰伯特光照模型
把上面的效果应用到Unity中,可以看出不被光照射的背面是比较暗的,此时我们可以优化兰伯特光照模型,有人提出了半兰伯特光照模型。
由上面的公式diffuse = I*max(0,dot(N,L))
,可知dot(N,L)
的范围为-1~1,如果我们可以把范围调整为0 ~1,那么模型看起来会更亮些,我们优化下让 dot(L,N)*0.5+0.5
,这样范围就改为了0 ~1。
最后的公式为:
diffuse = I*max(0,dot(N,L)*0.5+0.5)
半兰伯特Shader程序
Shader "My/05 shader"{SubShader{Pass{CGPROGRAM#include "Lighting.cginc"//引入灯光库#pragma vertex vert#pragma fragment frag//application to vertexstruct a2v{float4 vertex:POSITION;float3 normal:NORMAL;};struct v2f{float4 position:SV_POSITION;float3 color:COLOR;};v2f vert(a2v v){v2f f;f.position = UnityObjectToClipPos(v.vertex);//顶点转为裁剪空间fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;//环境光fixed3 light_dir = normalize(_WorldSpaceLightPos0.xyz);//归一化灯光方向fixed3 normal_dir = normalize(mul(v.normal,(float3x3)unity_WorldToObject));//先把法线方向转为世界空间,归一化法线方向//半兰伯特光照模型fixed3 diffuse = _LightColor0.rgb*max(0,(dot(light_dir,normal_dir)*0.5+0.5));//点成求cos,然后灯光颜色矩阵相乘获取漫反射光f.color = diffuse+ambient;return f;}fixed4 frag(v2f f):SV_Target{return fixed4(f.color,1);}ENDCG}}}
从相同的视角来观察两个模型,效果对比如下:
Shader学习第六篇:Lambert (兰伯特)光照模型相关推荐
- shader基础学习摘要(二) 兰伯特光照模型
在第6.4节中,书中给出了计算基本光照模型中漫反射光部分的计算公式分别表示为: 目录 漫反射模型 逐像素光照(逐顶点光照改进版) 逐顶点光照(兰伯特原版) 半兰伯特光照模型 漫反射模型 兰伯特定律:反 ...
- Unity shader学习-漫反射-兰伯特光照模型和半兰伯特光照模型
兰伯特漫反射公式:Diffuse = 直射光颜色 *物体颜色* max(0,cos夹角(光和法线的夹角) ) 下面给出顶点漫反射代码: Shader "Unlit/005" { ...
- Unity Shader漫反射光照模型与半兰伯特光照模型
文章目录 一.基础光照模型中漫反射部分的计算公式 二.逐顶点光照实现 逐顶点代码 逐顶点效果图 三.逐像素光照模型实现 逐像素代码 逐像素效果图 四.半兰伯特光照模型实现 广义半兰伯特光照模型公式 半 ...
- 【Unity Shader】(2)半兰伯特模型 构建光照
在unity的Shader中使用半兰伯特模型来构建光照 在认识半兰伯特模型之前,建议查看一下我之前的兰伯特模型构建光照 兰伯特光照模型 半兰伯特光照模型 由于兰伯特模型的计算公式仅截取了[0,1]的光 ...
- 庄懂老师TA学习笔记 - 半兰伯特光照模型
先看一下兰伯特光照模型的公式 Max(0, nDir ·lDir) 通过公式我们知道,当法线方向和光照方向的反方向的角度大于90度时,点乘就会出现负数的结果,所以我们使用与0取最大值来排除掉这些没有实 ...
- 兰伯特光照模型(Lambert Lighting)和半兰伯特光照模型(Half-Lanbert)
关于漫反射 光打到凹凸不平的平面上,光线会被反射到四面八方,被称为漫反射 关于这种模型,由于光线由于分散,所以进入人眼的光线强度和观察角度没有区别 在A点和B点接收到的光线强度是一样的 在漫反射下,光 ...
- 9.半兰伯特光照模型
前情提要:前面一节的漫反射实际上是根据兰伯特光照模型来进行实现的 但这种做法有个缺点就是顶点法线和光的夹角大于90度的时候的成色是完全黑的这和我们生活中见到的事物是不一样的.所以就有了新的光照模型-- ...
- 伪兰伯特光照模型处理阴影过渡
默认shader的光照过渡太明显,不够柔和,使用伪兰伯特光照模型进行处理 伪兰伯特 默认材质 Shader "Custom/SimulateLambert" {Properties ...
- 光照模型-兰伯特光照模型
兰伯特光照模型理论基础
最新文章
- navicat的使用
- 使用spring-loaded开源项目,实现java程序和web应用的热部署
- 阿里巴巴CEO马云最新超经典哲学语录
- 全文检索引擎Solr系列——Solr核心概念、配置文件
- Ubuntu下VIM使用指南
- VC的若干实用小技巧
- #20071-[NOIP2020模拟赛B组Day6]礼物购买【二分】
- android 圆形边框填充颜色,如何在android中表示多种颜色的圆形边框
- Werkzeug routing
- python远程同步文件_Python实现的远程文件自动打包并下载功能示例
- 淘淘商城规格参数列表显示
- JavaScript介绍及视频教程
- CCS编译 报警#190-D enumerated type mixed with another type
- Typora 段落如何快速首行缩进两个字符
- hp服务器系统降级,HP 服务器firmware 升级方法.pdf
- 从“靠山吃山,靠水吃水”到守望“绿水青山”
- 批处理为win7桌面添加计算机图标,win7桌面图标不见了图文解决方案
- Springboot毕业设计毕设作品,黑白图片和上色处理系统 开题报告
- 程序员在十年后还会有现在的收入吗?
- 迈向更灵活,贝壳 OLAP 平台架构演进历程