日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php開源 > php教程 > 【Unity Shader編程】之十四 邊緣發(fā)光Shader(Rim Shader)的兩種實現(xiàn)形態(tài)

【Unity Shader編程】之十四 邊緣發(fā)光Shader(Rim Shader)的兩種實現(xiàn)形態(tài)

來源:程序員人生   發(fā)布時間:2016-07-15 08:47:45 閱讀次數(shù):5108次



本系列文章由@淺墨_毛星云 出品,轉(zhuǎn)載請注明出處。  
文章鏈接: http://blog.csdn.net/poem_qianmo/article/details/51764028
作者:毛星云(淺墨)    微博:http://weibo.com/u/1723155442
本文工程使用的Unity3D版本: 5.2.1 



這篇文章主要講授了如何在Unity3D中分別使用Surface Shader和Vertex & Fragment Shader來編寫邊沿發(fā)光Shader。

 



1、終究實現(xiàn)的效果

 


邊沿發(fā)光Shader比較直觀的1個應(yīng)用便是摹擬宇宙中的星球效果。將本文實現(xiàn)的邊沿發(fā)光Shader先賦1個Material,此Material再賦給1個球體,加上Galaxy Skybox, 實現(xiàn)的效果以下圖:

 


固然,邊沿發(fā)光Shader也能夠?qū)崿F(xiàn)例如暗黑3中精英怪的高亮效果,將1個怪物模型本身的Shader用邊沿發(fā)光Shader替換,實現(xiàn)效果以下圖:

 

以下是本文實現(xiàn)的Shader在編輯器中的1些效果圖。

        

   





2、Shader實現(xiàn)思路分析

 


思路方面,其實理解起來非常簡單,就是在正常的漫反射Shader的基礎(chǔ)之上,在終究的漫反射色彩值出來以后,再準(zhǔn)備1個自發(fā)光色彩值,附加上去,即得到了終究的帶自發(fā)光的色彩值。

按公式來表達(dá),也就是這樣:

 

終究色彩 = (漫反射系數(shù) x 紋理色彩 x RGB色彩)+自發(fā)光色彩

 

按英文公式來表達(dá),也就是這樣:


FinalColor=(Diffuse x Texture x RGBColor)+Emissive

 

 

 

 

 

3、Surface Shader版邊沿發(fā)光Shader實現(xiàn)



如果讀過這個系列第1篇文章的朋友,應(yīng)當(dāng)還記得這個系列的第1篇文章(傳送門:http://blog.csdn.net/poem_qianmo/article/details/40723789,里面的TheFirstShader,它就是1個標(biāo)準(zhǔn)的使用Unity Surface Shader實現(xiàn)的邊沿發(fā)光Shader。

利用Unity本身的Shader封裝,Surface Shader,也就是Shaderlab,算是新手或想快速上手的童鞋學(xué)習(xí)Unity中Shader書寫的1個非常好的切入點。

這邊貼出經(jīng)過加強(qiáng)的第1期TheFirstShader詳細(xì)注釋后的源代碼。可以發(fā)現(xiàn)里面關(guān)于主要框架的注釋都是中英雙語的,由于發(fā)現(xiàn)很多國外友人也關(guān)注了我在Github上的Shader repo(https://github.com/QianMo/Awesome-Unity-Shader),為了方便他們和后面更多的國外友人,以后如果周末寫博客的時間充裕,就干脆寫中英雙語的注釋得了。

OK,詳細(xì)注釋后的Surface Shader版可發(fā)光Shader源代碼以下:

Shader "Learning Unity Shader/Lecture 14/Surface Rim Shader" { //-----------------------------------【屬性 || Properties】------------------------------------------ Properties { //主色彩 || Main Color _MainColor("【主色彩】Main Color", Color) = (0.5,0.5,0.5,1) //漫反射紋理 || Diffuse Texture _MainTex("【紋理】Texture", 2D) = "white" {} //凹凸紋理 || Bump Texture _BumpMap("【凹凸紋理】Bumpmap", 2D) = "bump" {} //邊沿發(fā)光色彩 || Rim Color _RimColor("【邊沿發(fā)光色彩】Rim Color", Color) = (0.17,0.36,0.81,0.0) //邊沿發(fā)光強(qiáng)度 ||Rim Power _RimPower("【邊沿色彩強(qiáng)度】Rim Power", Range(0.6,36.0)) = 8.0 //邊沿發(fā)光強(qiáng)度系數(shù) || Rim Intensity Factor _RimIntensity("【邊沿色彩強(qiáng)度系數(shù)】Rim Intensity", Range(0.0,100.0)) = 1.0 } //----------------------------------【子著色器 || SubShader】--------------------------------------- SubShader { //渲染類型為Opaque,不透明 || RenderType Opaque Tags { "RenderType" = "Opaque" } //-------------------------開啟CG著色器編程語言段 || Begin CG Programming Part---------------------- CGPROGRAM //【1】聲明使用蘭伯特光照模式 ||Using the Lambert light mode #pragma surface surf Lambert //【2】定義輸入結(jié)構(gòu) || Input Struct struct Input { //紋理貼圖 || Texture float2 uv_MainTex; //法線貼圖 || Bump Texture float2 uv_BumpMap; //視察方向 || Observation direction float3 viewDir; }; //【3】變量聲明 || Variable Declaration //邊沿色彩 float4 _MainColor; //主紋理 sampler2D _MainTex; //凹凸紋理 sampler2D _BumpMap; //邊沿色彩 float4 _RimColor; //邊沿色彩強(qiáng)度 float _RimPower; //邊沿色彩強(qiáng)度 float _RimIntensity; //【4】表面著色函數(shù)的編寫 || Writing the surface shader function void surf(Input IN, inout SurfaceOutput o) { //表面反射色彩為紋理色彩 o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb*_MainColor.rgb; //表面法線為凹凸紋理的色彩 o.Normal = UnpackNormal(tex2D(_BumpMap, IN.uv_BumpMap)); //邊沿色彩 half rim = 1.0 - saturate(dot(normalize(IN.viewDir), o.Normal)); //計算出邊沿色彩強(qiáng)度系數(shù) o.Emission = _RimColor.rgb * pow(rim, _RimPower)*_RimIntensity; } //-------------------結(jié)束CG著色器編程語言段 || End CG Programming Part------------------ ENDCG } //后備著色器為普通漫反射 || Fallback use Diffuse Fallback "Diffuse" }

 

略微揣摩1下就明白,此Shader其實就是用利用了Unity5中封裝好的Standard Surface Output結(jié)構(gòu)體中的Emission(自發(fā)光)屬性,來到達(dá)這樣的邊沿光效果,技術(shù)含量很有限。這邊附1下Unity5中的SurfaceOutputStandard原型:

 

// Unity5 SurfaceOutputStandard原型: struct SurfaceOutputStandard { fixed3 Albedo; // 漫反射色彩 fixed3 Normal; // 切線空間法線 half3 Emission; //自發(fā)光 half Metallic; // 金屬度;取0為非金屬, 取1為金屬 half Smoothness; // 光澤度;取0為非常粗糙, 取1為非常光滑 half Occlusion; // 遮擋(默許值為1) fixed Alpha; // 透明度 };


將此Shader賦給Material后在編輯器效果圖:




 

 里面有6個參數(shù),包括主色彩、紋理、凹凸紋理、邊沿發(fā)光色彩、邊沿色彩強(qiáng)度、邊沿色彩強(qiáng)度系數(shù)這6個參數(shù)可以定制與調(diào)理,只要貼圖資源到位,就很容易可以調(diào)出自己滿意的效果來。



 

 


4、可編程Shader版邊沿發(fā)光Shader的實現(xiàn)



這篇文章核心主要就是實現(xiàn)本節(jié)的這個可編程(也就是Vertex & Fragment Shader)邊沿發(fā)光Shader。大家知道,Vertex & Fragment Shader是比Surface Shader更高1段位的實現(xiàn)形態(tài),有更大的可控性,更好的可編程性,可以實現(xiàn)更加豐富的效果,是更貼近CG著色語言的1種Shader形態(tài)。

OK,直接貼出經(jīng)過詳細(xì)注釋的Vertex & Fragment Shader版邊沿發(fā)光Shader實現(xiàn)源代碼:

 

Shader "Learning Unity Shader/Lecture 14/Basic Rim Shader" { //-----------------------------------【屬性 || Properties】------------------------------------------ Properties { //主色彩 || Main Color _MainColor("【主色彩】Main Color", Color) = (0.5,0.5,0.5,1) //漫反射紋理 || Diffuse Texture _TextureDiffuse("【漫反射紋理】Texture Diffuse", 2D) = "white" {} //邊沿發(fā)光色彩 || Rim Color _RimColor("【邊沿發(fā)光色彩】Rim Color", Color) = (0.5,0.5,0.5,1) //邊沿發(fā)光強(qiáng)度 ||Rim Power _RimPower("【邊沿發(fā)光強(qiáng)度】Rim Power", Range(0.0, 36)) = 0.1 //邊沿發(fā)光強(qiáng)度系數(shù) || Rim Intensity Factor _RimIntensity("【邊沿發(fā)光強(qiáng)度系數(shù)】Rim Intensity", Range(0.0, 100)) = 3 } //----------------------------------【子著色器 || SubShader】--------------------------------------- SubShader { //渲染類型為Opaque,不透明 || RenderType Opaque Tags { "RenderType" = "Opaque" } //---------------------------------------【唯1的通道 || Pass】------------------------------------ Pass { //設(shè)定通道名稱 || Set Pass Name Name "ForwardBase" //設(shè)置光照模式 || LightMode ForwardBase Tags { "LightMode" = "ForwardBase" } //-------------------------開啟CG著色器編程語言段 || Begin CG Programming Part---------------------- CGPROGRAM //【1】指定頂點和片斷著色函數(shù)名稱 || Set the name of vertex and fragment shader function #pragma vertex vert #pragma fragment frag //【2】頭文件包括 || include #include "UnityCG.cginc" #include "AutoLight.cginc" //【3】指定Shader Model 3.0 || Set Shader Model 3.0 #pragma target 3.0 //【4】變量聲明 || Variable Declaration //系統(tǒng)光照色彩 uniform float4 _LightColor0; //主色彩 uniform float4 _MainColor; //漫反射紋理 uniform sampler2D _TextureDiffuse; //漫反射紋理_ST后綴版 uniform float4 _TextureDiffuse_ST; //邊沿光色彩 uniform float4 _RimColor; //邊沿光強(qiáng)度 uniform float _RimPower; //邊沿光強(qiáng)度系數(shù) uniform float _RimIntensity; //【5】頂點輸入結(jié)構(gòu)體 || Vertex Input Struct struct VertexInput { //頂點位置 || Vertex position float4 vertex : POSITION; //法線向量坐標(biāo) || Normal vector coordinates float3 normal : NORMAL; //1級紋理坐標(biāo) || Primary texture coordinates float4 texcoord : TEXCOORD0; }; //【6】頂點輸出結(jié)構(gòu)體 || Vertex Output Struct struct VertexOutput { //像素位置 || Pixel position float4 pos : SV_POSITION; //1級紋理坐標(biāo) || Primary texture coordinates float4 texcoord : TEXCOORD0; //法線向量坐標(biāo) || Normal vector coordinates float3 normal : NORMAL; //世界空間中的坐標(biāo)位置 || Coordinate position in world space float4 posWorld : TEXCOORD1; //創(chuàng)建光源坐標(biāo),用于內(nèi)置的光照 || Function in AutoLight.cginc to create light coordinates LIGHTING_COORDS(3,4) }; //【7】頂點著色函數(shù) || Vertex Shader Function VertexOutput vert(VertexInput v) { //【1】聲明1個頂點輸出結(jié)構(gòu)對象 || Declares a vertex output structure object VertexOutput o; //【2】填充此輸出結(jié)構(gòu) || Fill the output structure //將輸入紋理坐標(biāo)賦值給輸出紋理坐標(biāo) o.texcoord = v.texcoord; //獲得頂點在世界空間中的法線向量坐標(biāo) o.normal = mul(float4(v.normal,0), _World2Object).xyz; //取得頂點在世界空間中的位置坐標(biāo) o.posWorld = mul(_Object2World, v.vertex); //獲得像素位置 o.pos = mul(UNITY_MATRIX_MVP, v.vertex); //【3】返回此輸出結(jié)構(gòu)對象 || Returns the output structure return o; } //【8】片斷著色函數(shù) || Fragment Shader Function fixed4 frag(VertexOutput i) : COLOR { //【8.1】方向參數(shù)準(zhǔn)備 || Direction //視角方向 float3 ViewDirection = normalize(_WorldSpaceCameraPos.xyz - i.posWorld.xyz); //法線方向 float3 Normalection = normalize(i.normal); //光照方向 float3 LightDirection = normalize(_WorldSpaceLightPos0.xyz); //【8.2】計算光照的衰減 || Lighting attenuation //衰減值 float Attenuation = LIGHT_ATTENUATION(i); //衰減后色彩值 float3 AttenColor = Attenuation * _LightColor0.xyz; //【8.3】計算漫反射 || Diffuse float NdotL = dot(Normalection, LightDirection); float3 Diffuse = max(0.0, NdotL) * AttenColor + UNITY_LIGHTMODEL_AMBIENT.xyz; //【8.4】準(zhǔn)備自發(fā)光參數(shù) || Emissive //計算邊沿強(qiáng)度 half Rim = 1.0 - max(0, dot(i.normal, ViewDirection)); //計算出邊沿自發(fā)光強(qiáng)度 float3 Emissive = _RimColor.rgb * pow(Rim,_RimPower) *_RimIntensity; //【8.5】計在終究色彩中加入自發(fā)光色彩 || Calculate the final color //終究色彩 = (漫反射系數(shù) x 紋理色彩 x rgb色彩)+自發(fā)光色彩 || Final Color=(Diffuse x Texture x rgbColor)+Emissive float3 finalColor = Diffuse * (tex2D(_TextureDiffuse,TRANSFORM_TEX(i.texcoord.rg, _TextureDiffuse)).rgb*_MainColor.rgb) + Emissive; //【8.6】返回終究色彩 || Return final color return fixed4(finalColor,1); } //-------------------結(jié)束CG著色器編程語言段 || End CG Programming Part------------------ ENDCG } } //后備著色器為普通漫反射 || Fallback use Diffuse FallBack "Diffuse" }

 相信很多朋友已看出來了,與普通的漫反射Shader相比,這個Shader的魔力就在于多出了“8.4準(zhǔn)備自發(fā)光參數(shù)”和“8.5在終究色彩中加入自發(fā)光色彩"兩個步驟而已,前面都是普通的Vertex & Fragment Shader常規(guī)寫法。


將此Shader賦給Material,得到的效果以下:

  

 

  


固然,你也能夠?qū)⑦@兩個Shader用于場景中各種模型,以下是1組效果圖:

 









OK,這篇文章的內(nèi)容大致如此。我們下篇文章,再會。




附: 本文配套源碼下載鏈接


【Github】本文Shader源碼


生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 亚洲三级在线 | 国产成人精品av在线 | 九九九九色 | 久久中文字幕一区二区 | 美女视频免费一区二区 | 婷婷久久五月天 | 超碰www| 久久久国产精品 | 亚洲播播 | 免费一级毛片在线观看 | 欧美日韩中文在线观看 | jzzujzz少亚洲成熟少妇 | 中文字幕亚洲第一 | 精品久久一区二区三区 | 国产免费小视频 | 日韩欧美一区二区三区 | 久久色av | 在线中文视频 | 国产在线观看一区二区三区 | 国产精品尤物 | 能看的av| 91伦理视频在线观看 | 欧美专区在线观看 | 一区久久| 亚洲精品卡一 | 日韩国产| 一级黄色av | 国产精品无码专区在线观看 | 久久亚洲成人 | 91亚洲精品中文字幕 | 91亚洲精品一区二区 | 精品成人国产 | 国产黄在线观看 | 天天干天天摸 | 成年人免费在线视频 | 亚洲一区二区三区中文字幕 | 免费看的av | 亚洲性视频在线 | 精品国产网站 | 国产精品色综合一区二区三区 | 高清国产一区二区三区四区五区 |