基础且直白的Unity渲染(小知识点)-顶点光照和像素光照。

本文探讨了Unity引擎中逐顶点和逐像素光照的区别,强调了引擎如何根据设备性能灵活选择计算方式,并介绍了Unity默认shader的重要性和灯光设置。还提供了Unlit/VertexLight和Unlit/FragmentLight的Shader示例。
逐顶点的光照: 先看在引擎中的逐顶点和逐像素的光照的效果:
可以發現燈光其實只是作爲一個判斷來使用。最終光照是按頂點還是按像素是根據我們需要來進行組合使用。
FrameDebug中的數據可以明顯看到。多光照下可以隨意自己需要進行設置光照是逐頂點還是逐像素。 在看看Unity提供的MoblieDiffuse
會發現unity提供的這一套shader默認將後續的燈光全部作爲逐頂點來計算光照了。 因爲一些低端電腦或者移動平臺上會出現多盞实时灯光的情况会很少。因此除了主光源外的灯光利用逐顶点计算光照也是可以接受的。
Unity提供的默认standshader:
Unity提供的默认shader有着很丰富的功能。这时就可以完整利用到unity本身提供的灯光设置里的Important和NotImpotant功能。 灯光属性中的Important和NotImpotant的设置对于我们进行shader的灯光计算没有决定性作用,可以根据自己的需要进行书写。Unity的灯光仅作为一个输出数据和判断的数值而已。所有的计算都是在shader内进行的。
注意点: 不建议在一个shader内书写逐顶点和逐像素进行混合运算。除非是项目特殊需求。第一效果不好控制。第二现在平台性能也不会那么差。还是可以方便都用逐像素进行处理的。
逐顶点的shader: ```Shader "Unlit/VertexLight" { Properties {
_Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags{"LightMode"="ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; fixed3 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; fixed3 color : COLOR; }; float4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); float3 diffuse = _Color.rgb * _LightColor0.rgb * saturate(dot(worldNormal,lightDir)); o.color = diffuse + ambient; return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed3 col = i.color; return float4(col,1); } ENDCG } Pass { Name "AddLight" Tags{"LightMode"="ForwardAdd" } Blend One One ZWrite Off ZTest LEqual CGPROGRAM #pragma vertex vert #pragma fragment frag //================================== //加入额外光照计算用变体。 //#pragma multi_compile_fwdadd #pragma multi_compile_fwdadd_fullshadows //================================== #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" struct appdata { float4 vertex : POSITION; fixed3 normal : NORMAL; }; struct v2f { float4 worldPos : TEXCOORD0; float4 vertex : SV_POSITION; fixed3 color : COLOR; SHADOW_COORDS(3) }; float4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.worldPos = mul(unity_ObjectToWorld, v.vertex); fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 worldNormal = UnityObjectToWorldNormal(v.normal); #ifdef USING_DIRECTIONAL_LIGHT fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); #else fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - o.worldPos.xyz); #endif float3 diffuse = _Color.rgb * _LightColor0.rgb * saturate(dot(worldNormal,worldLightDir)); TRANSFER_SHADOW(o); UNITY_LIGHT_ATTENUATION(atten, i, o.worldPos.xyz); o.color = (diffuse + ambient); return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed3 col = i.color; return float4(col,1); } ENDCG } }
}
逐像素的shader: ```Shader "Unlit/FargmentLight" { Properties { _Color ("Color", Color) = (1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; fixed3 normal : NORMAL; }; struct v2f { float4 vertex : SV_POSITION; float3 normal : TEXCOORD0; }; float4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.normal = v.normal; return o; } fixed4 frag (v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; fixed3 worldNormal = UnityObjectToWorldNormal(i.normal); fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); float3 diffuse = _Color.rgb * _LightColor0.rgb * saturate(dot(worldNormal,lightDir)); // sample the texture fixed3 col = diffuse + ambient; return float4(col,1); } ENDCG } Pass { Name "AddLight" Tags{"LightMode"="ForwardAdd" } Blend One One ZWrite Off ZTest LEqual CGPROGRAM #pragma vertex vert #pragma fragment frag //================================== //加入额外光照计算用变体。 //#pragma multi_compile_fwdadd #pragma multi_compile_fwdadd_fullshadows //================================== #include "UnityCG.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" struct appdata { float4 vertex : POSITION; fixed3 normal : NORMAL; }; struct v2f { float4 worldPos : TEXCOORD0; float4 vertex : SV_POSITION; //fixed3 color : COLOR; fixed3 normal : TEXCOORD1; SHADOW_COORDS(3) }; float4 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.normal = v.normal; o.worldPos = mul(unity_ObjectToWorld, v.vertex); TRANSFER_SHADOW(o); return o; } fixed4 frag (v2f i) : SV_Target { fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; #ifdef USING_DIRECTIONAL_LIGHT fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz); #else fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz); #endif fixed3 worldNormal = UnityObjectToWorldNormal(i.normal); float3 diffuse = _Color.rgb * _LightColor0.rgb * saturate(dot(worldNormal,worldLightDir)); // sample the texture UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz); fixed3 col = (diffuse + ambient) * atten; return float4(col,1); } ENDCG } } }
案例工程链接: https://pan.baidu.com/s/17Fh2zRuchHiTQUJUNFSXVWdjQRdSZUMwZr92==?linksource=zhihu&at=1655433478046
文章也发布在知乎:https://zhuanlan.zhihu.com/p/527677672
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值