亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

C#使用Shader實現夜幕降臨倒計時的效果

2020-01-24 00:57:36
字體:
來源:轉載
供稿:網友

最近火爆全球的PC游戲Battlerite(戰爭儀式)在倒計時的會生成一種類似夜幕降臨的效果,會以戰場中心為圓心,某個長度為半徑的范圍外是暗的,而這個半徑會逐漸縮小,而圓之外的陰暗部分是附著地形的,本文就嘗試使用屏幕后處理的手段來實現這種效果。

(暫時缺少Battlerite的截圖,稍后會補上)

首先看效果圖:

注:本文參考了Tasharen Fog of War插件

創建一個C#腳本,命名為NightFall.cs,為NightFall類創建一些公共變量(nightColor,center和radius),另外還需要一個NightFall.shader。

首先,我們要確定這個效果是在場景渲染之后還未送到屏幕顯示之前的實現的,所以,NightFall腳本是要掛載到主Camera上的(添加特性[RequireComponent(typeof(Camera))]),并要實現OnRenderImage方法。

其次,在OnRenderImage方法里,我們最終需要調用Graphics.Blit方法,而這個方法的第三個參數是Material類型,所以我們需要在代碼里創建一個臨時材質,這個材質使用了NightFall.shader。

再次,我們需要在Shader里面將屏幕坐標轉換為世界坐標,來計算與世界中心的坐標,所以我們需要MVP的逆矩陣(參考Shader山下(十六)坐標空間與轉換矩陣)。

最后,為了附著地形,我們需要在Shader計算深度,也就是坐標點與攝像機的相對距離,所以需要攝像機的位置。

C#的代碼:

using UnityEngine;

[RequireComponent(typeof(Camera))] public class NightFall : MonoBehaviour { public Shader shader; public Color nightColor = new Color(0.05f, 0.05f, 0.05f, 0.5f); public Vector3 center = Vector3.zero; public float radius = 10; Camera mCam; Matrix4x4 mInverseMVP; Material mMat; /// The camera we're working with needs depth. void OnEnable () { mCam = GetComponent<Camera>(); mCam.depthTextureMode = DepthTextureMode.Depth; if (shader == null) shader = Shader.Find("Image Effects/NightFall"); } /// Destroy the material when disabled. void OnDisable () { if (mMat) DestroyImmediate(mMat); } /// Automatically disable the effect if the shaders don't support it. void Start () { if (!SystemInfo.supportsImageEffects || !shader || !shader.isSupported) { enabled = false; } } // Called by camera to apply image effect void OnRenderImage (RenderTexture source, RenderTexture destination) { print (nightColor); print (destination); // Calculate the inverse modelview-projection matrix to convert screen coordinates to world coordinates mInverseMVP = (mCam.projectionMatrix * mCam.worldToCameraMatrix).inverse; if (mMat == null) { mMat = new Material(shader); mMat.hideFlags = HideFlags.HideAndDontSave; } Vector4 camPos = mCam.transform.position; // This accounts for Anti-aliasing on Windows flipping the depth UV coordinates. // Despite the official documentation, the following approach simply doesn't work: // http://docs.unity3d.com/Documentation/Components/SL-PlatformDifferences.html if (QualitySettings.antiAliasing > 0) { RuntimePlatform pl = Application.platform; if (pl == RuntimePlatform.WindowsEditor || pl == RuntimePlatform.WindowsPlayer || pl == RuntimePlatform.WindowsWebPlayer) { camPos.w = 1f; } } mMat.SetVector("_CamPos", camPos); mMat.SetMatrix("_InverseMVP", mInverseMVP); mMat.SetColor("_NightColor", nightColor); mMat.SetVector ("_Center", center); mMat.SetFloat ("_Radius", radius); Graphics.Blit(source, destination, mMat); } }

Shader代碼:

Shader "Image Effects/NightFall" { Properties { _NightColor ("Night Color", Color) = (0.05, 0.05, 0.05, 0.05) _Center ("Center", Vector) = (0,0,0,0) _Radius ("Radius", float) = 10 } SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } Blend SrcAlpha OneMinusSrcAlpha CGPROGRAM #pragma vertex vert_img #pragma fragment frag vertex:vert #pragma fragmentoption ARB_precision_hint_fastest #include "UnityCG.cginc" sampler2D _CameraDepthTexture; uniform float4x4 _InverseMVP; uniform float4 _CamPos; uniform half4 _NightColor; uniform half4 _Center; uniform half _Radius; struct Input { float4 position : POSITION; float2 uv : TEXCOORD0; }; void vert (inout appdata_full v, out Input o) { o.position = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord.xy; } float3 CamToWorld (in float2 uv, in float depth) { float4 pos = float4(uv.x, uv.y, depth, 1.0); pos.xyz = pos.xyz * 2.0 - 1.0; pos = mul(_InverseMVP, pos); return pos.xyz / pos.w; } fixed4 frag (Input i) : COLOR { #if SHADER_API_D3D9 || SHADER_API_D3D11 float2 depthUV = i.uv; depthUV.y = lerp(depthUV.y, 1.0 - depthUV.y, _CamPos.w); float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, depthUV)); float3 pos = CamToWorld(depthUV, depth); #else float depth = UNITY_SAMPLE_DEPTH(tex2D(_CameraDepthTexture, i.uv)); float3 pos = CamToWorld(i.uv, depth); #endif // Limit to sea level if (pos.y < 0.0) { // This is a simplified version of the ray-plane intersection formula: t = -( N.O + d ) / ( N.D ) float3 dir = normalize(pos - _CamPos.xyz); pos = _CamPos.xyz - dir * (_CamPos.y / dir.y); } half4 col; float dis = length(pos.xz - _Center.xz); if (dis < _Radius) { col = fixed4(0,0,0,0); } else { col = _NightColor; } return col; } ENDCG } } Fallback off }

需要說明的幾個點:

1、因為平臺差異性,為了兼容Direct3D,所以在C#和shader里通過CamPos(_CamPos)的w分量來調整uv坐標。

2、這里雖然沒有聲明_MainTex,但是_MainTex實際上就是即將成像的屏幕圖像,所以這里的i.uv也就是指屏幕圖像的紋理坐標。

3、_CameraDepthTexture是攝像機的深度紋理,通過UNITY_SAMPLE_DEPTH方法獲取深度。

4、CamToWorld里面,先是根據uv坐標和深度depth創建了一個float4的坐標值pos,然后對pos乘2減1是將這個坐標范圍從[0,1]轉換到了[-1,1],對應世界坐標。然后使用傳入的MVP逆矩陣_InverseMVP乘以這個坐標值,就得到了屏幕點的世界坐標。最后將pos的xyz分量除以w分量,這里w分量表示因為遠近而產生的縮放值。

5、在計算過世界坐標之后,對于y小于0的坐標要做一下處理,將效果限制在海平面(sea level)之上,使用射線平面相交方程(ray-plane intersection formula)的簡化版本來處理。

6、最后根據距離返回色彩值。

如果要實現夜幕降臨倒計時的效果,只需要在控制腳本(C#)中獲取Camera上的NightFall組件,根據時間修改radius變量即可。

以上所述是小編給大家介紹的C#使用Shader實現夜幕降臨倒計時的效果,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
夜夜嗨av一区二区三区四区| 亚洲欧美国内爽妇网| 久久久久久久久久亚洲| 久久91亚洲精品中文字幕| 亚洲老头同性xxxxx| 成人午夜在线影院| 欧美精品久久久久久久久| 欧美日韩综合视频网址| 亚洲精品国产精品国自产观看浪潮| 精品中文视频在线| 成人午夜激情免费视频| 亚洲精品一区在线观看香蕉| 成人黄色片网站| 亚洲男人天天操| 亚洲精品美女网站| 日韩精品极品毛片系列视频| 国产亚洲日本欧美韩国| 久久久国产91| 国产精品99久久99久久久二8| 韩国欧美亚洲国产| 国产精品视频大全| 91成人精品网站| 日韩成人性视频| 国产精品一区二区3区| 在线国产精品播放| 亚洲欧美精品在线| 日韩成人在线视频| 亚洲色图激情小说| 97av在线播放| 精品国产自在精品国产浪潮| 久久精品福利视频| 精品国产一区二区三区久久久狼| 欧美激情精品久久久久久久变态| 欧美日韩国产激情| 91精品久久久久| 国产精品久久久久9999| 亚洲成人精品久久久| 亚洲精品久久久久久久久久久| 国产+成+人+亚洲欧洲| 午夜精品在线视频| 69国产精品成人在线播放| 欧美专区第一页| 亚洲天堂第二页| 亚洲精品国产品国语在线| 国产午夜一区二区| 久久久国产精品x99av| 久久久久中文字幕| 精品国产一区二区在线| 国产女同一区二区| 亚洲bt欧美bt日本bt| 欧美激情综合色综合啪啪五月| 亚洲黄色在线看| 欧美有码在线观看视频| 97色伦亚洲国产| 欧美高清在线观看| 久久免费视频这里只有精品| 久久影视三级福利片| 国产精品中文字幕久久久| 91精品免费久久久久久久久| 欧美大片欧美激情性色a∨久久| 久久成人人人人精品欧| 亚洲www在线观看| 久久中文字幕一区| 国产成人高潮免费观看精品| 中文字幕亚洲情99在线| 国模叶桐国产精品一区| 青草青草久热精品视频在线网站| 中文字幕日本欧美| 亚洲激情中文字幕| 欧美精品日韩三级| 中文字幕日韩av综合精品| 亚洲精品久久久久久久久久久| 日本高清不卡在线| 国产97在线|亚洲| 亚洲人成电影在线| 国产精品亚洲一区二区三区| 久久亚洲精品一区| 亚洲美女av网站| 久久精品色欧美aⅴ一区二区| 国产日产欧美a一级在线| 色偷偷av一区二区三区乱| 色综合视频网站| 精品国产91久久久久久| 国产精品青青在线观看爽香蕉| 国产精品爽黄69天堂a| 日韩成人中文字幕在线观看| 国产欧美日韩亚洲精品| 久久久久久国产精品久久| 亚洲一区二区三区视频| 亚洲视频免费一区| 国外日韩电影在线观看| 国产91色在线播放| 91精品久久久久久久久中文字幕| 国产美女精彩久久| 日韩精品极品在线观看| 91色精品视频在线| 久久综合久久88| 欧美日韩一区二区精品| 68精品久久久久久欧美| 精品美女国产在线| 日韩高清不卡av| 不卡av在线网站| 欧美日韩成人精品| 亚洲一区二区三区xxx视频| 91啪国产在线| 久久亚洲私人国产精品va| 日韩免费看的电影电视剧大全| 久久韩剧网电视剧| 亚洲国模精品一区| 国产精品一区二区3区| 91高清免费在线观看| 久久免费视频网| 国产亚洲欧美视频| 日韩欧美精品中文字幕| 久久夜色精品国产欧美乱| 久久精品国产亚洲精品| 欧亚精品中文字幕| 中文字幕亚洲字幕| 欧美极品在线视频| 中文字幕欧美精品日韩中文字幕| 欧美中文在线观看| 精品亚洲va在线va天堂资源站| 亚洲激情国产精品| 国产精品久久久久久久一区探花| 日韩一二三在线视频播| 久久久久中文字幕2018| 欧美激情成人在线视频| 久久久久久久97| 国产日韩精品在线播放| 国产丝袜一区二区| 国产免费久久av| 欧美日韩福利在线观看| 欧美大片第1页| 亚洲国产精品va在看黑人| 久久这里只有精品视频首页| 欧美亚洲国产日韩2020| 色综合导航网站| 原创国产精品91| 欧美日韩一区二区三区在线免费观看| 色播久久人人爽人人爽人人片视av| 日韩av电影在线免费播放| 精品久久久久久久久国产字幕| 亚洲级视频在线观看免费1级| 欧美午夜精品伦理| 777777777亚洲妇女| 久久夜精品香蕉| 精品久久久久久久久久久久久| 亚洲国产欧美日韩精品| 欧美电影免费在线观看| 国产999精品久久久| 国产精品你懂得| 中文字幕久久久| 精品无人区太爽高潮在线播放| 欧美精品制服第一页| 91av在线播放| 一区国产精品视频| 精品视频久久久久久| 爽爽爽爽爽爽爽成人免费观看| 日韩欧美精品中文字幕| 色老头一区二区三区在线观看| 国产精品日韩专区| 中文字幕视频一区二区在线有码| 欧美精品国产精品日韩精品| 91久久精品日日躁夜夜躁国产|