【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase

【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第1张图片【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第2张图片

Shader "Unlit/ForwardBase"
{
	Properties
	{
		_MainTex ("Texture", 2D) = "white" {}
	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			Tags{
				"LightMode" = "ForwardBase" //定义该Pass在Unity的流水线中的角色 (只有定义它才能获取到一些Unity内置的光照变量如_LightColor0     
			}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwdbase //只有引入它才能正确进行获取如光照衰减值等信息
			
			#include "UnityCG.cginc"
			#include "Lighting.cginc" //这个命名空间中包含_LightColor0

			struct appdata
			{
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 vertex : SV_POSITION;
			};

			sampler2D _MainTex;
			float4 _MainTex_ST;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.vertex = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.uv, _MainTex);
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{				
				fixed4 col = tex2D(_MainTex, i.uv);			   
				col.rgb = col.rgb * _LightColor0.rgb;		//_LightColor0是平行光源颜色(即场景自带创建的光源)				
				return col;	
			}
			ENDCG
		}
	}
}

假如我去掉

#include "Lighting.cginc"

假如我去掉标签

"LightMode" = "ForwardBase" 

没有任何变化,因为Unity工程默认是ForwardBase光照模式!

【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第3张图片

Edit -> Project Settings -> Graphics,在Graphics面板中设置有渲染路径(也成为光照模式)

【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第4张图片

同理直接在摄像机指定其他渲染路径,而非Graphics面板设置的

【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第5张图片

官方文档获知的资料如下(红字为网页翻译,不必太在意后期的文章可能会进行解释)

Forward:前置渲染路径

  • ForwardBase: Used in Forward rendering, ambient, main directional light, vertex/SH lights and lightmaps are applied.
  • ForwardAdd: Used in Forward rendering; additive per-pixel lights are applied, one pass per light.
  • ForwardBase:用于正向渲染中,该Pass会计算环境光、最重要的平行光、逐顶点/SH光源和Lightmaps光照贴图
  • ForwardAdd:用于前向渲染。该Pass会计算额外的逐像素光源,每一个Pass对应一个光源

Deferred : 延迟渲染路径

  • Deferred: Used in Deferred Shading; renders g-buffer.
  • 延迟:用于延迟渲染。该Pass会渲染G缓冲(G-buffer)

Legacy Vertex Lit:顶点渲染路径

  • Vertex: Used in legacy Vertex Lit rendering when object is not lightmapped; all vertex lights are applied.
  • VertexLMRGBM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is RGBM encoded (PC & console).
  • VertexLM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is double-LDR encoded (mobile platforms).
  • 顶点(Vertex):当对象未设置光照时,用于旧版Vertex Lit渲染;所有顶点光都被应用。
  • VertexLMRGBM:当对象被光照时,用于传统的Vertex Lit渲染;在光照图是RGBM编码的平台上(PC和控制台)。
  • VertexLM:当对象被光照时,用于传统的Vertex Lit渲染;在光照图是双LDR编码的平台上(移动平台)。

Legacy Defferred (light prepass):延迟顶点渲染路径

  • PrepassBase: Used in legacy Deferred Lighting, renders normals and specular exponent.
  • PrepassFinal: Used in legacy Deferred Lighting, renders final color by combining textures, lighting and emission.
  • PrepassBase:在旧版Deferred Lighting中使用,该Pass会渲染法线和高光反射的指数部分。
  • PrepassFinal:在旧版Deferred Lighting中使用,该Pass通过合并纹理、光照和自发光来渲染得到最后的颜色。

其他特殊的光照模式 :

  • Always: Always rendered; no lighting is applied.
  • ShadowCaster: Renders object depth into the shadowmap or a depth texture.
  • MotionVectors: Used to calculate per-object motion vectors.
  • 始终:始终渲染;不会计算任何光照效果。
  • ShadowCaster:将对象深度渲染到阴影贴图或深度纹理中。
  • MotionVectors:用于计算每个对象的运动矢量。

关于LightMode介绍有另一篇文章说明:https://blog.csdn.net/qq_39574690/article/details/99766585

介绍前向渲染路径原理:(伪代码解释)

Pass{
    //遍历模型三角面
    for(each primitive in this model)
    {
        //遍历三角面片元
        for(each fragment covered by this primitive){
            //深度测试失败
            if(failed in depth test){
                //抛弃片元,不会进行渲染它
                discard;
            }else{
                //深度测试成功,进行渲染它(Shading可理解是进入了我们的着色器代码,输出的是片元着色器的颜色值)
                float4 color = Shading(materialInfo, pos, normal ,lightDir, viewDir);
                //将这个颜色,更新到帧缓冲的该片元位置上
                writeFrameBuffer(fragment, color);
            }
        }
    }
}

 以上伪代码得知,深度测试需要获取深度缓冲区,顺利通过测试后,便进行了计算颜色纸并写入颜色缓冲区。

这个过程是每一个逐像素光源都会进行一次Pass,比如有3个逐像素光源,影响着2个前向渲染路径的物体,就会有3*2=6个Pass进行。每一个Pass可看为一个DC,全部Pass产生的颜色值会进行混合。

在前向渲染路径的ForwardBase模式下,可以针对一个逐像素光源(即默认的平行光)、所有逐顶点光源或SH光源 以及 一个环境光来进行渲染。

光源的Light组件的渲染模式(Render Mode)设置为Not Important的光源会按逐顶点处理或SH处理

渲染模式被设置成Important的光源按逐像素处理

【Shader进阶】Pass块的Tags标签——LightMode之ForwardBase_第6张图片

上图为最大的逐顶点个数设置 以及 光源的渲染模式设置

ForwardBase渲染路径有如下的处理(详细情况请参考https://blog.csdn.net/qq_39574690/article/details/99766585)

fixed4 frag (v2f i) : SV_Target
{						
    fixed3 worldNormal = normalize(i.worldNormal);
    fixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos));
    fixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
    fixed3 halfDir = normalize(worldLightDir + worldViewDir); 
//判断是平行光
#ifdef USING_DIRECTIONAL_LIGHT
    //atten是光照衰减值,它是在光照贴图lightmaps中的一个值(Unity自动帮我们处理的)
    //如果你没有引入#pragma multi_compile_fwdbase,衰减值可能就是错误的
    fixed3 atten = 1.0;//衰减因子为1.0 因为平行光是没有衰减概念的
#endif
    //_LightColor0是平行光颜色(一个逐像素光源的颜色)
    //下面有_Diffuse和_Specular自发光(材质颜色)和ambient环境光参与
    fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb *     saturate(dot(worldNormal,worldLightDir));
    fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(worldNormal,     halfDir)), _Gloss);
    //环境光
    fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;   
    return fixed4(ambient + (specular + diffuse) * atten, 1.0);//衰减因子影响的是两个反射的颜色值
}

你可能感兴趣的:(Unity3d,Shader,#,Shader进阶)