在第6.4节中,书中给出了计算基本光照模型中漫反射光部分的计算公式分别表示为:

目录

  • 漫反射模型
    • 逐像素光照(逐顶点光照改进版)
    • 逐顶点光照(兰伯特原版)
    • 半兰伯特光照模型

漫反射模型

兰伯特定律:反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。

共由四个参数,从左到右依次为光源颜色、漫反射颜色、表面法线、单位矢量。

逐像素光照(逐顶点光照改进版)

完整注释的程序(逐像素光照)细节如下

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 6/Diffuse Pixel-Level" {Properties{_Diffuse("Diffuse", Color) = (1, 1, 1, 1)//便于可调颜色,为了可以使用该字段,需要后续与该字段存在一个类型相同,名称相同变量}SubShader{Pass {Tags { "LightMode" = "ForwardBase" }//LightMode标签在语法中应在pass语义块下,定义unity的光照流水线中的角色,这里定义了ForwardBase//在定义后,我们就可以得到一些unity内置光照变量,如_LightColor()CGPROGRAM#pragma vertex vert//告诉unity顶点着色器被命名为vert函数#pragma fragment frag//告诉unity片元着色器被命名为frag函数#include "Lighting.cginc"//包含内置库,以便后续使用,如_LightColor()fixed4 _Diffuse;//便于可调颜色,为了可以使用Properties字段,需要Pass语义块下定义该字段,名称类型相同/*然后我们定义了顶点着色器的输入和输出结构体(输出结构体同时也是片元着色器的输入结构体)*///输入结构体,顶点着色器常用struct a2v {float4 vertex : POSITION;//必要字段,模型空间中的顶点坐标,用vertex表示,通常类型是float4float3 normal : NORMAL;//定义法线名称为normal};//输出结构体,片元着色器常用struct v2f {float4 pos : SV_POSITION;//必要字段,裁剪空间中的顶点坐标,用变量pos表示,类型同POSITIONfloat3 worldNormal : TEXCOORD0;//有时TEXCOORD0可以换为COLOR/*当TEXCOORD0出现在a2v结构体中所代表的含义是表示第n+1组纹理坐标,如TEXCOORD0代表第一组纹理坐标,类型是float2或float4类型当TEXCOORD0出现在v2f结构体中所代表的含义是表示输出纹理坐标,但不是必须的*/};/*开始输入*/v2f vert(a2v v) {v2f o;//o代表着色器//将模型空间转到裁剪空间o.pos = UnityObjectToClipPos(v.vertex);/*将法线转移到世界空间.公式:世界法线 = 模型法线向量 * 法线转换矩阵,其中法线转换矩阵不能使用顶点变换矩阵(float3*3)unity_ObjectToWorld,否则会出现法线无法正常缩放,因为法线缩放与常规缩放不同,法线变换矩阵是顶点变换矩阵的逆矩阵的转置,推导参见https://www.zhihu.com/question/400660113*/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);// 计算漫反射光照模型。模型公式:反射光=(入射光线颜色和强度·漫反射系数)max(0,法线向量·光源方向单位向量)fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));//显示在屏幕上的实际颜色=环境光+反射光fixed3 color = ambient + diffuse;//返回(R,G,B,D) D为透明度return fixed4(color, 1.0);}ENDCG}}FallBack "Diffuse"
}

以下两图分别是兰伯特逐像素光照模型(上)与环境光(下)的对比

逐顶点光照(兰伯特原版)

与逐像素光照类似
区别:(1)着色器的输出结构体v2f为color语义。
(2)顶点着色器需要光照模型。
(3)片元着色器无计算光照模型步骤。

// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'Shader "Unity Shaders Book/Chapter 6/Diffuse Vertex-Level" {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矩阵,unity5.0已优化api)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"
}

以下是逐顶点漫反射光照的对比图(上为逐顶点光照,下为无材质)



可见存在部分锯齿,逐像素模型更优。

半兰伯特光照模型

此模型是对计算方法与效果的改进,并无物理依据。使用此模型可以将n与l向量的点积范围从[-1,1]变为[0,1],这样既不用比较最大值,加快了运行速度,也为背光面提供了明暗的变化

修改逐像素光照模型frag函数即可

fixed4 frag(v2f i) : SV_Target {// Get ambient termfixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;// Get the normal in world spacefixed3 worldNormal = normalize(i.worldNormal);// Get the light direction in world spacefixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);// Compute diffuse termfixed halfLambert = dot(worldNormal, worldLightDir) * 0.5 + 0.5;fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambert;fixed3 color = ambient + diffuse;

从做到右依次为逐顶点,逐像素,半兰伯特。

总结:在需要表示游戏阴影的条件下优选逐像素光照模型,而半兰伯特光照模型,即使被遮挡,依然存在有层次光照,且计算也更有效率

shader基础学习摘要(二) 兰伯特光照模型相关推荐

  1. 庄懂老师TA学习笔记 - 半兰伯特光照模型

    先看一下兰伯特光照模型的公式 Max(0, nDir ·lDir) 通过公式我们知道,当法线方向和光照方向的反方向的角度大于90度时,点乘就会出现负数的结果,所以我们使用与0取最大值来排除掉这些没有实 ...

  2. shader基础学习摘要(三)高光反射

    高光反射 理论推导 代码实践 Phone光照模型 逐顶点 逐像素 Blinn-Phong光照模型 内置函数 理论推导 在6.2.4节中,我们给出了基本光照模型中高光反射部分的计算公式 高光反射求的夹角 ...

  3. Shader学习3——半兰伯特

    半兰伯特其实就是把暗的地方提亮了一些,在数值上就是获取到的光源强度* 0.5 + 0.5,也就是原来是0的会变成0.5,原来是1的还是1. 半兰伯特:漫反射颜色 = 光源颜色 x 材质的漫反射颜色 x ...

  4. Unity shader学习-漫反射-兰伯特光照模型和半兰伯特光照模型

    兰伯特漫反射公式:Diffuse = 直射光颜色 *物体颜色* max(0,cos夹角(光和法线的夹角) ) 下面给出顶点漫反射代码:   Shader "Unlit/005" { ...

  5. UE5 Shader基础学习笔记——13-20 DetailNormal/Smoothstep/Length/CeilFloorRound/DDXDDY/SinCos/Power

    UE5 Shader基础学习笔记--13-20 DetailNormal/Smoothstep/Length/CeilFloorRound/DDXDDY/SinCos/Power Lec13 Deta ...

  6. Unity Shader漫反射光照模型与半兰伯特光照模型

    文章目录 一.基础光照模型中漫反射部分的计算公式 二.逐顶点光照实现 逐顶点代码 逐顶点效果图 三.逐像素光照模型实现 逐像素代码 逐像素效果图 四.半兰伯特光照模型实现 广义半兰伯特光照模型公式 半 ...

  7. 【笔记】MySQL的基础学习(二)

    [笔记]MySQL的基础学习(二) MySQL 老男孩  一 视图 视图其实就是给表起个别名 1.创建视图 格式:CREATE VIEW 视图名称 AS SQL语句 CREATE VIEW v1 AS ...

  8. TCL/Tk基础学习(二)

    TCL/TK基础学习(二) 表达式 算术操作符 关系.逻辑.按位.选择操作符 函数 表达式 Tcl表达式由操作符.操作数.圆括号等构成.于C语言.verilog用法几乎相同. # 算术操作符.逻辑运算 ...

  9. Mendix敏捷开发零基础学习《二》-进阶(Microflow微流、表单验证、运算符、条件判断、数据嵌套、触发器、Debug问题跟踪、版本管理)

    目录结构 Mendix敏捷开发零基础学习<二> 一.Microflow微流 1.引言 2.常见的功能 3.微流可以做那些事情? 3.1 举例1(用微流打开新增页面) 3.2 举例2(用微流 ...

最新文章

  1. Python+OpenCV 图像处理系列(4)—— 图像像素的读写、算术运算、逻辑运算及像素的统计
  2. 用脚写字考上985!无臂硕士开学报到,宿舍设计太细节了……
  3. python使用numpy生成指定步长的浮点数序列
  4. 谁扛起张一鸣的游戏野心?
  5. 在Ubuntu上通过命令行安装Elisa KDE音乐播放器
  6. 二十万字C/C++、嵌入式软开面试题全集宝典五
  7. 数据结构算法——判断表达式中的括号是否匹配
  8. 已知ABAP tcode,需要查找assign了该tcode的PFCG role
  9. jQuery图片延迟加载插件jQuery.lazyload
  10. Java 复习笔记 异常Exception
  11. css的背景图片不显示,wepback打包时,css的背景图片显示不出来,求教!
  12. Icon资源详解[1]
  13. java常用类、最常用的包
  14. 论文笔记_S2D.70_2021_IEEE-RAL_CodeMapping:使用紧凑场景表示的稀疏SLAM的实时稠密建图
  15. APP社交类源代码分享直接上车
  16. 谭浩强《c语言程序设计》第五章第十六题 输出图案:空格和*搭配的循环
  17. 【NLP基础理论】 08 词汇语义学 Lexical Semantics
  18. SCI论文写作 -- 新手如何写第一篇sci
  19. 为Web登陆添加验证码功能
  20. Android Studio 关于android resource linking failed的报错解决方法

热门文章

  1. 〖Python自动化办公篇④〗- 文件自动化管理 - 文件查找与基于文件内容查找文件
  2. 公司网站建设的几点建议—竹晨网络
  3. Qt实现的一些小软件
  4. python中的socketserver模块与多线程
  5. python 英语分词_英文分词算法(Porter stemmer)
  6. 如何在虚拟机安装的Win10系统里快速打开【此电脑】图标?(图文详解)
  7. FTP笔记-FTP主动模式和被动模式
  8. RTX腾讯通对话框字体 错乱修复 ,如发出去 是躺着的字
  9. Harris-Laplace角点检测初探+python实现
  10. 医院管理系统mysql课程设计_数据库(课程设计)报告(医院管理系统).doc