[Unity Shader] 逐顶点光照和逐片元漫反射光照
书中的6.4节讲的是漫反射的逐顶点光照和逐片元光照。
前一种算法是根据漫反射公式计算顶点颜色(顶点着色器),对颜色插值(光栅化过程)返回每个像素的颜色值(片元着色器)。
第二种算法是获得顶点的法线(顶点着色器),对法线插值(光栅化过程),根据漫反射公式计算像素颜色(片元着色器)。
注:漫反射公式:(光源颜色 * 材质漫反射颜色)* (表面法线矢量 · 表面到光源的矢量)
书中对上两种算法的实现如下:
Shader "Unity Shaders Book/Chapter 6/Diffuse Vertex Level"
{
Properties
{
_Diffuse("Diffuse", Color) = (1.0, 1.0, 1.0, 1.0)
}
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;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(mul(v.normal, (float3x3)_World2Object));
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 Shaders Book/Chapter 6/Diffuse Pixel Level"
{
Properties
{
_Diffuse("Diffuse", Color) = (1.0, 1.0, 1.0, 1.0)
}
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 worldNormal : TEXCOORD0;
}; v2f vert (a2v v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.worldNormal = mul(v.normal, (float3x3)_World2Object);
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.rgb, 1.0);
} ENDCG
}
} Fallback "Diffuse"
}
逐片元光照

刚开始看这两段代码有点懵,觉得并没有什么区别,不理解为什么将漫反射的计算挪到片元着色器中就能区别上面两种算法。
查了一些帖子了解到,顶点着色器是对每个顶点数据进行处理的,包括空间转换和颜色计算等,并不是对每个像素进行处理。而片元着色器有时又叫做像素着色器,它是对每个片元处理一次。片元着色器得到的片元数据(像素数据),是在光栅化过程中对顶点数据进行插值得到的,并不只是顶点数据,
“属性插值的方法可以得到片元的颜色、法向量、深度值、纹理坐标等。”(https://wenku.baidu.com/view/219ecc7daef8941ea66e0519.html?pn=50NaN),即在片元着色器中使用的法线数据,其实已经是插值后的,因此在片元着色器中计算漫反射时,使用的就是逐片元光照的算法。这也是为什么逐片元光照会比逐顶点光照效率低的原因(计算漫反射的次数更多)。
“但是,由于逐顶点光照依赖于线性插值来得到像素光照,因此,当光照模型中有非线性的计算(例如计算高光反射时)时,逐顶点光照就会出问题。而且,由于逐顶点光照会在渲染图元内部对顶点颜色进行插值,这会导致渲染图元内部的颜色总是暗于顶点处的最高颜色值,这在某些情况下会产生明显的棱角现象。”

[Unity Shader] 逐顶点光照和逐片元漫反射光照的更多相关文章
- Unity Shader入门精要学习笔记 - 第9章 更复杂的光照
		
转载自 冯乐乐的<Unity Shader入门精要> Unity 的渲染路径 在Unity里,渲染路径决定了光照是如何应该到Unity Shader 中的.因此,如果要和光源打交道,我们需 ...
 - Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术
		
转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...
 - unity shader base pass and additional pass
		
[Unity Shaders]Shader中的光照,shadersshader 写在前面 自己写过Vertex & Fragment Shader的童鞋,大概都会对Unity的光照痛恨不已 ...
 - OpenGL光照2:材质和光照贴图
		
本文是个人学习记录,学习建议看教程 https://learnopengl-cn.github.io/ 非常感谢原作者JoeyDeVries和多为中文翻译者提供的优质教程 的内容为插入注释,可以先跳过 ...
 - unity shader入门(二)语义,结构体,逐顶点光照
		
下为一个逐顶点漫反射光照shader Shader "study/Chapter6/vertexShader"{ Properties{_Diffuse("Diffuse ...
 - unity shader入门(三)逐像素光照,Blinn-Phong模型
		
与上篇逐顶点光照很像,只是改为在片元着色器中计算光照,下为逐像素光照shader Shader "study/Chapter6/PixelShader"{ Properties{ ...
 - Unity3D学习(六):《Unity Shader入门精要》——Unity的基础光照
		
前言 光学中,我们是用辐射度来量化光. 光照按照不同的散射方向分为:漫反射(diffuse)和高光反射(specular).高光反射描述物体是如何反射光线的,漫反射则表示有多少光线会被折射.吸收和散射 ...
 - 【Unity Shader】(六) ------ 复杂的光照(上)
		
笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Sha ...
 - Unity Shader入门精要学习笔记 - 第6章 开始 Unity 中的基础光照
		
转自冯乐乐的<Unity Shader入门精要> 通常来讲,我们要模拟真实的光照环境来生成一张图像,需要考虑3种物理现象. 首先,光线从光源中被发射出来. 然后,光线和场景中的一些物体相交 ...
 
随机推荐
- MEMCACHE与REDIS
			
千万数据量的高并发,容灾. Redis 基于单线程, 持久性 多数据类型 内存中只存KEY Redis支持数据的备份,即master-slave模式的数据备份. Redis与Memcached的区别 ...
 - 情绪ABC理论
			
美国著名心理学家阿尔伯特·艾利斯 [Albert Ellis 1913.09.27]于20世纪50年代创立, 其理论认为引起人们情绪困扰的并不是外界发生的事件,而是人们对事件的态度.看法.评价等认知内 ...
 - UVa 1642 - Magical GCD(数论)
			
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
 - 写了一个web使用向导的小插件
			
运行效果: 引入插件: <link rel="stylesheet" href="ez-guide.css"> <script src=&qu ...
 - [AHOI2009]飞行棋
			
嘟嘟嘟 刚开始想这道题的时候确实很蒙,只想到矩形对边做对应的弧长相等,然后想办法凑出相等的弧长.其实正解很简单,不要去想边,应该想对角线,因为根据初中园的知识,这个矩形的对角线是圆的直径,而直径所对的 ...
 - C. String Transformation
			
http://codeforces.com/problemset/problem/946/C You are given a string s consisting of |s| small engl ...
 - HDU 6318 Swaps and Inversions 思路很巧妙!!!(转换为树状数组或者归并求解逆序数)
			
Swaps and Inversions Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Oth ...
 - 什么是X86和X86-64
			
X86的定义 X86是一个Intel或AMD通用计算机系列的标准编号缩写,也是32位微处理器架构的一种,也标识一套通用的计算机指令集. X86-64的定义 X86-64,简称X64,是一个Intel或 ...
 - 利用Dropbox中转自己的C2
			
利用Dropbox中转自己的C2 0x00 前言 本来的目的呢,是利用dropbox中转自己的c2达到免杀的效果,然后可能是看了文章太久没抓住机会复现,到最后发现已经失效了,会被360拦截,所以好像也 ...
 - Git 最新版本2.20.1 安装及配置
			
我们先去官网下载地址,去下载. https://git-scm.com/downloads 1. 2. 3. 双击 Git-2.20.1-64-bit.exe 安装 4. 5. 6. 7. 8. 9. ...