多多返利网站建设,公众号编辑器怎么使用,wordpress 积分系统,泰州做网站目录
一、本节介绍
1 上集回顾
2 本节介绍
二、什么是漫反射材质球
三、 漫反射进化史
1 三种算法结果的区别
2 具体算法
2.1 兰伯特逐顶点算法
a.本小节使用的unity自带结构体。
b.兰伯特逐顶点算法公式
c.代码实现——兰伯特逐顶点算法
2.2 代码实现——兰伯特逐…目录
一、本节介绍
1 上集回顾
2 本节介绍
二、什么是漫反射材质球
三、 漫反射进化史
1 三种算法结果的区别
2 具体算法
2.1 兰伯特逐顶点算法
a.本小节使用的unity自带结构体。
b.兰伯特逐顶点算法公式
c.代码实现——兰伯特逐顶点算法
2.2 代码实现——兰伯特逐像素算法
a.像素和顶点算法的区别
b.实现代码 2.3 代码实现——半兰伯特算法
a.为什么会出现半兰伯特
b.半兰伯特公式
c.代码实现
四、下集介绍 一、本节介绍
1 上集回顾
本集讲了如何让图片和外部颜色叠加显示。
2 本节介绍
如何做一个漫反射材质球。
二、什么是漫反射材质球
1 之前的颜色材质球
我们目前只学过直接上色的材质球如图1所示还有上节课的颜色和图片叠加的材质球。 图1 材质球 2 现实的光照下的球
现实光照下的大部分材质球并不是纯色且全亮的而是如图2所示。 图2 现实中的球 这种模拟大部分现实世界物体发光的状态就是漫反射材质球。 备注 反射有两种镜面反射和漫反射。像镜子的反光非常光滑的物体反光比如金属属于镜面反射其他大部分是漫反射。具体区别详见初中物理~自己百度哦o(*︶*)o 三、 漫反射进化史
我们算到最后对屏幕来说仅仅想知道我这个点应该用什么颜色。
所以对这个颜色的计算出现了三种解法。
兰伯特逐顶点算法兰伯特逐像素算法半兰伯特算法
备注兰伯特是个人他和别人一起研究出来了以上三个定律。
1 三种算法结果的区别
兰伯特逐顶点算法白色和黑色交界处有些方块块的感觉、照不到的地方全黑
兰伯特逐像素算法白色和黑色交界处平滑过渡、照不到的地方全黑
半兰伯特算法白色和黑色交界处平滑过渡、照不到的地方不是全黑
内容参考侵权立删
Unity Shader 漫反射Lambert、Half Lambert - 知乎 图3 三种算法得到的效果 2 具体算法
2.1 兰伯特逐顶点算法
a.本小节使用的unity自带结构体。
struct appdata_full {float4 vertex : POSITION; //顶点坐标float4 tangent : TANGENT; //切线float3 normal : NORMAL; //法线float4 texcoord : TEXCOORD0; //第一纹理坐标float4 texcoord1 : TEXCOORD1;//第二纹理坐标float4 texcoord2 : TEXCOORD2;//第三纹理坐标float4 texcoord3 : TEXCOORD3;//第四纹理坐标fixed4 color : COLOR; //顶点颜色UNITY_VERTEX_INPUT_INSTANCE_ID //ID信息
};
b.兰伯特逐顶点算法公式 公式解释
屏幕上对应点的颜色 光的颜色*物体的颜色*max0该点的法向量*该点的光照方向 备注max函数解释 max(a,b)如果这里面a大答案就是a 如果b大答案就是b。 例 max(5,20)20 max(8,-9)8 此处的作用 因为颜色没有负数如果n*l算出来小于0的时候就直接为0其他时候就是n*l的值。 其实就是起一个“一刀切”掉负数的作用。 得出结论我们想计算漫反射的时候屏幕显示什么颜色我们需要光的颜色、物体的颜色、该点的法向量单位向量、该点的光照方向单位向量。 备注公式里的字母上带^就是单位向量的意思。 c.代码实现——兰伯特逐顶点算法 计算注意事项 在计算n*l时注意该点的法向量往往直接获取的是物体本地坐标该点的光照方向往往获取的是世界坐标 这样是不能乘的所以需要把他们都换算到一个坐标系这里换算到世界坐标下。 会用到的方法
UnityObjectToWorldNormal() //把物体的法线坐标换算到世界坐标下
normalize() //把任何一个向量变成单位向量
dot() //点乘
max() //上文讲过_WorldSpaceLightPos0 //世界坐标下的光线坐标//但是要引用#include Lighting.cginc才能找到 实现的代码 SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include UnityCG.cginc//新的引用#include Lighting.cginc//返回结构体 //引用结构体appdata_full vert (appdata_full v){ //模型顶点坐标转屏幕坐标v.vertex UnityObjectToClipPos(v.vertex);//获取法线坐标并转换成世界坐标下的法线坐标float3 worldNormal UnityObjectToWorldNormal(v.normal);//世界坐标下的光线坐标 //单位化坐标 //获取世界坐标下的光线坐标float3 worldLight normalize(_WorldSpaceLightPos0.xyz);//上面的公式float3 diffuse _LightColor0.rgb * v.color.rgb * max(0,dot(worldNormal,worldLight));//算出的值给颜色v.color float4(diffuse,1);return v;}float4 frag (appdata_full v) : SV_Target{ //输出颜色 return float4(v.color,1) ;}ENDCG}}
2.2 代码实现——兰伯特逐像素算法
a.像素和顶点算法的区别
从写法角度来看顶点算法是在顶点着色器中写的像素算法是在片元着色器中写的。从原理角度来说因为顶点是初始值经过一系列计算后数据就会和我们想要的有些偏差。 例让你拿笔写一个字你可能就写了但是让你拿竹竿上面绑个中性笔写字你就写不准了肯定是离画出来的地方越近画出来越是自己想要的。 结论像素着色器离最后的显示比较近所以出来的结果和我们想要的更一致。 b.实现代码
Shader Unlit/005_1
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include UnityCG.cginc#include Lighting.cgincappdata_full vert (appdata_full v){ v.vertex UnityObjectToClipPos(v.vertex);//把法线转换成世界坐标传进去v.normal UnityObjectToWorldNormal(v.normal);return v;}float4 frag (appdata_full v) : SV_Target{//法线世界坐标float3 worldNormal v.normal;//光线世界坐标float3 worldLight normalize(_WorldSpaceLightPos0.xyz);//计算颜色float3 diffuse _LightColor0.rgb * v.color.rgb * max(0,dot(worldNormal,worldLight));//把颜色传进去return float4(diffuse,1) ;}ENDCG}}
}2.3 代码实现——半兰伯特算法
a.为什么会出现半兰伯特
兰伯特的两个算法得到的球在没有光线照射的时候都是黑色的但玩游戏的时候往往希望虽然光线无法照到但我们可以看见。 数学知识公式中的n*l值的范围是【-1,1】之间我们希望把这个区间改成【0,1】前面的课学过【-1,1】*0.50.5就可以转成【0,1】0的时候就是之前光照模型中黑色部分越靠近1越亮。 因为我们实际上并不是需要它看不见只是需要它要明暗变化所以我们在环境光的基础上加上兰伯特公式计算出的值就有了明暗变化。
于是就出现了第三种半兰伯特。
b.半兰伯特公式 在上图基础上 最终颜色 环境光Cdiffuse c.代码实现
这里其他代码都没有变只更改了上图0.5的部分。最后输出前再加入环境光。 备注 获取环境光强度的方法UNITY_LIGHTMODEL_AMBIENT.xyz Shader Unlit/005_2
{SubShader{Pass{CGPROGRAM#pragma vertex vert#pragma fragment frag#include UnityCG.cginc#include Lighting.cgincappdata_full vert (appdata_full v){v.vertex UnityObjectToClipPos(v.vertex);v.normal UnityObjectToWorldNormal(v.normal);return v;}float4 frag (appdata_full v) : SV_Target{float3 worldNormal v.normal;float3 worldLight normalize(_WorldSpaceLightPos0.xyz);//本节变动//获取环境光float3 anbient UNITY_LIGHTMODEL_AMBIENT.xyz;//计算范围float halfLamient dot(worldNormal,worldLight)*0.50.5;//计算反射强度float3 diffuse _LightColor0.rgb * v.color.rgb *halfLamient;//反射光加光照强度float3 c anbient diffuse;return float4(c,1) ;}ENDCG}}
}
四、下集介绍
本集讲了3种计算反射光的方法。
下集讲光照计算高光反射。最晚更新日期1月7日