- 流水线
- 顶点着色器
- 片元(像素)着色器
- shaderTab 语义学习及编码
- 材质面板定义
- 渲染队列
- 固定渲染管线
- “我们可以通过开启或关闭某些功能来让GPU进行相应的渲染”
- 编程渲染管线
- 通过更加灵活的编程,可更灵活定制化
- 3D数学
- 线性代数
- 物理
- 光照模型
- 基础光照
- 处理光照方式
- 逐顶点
- 逐像素
- 逐顶点计算光源比逐像素计算光源,效率更高但效果不够平滑,且存在非线性计算时,光照会出问题
- 球谐函数 (Spherical Harmonics,SH) 处理
- 将光源分布分解到各个球谐函数基上
- 类似小波变换
- 光源颜色,由光源组件设置决定
- 漫反射颜色,由材质的shader变量决定
- 环境光颜色,g_ambient,由unity的全局变量决定,在Window->rendering->Light setting->Scene中设置
- 自发光颜色,由材质的shader变量决定
- 材质的高光反射颜色,M_specular,由材质的shader变量决定
- 兰伯特漫反射光照模型
- C_diffuse = (c_light*m_diffuse)*max(0,n*l)
- 在shader中max可以用饱和函数saturate()函数代替max函数
- c_light:光源颜色
- m_diffuse:漫反射颜色
- n: 单位法向量
- l:单位光源入射方向向量
- C_diffuse = (c_light*m_diffuse)*max(0,n*l)
- 半兰伯特漫反射光照模型
- C_diffuse = (c_light*m_diffuse)*(0.5*(n*l)+0.5)
- 将【-1,1】映射到【0,1】,原兰伯特漫反射光照模型的[-1,0】范围值全部置为0,即在无光照射的地方没有明暗变化,因此兰伯特漫反射光照模型将这部分映射到【0,1】而具有明暗变化
- 该原理没有任何物理依据,只是一种画面增强手段
- C_diffuse = (c_light*m_diffuse)*(0.5*(n*l)+0.5)
- 环境光照模型
- c_ambient = g_ambient
- 环境光照就是环境光颜色
- c_ambient = g_ambient
- 自发光光照模型
- c_emissive = g_emissive
- 自发光就是自发光颜色
- c_emissive = g_emissive
- 高光反射光照模型
- phong模型
-
- c_light:光源颜色
- M_specular:材质的高光反射颜色
- M_gloss:是幂数,M_gloss越大,高亮亮斑越小,即越集中
-
- phong模型
- 处理光照方式
- 基础光照
M_gloss小
M_gloss大
Tags{"LightMode" = "ForWardBase"
如需要双面渲染等情况)以及一个Additional Pass。
一个Additional Pass会根据影响该物体的其他逐像素光源的数目被多次调用,即每个逐像素光源会执行一次Additional Pass。需要开启:#pragma multi_compile_fwdadd指令保证获得正确的光照变量
前向渲染的问题是:当场景中包含大量实时光源时,前向渲染的性能会急速下降。例如,如果我们在场景的某一块区域放置了多个光源,这些光源影响的区域互相重叠,那么为了得到最终的光照效果,我们就需要为该区域内的每个物体执行多个Pass来计算不同光源对该物体的光照结果,然后在颜色缓存中把这些结果混合起来得到最终的光照。然而,每执行一个Pass我们都需要重新渲染一遍物体,但很多计算实际上是重复的。延迟渲染是一种更古老的渲染方法,但由于上述前向渲染可能造成的瓶颈问题,近几年又流行起来。除了前向渲染中使用的颜色缓冲和深度缓冲外,延迟渲染还会利用额外的缓冲区,这些缓冲区也被统称为G缓冲(G-buffer),其中G是英文Geometry的缩写。G缓冲区存储了我们所关心的表面(通常指的是离摄像机最近的表面)的其他信息,例如该表面的法线、位置、用于光照计算的材质属性等。
1.延迟渲染的原理
延迟渲染主要包含了两个Pass。在第一个Pass中,我们不进行任何光照计算,而是仅仅计算哪些片元是可见的,这主要是通过深度缓冲技术来实现,当发现一个片元是可见的,我们就把它的相关信息存储到G缓冲区中。然后,在第二个Pass中,我们利用G缓冲区的各个片元信息,例如表面法线、视角方向、漫反射系数等,进行真正的光照计算。
对于延迟渲染路径来说,它最适合在场景中光源数目很多、如果使用前向渲染会造成性能瓶颈的情况 下使用。而且,延迟渲染路径中的每个光源都可以按逐像素的方式处理。但是,延迟渲染也有一些缺点。 ● 不支持真正的抗锯齿(anti-aliasing)功能。 ● 不能处理半透明物体。 ● 对显卡有一定要求。如果要使用延迟渲染的话,显卡必须支持MRT(Multiple Render Targets)、 Shader Mode 3.0及以上、深度渲染纹理以及双面的模板缓冲。
当使用延迟渲染时,Unity要求我们提供两个Pass。 (1)第一个Pass用于渲染G缓冲。在这个Pass中,我们会把物体的漫反射颜色、高光反射颜色、平滑 度、法线、自发光和深度等信息渲染到屏幕空间的G缓冲区中。对于每个物体来说,这个Pass仅会执行一次。 (2)第二个Pass用于计算真正的光照模型。这个Pass会使用上一个Pass中渲染的数据来计算最终的 光照颜色,再存储到帧缓冲中。 默认的G缓冲区(注意,不同Unity版本的渲染纹理存储内容会有所不同)包含了以下几个渲染纹理 (Render Texture,RT)。
● RT0:格式是ARGB32,RGB通道用于存储漫反射颜色,A通道没有被使用。 ● RT1:格式是ARGB32,RGB通道用于存储高光反射颜色,A通道用于存储高光反射的指数部分。 ● RT2:格式是ARGB2101010,RGB通道用于存储法线,A通道没有被使用。 ● RT3:格式是ARGB32(非HDR)或ARGBHalf(HDR),用于存储自发光+lightmap+反射探针 (reflection probes)。 ● 深度缓冲和模板缓冲。
当在第二个Pass中计算光照时,默认情况下仅可以使用Unity内置的Standard光照模型。如果我们想 要使用其他的光照模型,就需要替换掉原有的Internal-DeferredShading.shader文件。更详细的信息可以 访问官方文档(http://docs.unity3d.com/Manual/RenderTech-DeferredShading.html )。 |
顶点照明渲染路径是对硬件配置要求最少、运算性能最高,但同时也是得到的效果最差的一种类型,它不支持那些逐像素才能得到的效果,例如阴影、法线映射、高精度的高光反射等。实际上,它仅仅是前向渲染路径的一个子集,也就是说,所有可以在顶点照明渲染路径中实现的功能都可以在前向渲染路径中完成。就如它的名字一样,顶点照明渲染路径只是使用了逐顶点的方式来计算光照,并没有什么神奇的地方。实际上,我们在上面的前向渲染路径中也可以计算一些逐顶点的光源。但如果选择使用顶点照明渲染路径,那么Unity会只填充那些逐顶点相关的光源变量,意味着我们不可以使用一些逐像素光照变量。
float3 lightCoord = mul(unity_WorldToLight, float4(i.worldPos, 1)).xyz; fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL; |
SHADOW_COORDS(2) TRANSFER_SHADOW(o); fixed shadow = SHADOW_ATTENUATION(i); return fixed4(ambient + (diffuse + specular) * atten * shadow, 1.0); |
将:
fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL; fixed shadow = SHADOW_ATTENUATION(i); return fixed4(ambient + (diffuse + specular) * atten * shadow, 1.0); |
统一为:
UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
return fixed4(ambient + (diffuse + specular) * atten, 1.0); |
用于呈现物体表面不平整效果,使渲染更加真实,在shader中替代顶点法线计算
Fixed specularMask = tex2D(纹理变量名,i.uv).r * _SpecularScale
void OnWizardCreate () { // create temporary camera for rendering</ |