专业网站建站,wordpress登录不上后台,东莞常平中学录取分数线2022,济南网站推广优化从宏观上讲渲染包含了两大部分#xff1a;决定一个像素的可见性#xff0c;决定一个像素的光照计算
而光照模型就是用于决定在一个像素上决定怎样的渲染光照计算。
一、我们是如何看到这个世界的
1.光源
实时渲染中#xff0c;我们通常把光源当成一个没有体积的点#…从宏观上讲渲染包含了两大部分决定一个像素的可见性决定一个像素的光照计算
而光照模型就是用于决定在一个像素上决定怎样的渲染光照计算。
一、我们是如何看到这个世界的
1.光源
实时渲染中我们通常把光源当成一个没有体积的点用l来表示它的方向
辐照度量化光的方法一个光源发出了多少光
在计算光照模型时我们需要知道一个物体的辐照度
对于平行光辐照度通过计算垂直于l的单位时间内穿过的能量来得到。
但物体表面往往时和l不垂直的那么
如何计算辐照度光源方向l和法线n之间的夹角的余弦值
注意这里的默认方向的模都为1 辐照度和照射到物体表面时光线之间的距离成反比因此辐照度与成正比。
可以使用光源方向l和表面法线n的点积得到。这也是用点积来计算辐照度的由来。
2.吸收和散射
光线由光源发射出来后会与物体相交相交的结果有两种散射和吸收
散射只改变方向不改变颜色和密度
吸收只改变密度和颜色但不改变光线的方向
散射后的两种方向
1.散射到物体内部这种现象被称为折射或投射2.散射到外部这种现象被称为反射
对于不透明物体折射进入物体内部的光线还会继续与内部的颗粒进行交互。其中一些光线最后会重新发射出物体表面而另一些则被物体吸收。那些从物体表面重新发射出的光线将具有和入射光线不同的方向分布和颜色。 为了区分两种不同的散射光照模型中用了两种不同的部分来计算
高光反射表示物体表面是如何反射光线的漫反射表示有多少光线会被折射、吸收和散射出表面
出射度根据入射光线的数量和方向计算出出射光线的数量和方向
辐照度和出射度之间是满足线性关系的而他们之间的比值就是材质的漫反射和高光反射属性
3.着色
定义着色shading是指根据材质属性如漫反射属性等、光源信息如光源方向、辐照度等使用一个等式去计算沿着某一个观察方向的出射度的过程。
我们把这个等式称为光照模型。不同的光照模型有不同的目的。
如一些用于描述粗糙的物体表面一些用于描述金属表面
4.BRDF光照模型
通俗的来讲当给定入射光线的方向和辐照度后BRDF可以给出在某个出射方向上的能量分布。
本章涉及的BRDF是对真实场景进行理想化和简化后的模型并不能真实的反应物体与光线的交互。这写光照模型被称为经验模型。 图形学第一定律如果它看起来是对的那么它就是对的。 二、标准光照模型
1975年著名学者裴祥风提出了标准光照模型背后的基本理念。标准光照模型只关心直接光照也就是那些直接从光源发射出来照射到物体表面后经过物体表面的一次反射直接进入摄像机的光线。
该方法将光线分为4部分
自发光emissive。用于表述当给定一个方向时一个表面本身会向该方向发射出多少辐射度。注意如果没有使用全局光照技术这些自发光是并不会真的照亮周围物体的而是它本身看起来更亮了而已。
高光反射specular。用于描述当光线从光源照射到模型表面时该表面会在完全镜面反射方向散射多少辐射量。
漫反射diffuse。用于描述当光线从光源照射到模型表面时该表面会向每个方向散射多少辐射量。
环境光ambient。用于描述其他所有间接光照。
1.环境光
间接光照是指光线通常会在多个物体间反射最后进入摄像机也就是说光线在进入摄像机前经过了不只一次光照。
在标准光照模型中使用了一种被称为环境光的部分来近似模拟间接光照。环境光的计算非常简单它是一个全局变量即场景中的所有物体都使用这个环境光。 2.自发光
自发光也可以直接由光源发射进摄像机而不需要经过任何物体的反射。标准光照模型使用自发光来计算这个部分的贡献度。其计算很简答直接使用该材质的自发光颜色 通常在实时渲染中自发光表面并不会照亮周围表面这个物体并不会被当成一个光源。
只有引入全局光照系统后才可以模拟这类自发光物体对周围环境的影响
3.漫反射
漫反射用于对那些被物体表面随机散射到各个方向的辐射度进行建模。
漫反射中视角不重要入射光线角度很重要
兰伯特定律反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比。 材质的漫反射颜色 光源颜色
防止物体被从后面来的光源照亮所以将负值截去
4.高光反射
用于计算沿着完全镜面防溺水方向被反射的光线这可以让物体看起来是有光泽的如金属材质
需要知道的变量法线方向、视角方向、光源方向、反射方向等
其中反射方向可以由得到 phong模型计算高光反射
材质的光泽度也称反光度。用于控制高光区域的“亮点”有多宽越大两点越小
是材质的高光颜色。用于控制材质对于高光反射的强度和颜色。
光源颜色和强度
Blinn-Phong模型 基本思想是为避免计算。因此引入一个新的矢量它可以通过对和qupingjun后再归一化得到 Blinn-Phong模型公式 在硬件实现中如果摄像机和光源距离模型足够远的话Blinn模型会快于Phong因为和都是定值所以也是一个常量。这两种模型都是经验模型不存在谁更正确一些。
5.逐像素还是逐顶点
我们在哪里计算这些模型呢
一般有两种选择
在片元着色器中计算也被称为逐像素光照在顶点着色器中计算也被称为逐顶点光照
逐像素光照
以每一个像素为基础得到它的法线可以对顶点法线插值得到也可以从法线纹理中采样得到然后进行光照模型计算。这种在面片之间对顶点法线进行插值的技术被称为Phong着色也被称为Phong插值或法线着色技术与之前讲的Phong光照模型不同
逐顶点光照 又称高洛德着色Gouraud。对每个顶点上进行光照在渲染图元中进行线性插值最后输出成像素颜色。由于顶点数目小于像素数目因此顶点光照计算小于像素光照。但顶点光照更依赖于线性插值来得到像素光照所以当光照模型中有非线性的计算时如高光反射逐顶点光照就会出错。逐顶点光照会在渲染图元内部对顶点进行插值导致渲染图元内部颜色总处于暗于顶点处的最高颜色值会导致产生明显的棱角现象。
6.总结
标准光照模型是经验模型Blinn-Phong简化了计算在某些情况下计算更快Blinn-Phong无法表现很多重要的物理现象如菲涅尔反射Blinn-Phong是各向同性的即当我们固定视角和光源方向旋转这个表现时反射不会发生任何改变有些表面是各向异性的反射性质如拉丝金属、毛发等
三、unity中的环境光和自发光
在标准光照模型中计算环境光和自发光
环境光 可以在light中控制
只需要在shader中通过内置变量
UNITY_LIGHTMODEL_AMBIENT
来控制环境光的颜色和强度信息
自发光
在片元着色器输出最后的颜色之前把材质的自发光颜色添加到输出颜色上即可
四、在unityshader中实现漫反射光照模型
漫反射基本光照公式
我们需要四个参数
入射光线颜色和强度材质漫反射系数表面法线光源方向
为了防止点积结果负值使用max操作CG提供了这一函数。在本例子中使用CG的另一函数可以达到同一目的saturate 函数saturate() 参数x为用于操作的矢量或标量可以是float、float2、float3等类型 描述把x截取在[0,1]范围内如果x是一个矢量那么会对它的每一个分量进行这样的操作 1.实践逐顶点光照
全部代码如下
Shader Shader/DiffuseVertexLevel
{Properties{[HDR]_Diffuse (Diffues, Color) (1,1,1,1)}SubShader{Tags { RenderTypeOpaque }LOD 100Pass{Tags{LightModeForwardBase}//定义光照模式 只有正确定义LightMode我们才能获得一些unity的内置变量CGPROGRAM//包围CG代码片#pragma vertex vert#pragma fragment frag//定义顶点着色器和像素着色器名字#include UnityCG.cginc#include Lighting.cginc//为了使用unity内置的一些变量还需要包含进unity的内置文件UnityCG.cgincstruct appdata{float4 vertex : POSITION;float3 normal : NORMAL;//为了访问顶点的法线在appdata中定义normal变量};struct v2f{float4 vertex : SV_POSITION;fixed3 color : COLOR;//为了把顶点着色器中得到的光照颜色传递给片元着色器};fixed4 _Diffuse;//声明变量v2f vert (appdata v){v2f o;o.vertex UnityObjectToClipPos(v.vertex);fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal normalize(mul(v.normal,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
}效果如下
2.实践逐像素光照
全部代码如下
Shader Shader/DiffusePixelLevel
{Properties{[HDR]_Diffuse (Diffues, Color) (1,1,1,1)}SubShader{Tags { RenderTypeOpaque }LOD 100Pass{Tags{LightModeForwardBase}//定义光照模式 只有正确定义LightMode我们才能获得一些unity的内置变量CGPROGRAM//包围CG代码片#pragma vertex vert#pragma fragment frag//定义顶点着色器和像素着色器名字#include UnityCG.cginc#include Lighting.cginc//为了使用unity内置的一些变量还需要包含进unity的内置文件UnityCG.cgincstruct appdata{float4 vertex : POSITION;float3 normal : NORMAL;//为了访问顶点的法线在appdata中定义normal变量};struct v2f{float4 pos : SV_POSITION;float3 worldNormal : TEXCOORD0;};fixed4 _Diffuse;//声明变量v2f vert (appdata v){v2f o;o.pos UnityObjectToClipPos(v.vertex);o.worldNormal normalize(mul(v.normal,unity_WorldToObject));return o;}fixed4 frag (v2f i) : SV_Target{ fixed3 ambient UNITY_LIGHTMODEL_AMBIENT.xyz;fixed3 worldNormal normalize(i.worldNormal);fixed3 worldLight normalize(_WorldSpaceLightPos0.xyz);fixed3 diffuse _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLight));fixed3 color ambient diffuse;return fixed4(color, 1.0);}ENDCG}}Fallback Diffuse
}效果如下 3.半兰伯特模型 对于模型的背光面原兰伯特中点积结果将映射到同一个值。
而半兰伯特则在背光面也可以有明暗变化不同的点积结果会映射到不同的值上
半兰伯特无任何物理依据仅仅是视觉加强技术。
五、在unityshader中实现高光反射光照模型
基本同理