最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網 會員登陸 & 注冊

Unity——UI光照(模擬光照)

2023-04-16 23:18 作者:叁拾柒渡伍  | 我要投稿

前言

????????沒錯,這是UI光照不是2D光照。是Image不是SpriteRenderer。

????????本文的內容更偏向于花活騷操作,為了不耽誤讀者的時間,請?zhí)崆爸獣裕?/span>

????????不管是Buind-In管線還是URP管線下,可能都沒有特別提供針對UI的光照功能,可能也確實沒有必要,但是本著“玩”技術的心理,我在這里給出一個UI模擬光照的“魔道功法”。

????????其實就是Shader 實現經驗型光照模型的衍生,因為本文屬于Shader光照部分的衍生,所以本文并不會非常詳細的講解光照相關的知識,那部分知識可能會單獨做一期,詳細的講解知識點以及計算過程。

????????老規(guī)矩!此方案是否具有實用性,各位讀者請自行衡量。

????????作者也認為實用性較小,所以當做一個騷操作來寫。

???????? 先來看效果:

平行光
點光源
聚光燈

????????如果部分讀者不太了解Shader方面的知識也沒有關系,因為是個花活,用的的東西也比較簡單,閱讀完本文也是可以實現的。

????????最后會給出完整的Shader代碼。

思路

????????單純讓Image模擬光照的思路其實比較簡單,就是將3D模型實現光照的那一套挪用到UI上即可,修改的地方相當少。比如我示例中使用的就是【蘭伯特(Lambert)光照模型】。

????????至于為什么采用蘭伯特光照模型,那是因為蘭伯特光照模型比較簡單。

實現

????????蘭伯特光照模型是一個經驗光照模型。他不符合真正的物理,只是看起來可能是對的,根據計算機圖形學第一定律:(⊙o⊙)…。

計算機圖形學第一定理

蘭伯特光照模型: Diffuse=Ambient+Kd*LightColor*Dot(N,L)

Diffuse:最終漫反射光強(顏色)????????????Ambient:環(huán)境光強(環(huán)境色)

Kd:材質對光的反射系數???????????????????????LightColor:燈光的顏色

N:頂點法線向量???????????????????????????????????L:頂點到光源位置的單位向量

示意圖

????????如果對光照這部分不太了解的讀者,可以先理解為L與N形成的夾角越小,那就表示更亮,反之就更暗,在90°及以上的時候我們認為當前點不接受光照。

????????知道了思路,實現起來就很簡單了,我們直接動手開始寫Shader。

????????我們這里只寫最簡的功能,把貼圖渲染出來,支持光照。其他的功能比如什么調整Color,圖片透明,還有因為引入cginc導致變體變多等問題因為與本文無關就不處理了。

????????我們要用到編輯器為我們提供的一些數據,需要引用 #include "Lighting.cginc"

? ??????環(huán)境色:fixed4 Ambient=unity_AmbientSky;

????????反射系數:這里用1,half Kd=1;

????????燈光顏色:fixed4 LightColor=_LightColor0;

????????N法線:這里只考慮最簡單情況,讓法線面向【前】fixed3 N=fixed3(0,0,-1);

????????L光源單位向量:fixed3 L=_WorldSpaceLightPos0;

????????然后只需要將以上數值帶入公式,就可以了。

????????fixed4 Diffuse=Ambient+Kd*LightColor*max(0,dot(N,L));

????????為了避免一些因為負值導致的問題,我們使用Max()限制一下范圍。

部分代碼

? ? Properties

? ? {

????????//為了與UI的Sprite對接,圖片的名字盡量不要動

? ? ? ?_MainTex ("Texture", 2D) = "white" {}

? ? }

? ? SubShader

? ? {

? ? ? ? Tags { "RenderType"="Transparent" }

? ? ? ? Pass

? ? ? ? {

? ? ? ? ? ? Tags{"LightMode"="ForwardBase"}

? ? ? ? ? ? CGPROGRAM

? ? ? ? ? 略?......

? ? ? ? ? ? #include "Lighting.cginc"

????????????略......

? ? ? ? ? ? fixed4 frag (v2f i) : SV_Target

? ? ? ? ? ? {

? ? ? ? ? ? ? ? fixed4 col = tex2D(_MainTex, i.uv);

? ? ? ? ? ? ? ? fixed4 Ambient=unity_AmbientSky;

? ? ? ? ? ? ? ? half Kd=1;

? ? ? ? ? ? ? ? fixed4 LightColor=_LightColor0;

? ? ? ? ? ? ? ? fixed3 N=fixed3(0,0,-1);

? ? ? ? ? ? ? ? fixed3 L=_WorldSpaceLightPos0;

? ? ? ? ? ? ? ? fixed4 Diffuse=Ambient+Kd*LightColor*max(0,dot(N,L));

? ? ? ? ? ? ? ? col*=Diffuse;

? ? ? ? ? ? ? ? return col;

? ? ? ? ? ? }

? ? ? ? ? ? ENDCG

? ? ? ? }

? ? }

現在平行光就已經實現了。

點光源與聚光燈

????????平行光和點光源與聚光燈不同,點光源與聚光燈發(fā)出的光會隨著距離做出衰減,距離光源越遠,光強越弱,這個衰減并不是一個線性的。這個衰減可以自己計算也可以使用Unity提供的方法UNITY_LIGHT_ATTENUATION(“返回的衰減值”,“頂點世界坐標”)

我們以點光源為例,看一下返回的衰減值是個什么樣子的。

代碼
圖像

? ? ? ? 我們要做的就是把這個衰減值*燈光顏色附加到圖像上。就可以得到最后的結果。

????????我們在第二Pass中實現效果。此處要用到#include "AutoLight.cginc"空間中的方法。

代碼

完整代碼

Shader "UI/UILight"

{

? ? Properties

? ? {

? ? ? ? [PerRendererData]_MainTex ("Texture", 2D) = "white" {}

? ? }

? ? SubShader

? ? {

? ? ? ? Tags { "RenderType"="Transparent" }

? ? ? ? Pass

? ? ? ? {

? ? ? ? ? ? Tags{"LightMode"="ForwardBase"}

? ? ? ? ? ? CGPROGRAM

? ? ? ? ? ? #pragma vertex vert

? ? ? ? ? ? #pragma fragment frag

? ? ? ? ? ? #include "UnityCG.cginc"

? ? ? ? ? ? #include "Lighting.cginc"

? ? ? ? ? ? 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

? ? ? ? ? ? {

? ? ? ? ? ? ? ? return 0;

? ? ? ? ? ? ? ? fixed4 col = tex2D(_MainTex, i.uv);

? ? ? ? ? ? ? ? clip(col.w-0.01);

? ? ? ? ? ? ? ? fixed4 Ambient=unity_AmbientSky;

? ? ? ? ? ? ? ? half Kd=1;

? ? ? ? ? ? ? ? fixed4 LightColor=_LightColor0;

? ? ? ? ? ? ? ? fixed3 N=fixed3(0,0,-1);

? ? ? ? ? ? ? ? fixed3 L=_WorldSpaceLightPos0;

? ? ? ? ? ? ? ? fixed4 Diffuse=Ambient+Kd*LightColor*max(0,dot(N,L));

? ? ? ? ? ? ? ? col*=Diffuse;

? ? ? ? ? ? ? ? return col;

? ? ? ? ? ? }

? ? ? ? ? ? ENDCG

? ? ? ? }

? ? ? ? ? ?Pass

? ? ? ? {

? ? ? ? ? ? Tags{"LightMode"="ForwardAdd"}

? ? ? ? ? ? Blend One One

? ? ? ? ? ? CGPROGRAM

? ? ? ? ? ?#pragma vertex vert

? ? ? ? ? ? #pragma fragment frag

? ? ? ? ? ? #pragma multi_compile_fwdadd

? ? ? ? ? ? #include "UnityCG.cginc"

? ? ? ? ? ? #include "Lighting.cginc"

? ? ? ? ? ? #include "AutoLight.cginc"

? ? ? ? ? ? struct appdata

? ? ? ? ? ? {

? ? ? ? ? ? ? ? float4 vertex : POSITION;

? ? ? ? ? ? ? ? float2 uv : TEXCOORD0;

? ? ? ? ? ? ? ? float3 normal:NORMAL;

? ? ? ? ? ? };

? ? ? ? ? ? struct v2f

? ? ? ? ? ? {

? ? ? ? ? ? ? ? ?float2 uv : TEXCOORD0;

? ? ? ? ? ? ? ? float4 vertex : SV_POSITION;

? ? ? ? ? ? ? ? float3 worldPos:TEXCOORD2;

? ? ? ? ? ? };

? ? ? ? ? ? sampler2D _MainTex;

? ? ? ? ? ? float4 _MainTex_ST;

? ? ? ? ? ? v2f vert (appdata v)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? v2f o;

? ? ? ? ? ? ? ? o.vertex = UnityObjectToClipPos(v.vertex);

? ? ? ? ? ? ? ? o.uv = TRANSFORM_TEX(v.uv, _MainTex);

? ? ? ? ? ? ? ? o.worldPos=mul(unity_ObjectToWorld,v.vertex);

? ? ? ? ? ? ? ? return o;

? ? ? ? ? ? }

? ? ? ? ? ? fixed4 frag (v2f i) : SV_Target

? ? ? ? ? ? {

? ? ? ? ? ? ? ? fixed4 col = tex2D(_MainTex, i.uv);

? ? ? ? ? ? ? ? UNITY_LIGHT_ATTENUATION(atten,0,i.worldPos)

? ? ? ? ? ? ? ? fixed4 LightColor=_LightColor0*atten;

? ? ? ? ? ? ? ? return col*LightColor;

? ? ? ? ? ? }

? ? ? ? ? ? ENDCG

? ? ? ? }

? ? }

}

現在就已經實現了我一開始那三張圖的效果了。

????????最后可能會出現一些Scene和Game窗口顯示不一樣的情況。比如在平行光是正常的,但是點光源和聚光燈不正常。還有就是這種方式的開銷相對來說會變大。

問題1
問題2

可以將Canvas的渲染模式(Render Mode)改為Screen Space-Camera。新建一個相機,讓他只渲染UI層,為了讓UI顯示在模型之前,相機的Depth調高,并且將Clear Flags設置為Depth Only。

設置Canvas
設置相機

???????

?????????到這里文章的內容就全部結束。

????????本期的內容是個騷操作,目的是與各位讀者分享一下有趣的操作。因為本期的定位不是[教程]系列,可能會有些不是仔細,希望各位讀者理解。

????????如果本文對您有一絲絲的幫助請賞給作者一個贊好嗎。

????????最后想說一點,以后我打算每期專欄配一個演示視頻,可能會更好的幫助有需要的讀者,能讓有需要的讀者更直觀的看到我的操作過程。

????????我們下期再見。


Unity——UI光照(模擬光照)的評論 (共 條)

分享到微博請遵守國家法律
丹巴县| 抚松县| 门头沟区| 蚌埠市| 海宁市| 泌阳县| 澳门| 马边| 深州市| 襄城县| 高安市| 山东省| 临泉县| 盘山县| 孝感市| 哈密市| 陈巴尔虎旗| 石台县| 江阴市| 原平市| 盐边县| 浦城县| 虹口区| 斗六市| 天全县| 邵武市| 焦作市| 四平市| 镇江市| 治多县| 河源市| 杭锦旗| 沙河市| 奎屯市| 荣成市| 木里| 广宗县| 山丹县| 双城市| 曲松县| 东源县|