日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Unity Shader】三、漫反射Diffuse Shader例子

發(fā)布時間:2024/9/21 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Unity Shader】三、漫反射Diffuse Shader例子 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

學(xué)習(xí)目標:

  • 漫反射Diffuse Shader,逐頂點計算和逐像素計算。
  • 半蘭伯特(HalfLambert)光照模型。
  • 結(jié)合材質(zhì)自身的色彩(Material Color)及環(huán)境光(Ambient)。

漫反射計算公式:

漫反射Diffuse顏色 = 直射光顏色 * max(0, cos(光源方向和法線方向夾角)) * 材質(zhì)自身色彩

其中max(0, cos(光源方向和法線方向夾角))部分可以改用半蘭伯特光照模型以增強背光面的光照效果。


?逐頂點漫反射

Shader "Custom/04-Diffuse Vertex" { // 逐頂點漫反射 Properties{_Diffuse("Diffuse Color", Color) = (1,1,1,1) // 可在編輯器面板定義材質(zhì)自身色彩 }SubShader{Pass {// 只有定義了正確的LightMode才能得到一些Unity的內(nèi)置光照變量Tags{"LightMode" = "ForwardBase"}CGPROGRAM// 包含unity的內(nèi)置的文件,才可以使用Unity內(nèi)置的一些變量 #include "Lighting.cginc" // 取得第一個直射光的顏色_LightColor0 第一個直射光的位置_WorldSpaceLightPos0(即方向) #pragma vertex vert #pragma fragment fragfixed4 _Diffuse; // 使用屬性struct a2v{float4 vertex : POSITION; // 告訴Unity把模型空間下的頂點坐標填充給vertex屬性float3 normal : NORMAL; // 告訴Unity把模型空間下的法線方向填充給normal屬性float4 texcoord : TEXCOORD0; // 告訴Unity把第一套紋理坐標填充給texcoord屬性
// POSITON、NORMAL、TEXCOORD0都是Unity內(nèi)置的變量 };struct v2f{float4 position : SV_POSITION; // 聲明用來存儲頂點在裁剪空間下的坐標float3 color : COLOR; // 用于傳遞計算出來的漫反射顏色
         // SV_POSITION、COLOR都是Unity內(nèi)置的變量 };// 計算頂點坐標從模型坐標系轉(zhuǎn)換到裁剪面坐標系 v2f vert(a2v v){v2f f;f.position = mul(UNITY_MATRIX_MVP, v.vertex); // UNITY_MATRIX_MVP是內(nèi)置矩陣。該步驟用來把一個坐標從模型空間轉(zhuǎn)換到剪裁空間// 環(huán)境光fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;// 法線方向。把法線方向從模型空間轉(zhuǎn)換到世界空間fixed normalDir = normalize(mul(v.normal, (float3x3)unity_WorldToObject)); // 反過來相乘就是從模型到世界,否則是從世界到模型// 光照方向fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); // 對于每個頂點來說,光的位置就是光的方向,因為光是平行光// 漫反射Diffuse顏色 = 直射光顏色 * max(0, cos(光源方向和法線方向夾角)) * 材質(zhì)自身色彩fixed3 diffuse = _LightColor0 * max(0, dot(normalDir, lightDir)) * _Diffuse; // 融合材質(zhì)自身色彩用乘法// 加上環(huán)境光f.color = diffuse + ambient; // 顏色疊加用加法(通常亮度會增加)return f;}// 計算每個像素點的顏色值 fixed4 frag(v2f f) : SV_Target {return fixed4(f.color, 1); // f.color是float3已經(jīng)包含了三個數(shù)值 }ENDCG}}FallBack "Diffuse" }

如果去掉自定義的_Diffuse(材質(zhì)自身色彩)屬性和環(huán)境光(Ambient),漫反射顏色值將僅由光源顏色來決定。白色光源的顯示效果如下:

現(xiàn)在想要融合材質(zhì)自身的顏色值來顯示,編輯器面板選擇一個材質(zhì)自身的色彩,顯示效果如下:

最后再加上環(huán)境光(UNITY_LIGHTMODEL_AMBIENT),能看到變白變亮了,效果如下:


逐像素漫反射

Shader "Custom/05-Diffuse Fragment" { // 逐像素漫反射 Properties{_Diffuse("Diffuse Color", Color) = (1,1,1,1) // 可在編輯器面板定義材質(zhì)自身色彩 }SubShader{Pass {// 只有定義了正確的LightMode才能得到一些Unity的內(nèi)置光照變量Tags{"LightMode" = "ForwardBase"}CGPROGRAM// 包含unity的內(nèi)置的文件,才可以使用Unity內(nèi)置的一些變量 #include "Lighting.cginc" // 取得第一個直射光的顏色_LightColor0 第一個直射光的位置_WorldSpaceLightPos0(即方向) #pragma vertex vert #pragma fragment fragfixed4 _Diffuse; // 使用屬性struct a2v{float4 vertex : POSITION; // 告訴Unity把模型空間下的頂點坐標填充給vertex屬性float3 normal : NORMAL; // 告訴Unity把模型空間下的法線方向填充給normal屬性float4 texcoord : TEXCOORD0;// 告訴Unity把第一套紋理坐標填充給texcoord屬性 };struct v2f{float4 position : SV_POSITION; // 聲明用來存儲頂點在裁剪空間下的坐標float3 worldNomalDir : COLOR; // 用于存儲世界空間下的法線方向 };// 計算頂點坐標從模型坐標系轉(zhuǎn)換到裁剪面坐標系 v2f vert(a2v v){v2f f;f.position = mul(UNITY_MATRIX_MVP, v.vertex); // UNITY_MATRIX_MVP是內(nèi)置矩陣。該步驟用來把一個坐標從模型空間轉(zhuǎn)換到剪裁空間// 法線方向。把法線方向從模型空間轉(zhuǎn)換到世界空間f.worldNomalDir = (mul(v.normal, (float3x3)unity_WorldToObject)); // 反過來相乘就是從模型到世界,否則是從世界到模型return f;}// 計算每個像素點的顏色值 fixed4 frag(v2f f) : SV_Target {// 環(huán)境光fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;// 法線方向。fixed normalDir = normalize(f.worldNomalDir); // 單位向量// 光照方向。fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); // 對于每個頂點來說,光的位置就是光的方向,因為光是平行光// 漫反射Diffuse顏色 = 直射光顏色 * max(0, cos(光源方向和法線方向夾角)) * 材質(zhì)自身色彩fixed3 diffuse = _LightColor0 * max(0, dot(normalDir, lightDir)) * _Diffuse; // 顏色融合用乘法// 加上環(huán)境光fixed3 tempColor = diffuse + ambient; // 顏色疊加用加法(亮度通常會增加)return fixed4(tempColor, 1); // tempColor是float3已經(jīng)包含了三個數(shù)值 }ENDCG}}FallBack "Diffuse" }

?如下圖,左邊逐像素計算,右邊逐頂點計算,在觀察背光面陰影邊緣時能看出明顯差別,逐頂點計算的陰影過度呈塊狀的。


?半蘭伯特(HalfLambert)光照模型

  • http://www.cnblogs.com/2Yous/p/4206959.htm

直接修改上面frag函數(shù)中漫反射Diffuse顏色的計算公式。

// 計算每個像素點的顏色值 fixed4 frag(v2f f) : SV_Target {// 環(huán)境光fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;// 法線方向。fixed normalDir = normalize(f.worldNomalDir); // 單位向量// 光照方向。fixed3 lightDir = normalize(_WorldSpaceLightPos0.xyz); // 對于每個頂點來說,光的位置就是光的方向,因為光是平行光// 半蘭伯特光照float3 halfLambert = dot(normalDir, lightDir) * 0.5 + 0.5; // 使得背光面不至于為0全黑// 漫反射Diffuse顏色 = 直射光顏色 * max(0, cos(光源方向和法線方向夾角)) * 材質(zhì)自身色彩fixed3 diffuse = _LightColor0 * halfLambert * _Diffuse; // 顏色融合用乘法// 加上環(huán)境光fixed3 tempColor = diffuse + ambient; // 顏色疊加用加法(亮度通常會增加)return fixed4(tempColor, 1); // tempColor是float3已經(jīng)包含了三個數(shù)值}

可以看到在背光面也有了少量光照,明顯沒有旁邊的對照組那么黑。


?注意點:

  • 顏色融合是相乘,顏色疊加是相加(通常亮度會增加)。
  • 逐像素計算光照要比逐頂點計算光照更加消耗性能。

學(xué)習(xí)資料:

  • http://www.sikiedu.com/course/37/task/441/show#

?

與50位技術(shù)專家面對面20年技術(shù)見證,附贈技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的【Unity Shader】三、漫反射Diffuse Shader例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。