【Unity Shaders】遊戲性和畫面特效——建立一個夜視效果的畫面特效,unityshaders
本系列主要參考《Unity Shaders and Effects Cookbook》一書(感謝原書作者),同時會加上一點個人理解或拓展。
這裡是本書所有的插圖。這裡是本書所需的代碼和資源(當然你也可以從官網下載)。
========================================== 分割線 ==========================================
寫在前面
嗚呼,這本書最後一篇了有木有!!!想想就有點小激動呢。。。(可是還有很多隔過去了。)技術文章裡就不說太多廢話了,之後會寫一篇總結的,坑也會慢慢補上的(我希望吧。)。
好啦!我們本節要學習的特效是一個更加常見的畫面特效。在市場上很多的第一人稱射擊遊戲(FPS)中,我們都可以看到夜視效果的身影,比如《使命召喚》、《光暈》等等。這種效果使螢幕蒙上一層非常獨特的黃綠色。下面是《使命召喚》中的夜視效果:
為了實現這種夜視效果,我們需要使用Photoshop來分解上述效果的實現。我們可以從網上找一些參考圖片,然後和已有圖層合并,看看我們需要哪種混合效果,以及我們要怎樣組合不同的圖層。下面的映像顯示了在Photoshop中進行上述過程的最後結果:
而最後Shader實現的結果像下面這樣:
下面,我們開始將Photoshop中的最終映像分解成幾個部分,來更好的理解這些資源是如何被整合在一起的。而後,我們會深入講解實現過程。
準備工作
之前說過,使用Photoshop可以讓我們方便地構分層映像,以便我們可以更好地理解如何得到一個夜視效果。現在,我們就把夜視效果分解成幾個組成圖層。
- 偏綠色的畫面(Tinted green):夜視效果的第一個圖層就是它標誌性的綠色,幾乎所有的夜視映像都是這種色調的。這可以讓我們的特效看起來就是明顯的夜視效果。
- 掃描線(Scan lines):為了增加夜視效果的真實性,我們在上述著色層的上面添加了一層掃描線。在這裡,我們使用了一張用Photoshop建立的紋理,然後讓使用者選擇平鋪係數來控制掃描線的寬窄和大小。
- 噪點(Noise):下一個圖層是一個簡單的噪點圖層,它平鋪在上述兩種圖層的上方,用於分解映像為我們的特效添加更多的細節效果。
- 暈影(Vignette):夜視效果的最後一層就是暈影。從上面《使命召喚》的遊戲可以看出,它使用一個暈影來類比一個視野效果。我們使用下面的圖層來作為暈影紋理。
現在,我們把上述各個紋理結合在一起,開始正式建立夜視效果的畫面特效。
實現
現在你的畫面特效指令碼系統應該已經建立好了,現在我們來實現具體的指令碼和Shader。
首先,我們來填寫NightVisionEffect.cs指令碼的主要代碼。接下來,我們來實現關鍵的Shader部分。
完整的指令碼和Shader如下:
NightVisionEffect指令碼:
using UnityEngine;using System.Collections;[ExecuteInEditMode]public class NightVisionEffect : MonoBehaviour {#region Variablespublic Shader nightVisionShader;public float contrast = 2.0f;public float brightness = 1.0f;public Color nightVisionColor = Color.white;public Texture2D vignetteTexture;public Texture2D scanLineTexture;public float scanLineTileAmount = 4.0f;public Texture2D nightVisionNoise;public float noiseXSpeed = 100.0f;public float noiseYSpeed = 100.0f;public float distortion = 0.2f;public float scale = 0.8f;private Material curMaterial;private float randomValue = 0.0f;#endregion#region Propertiespublic Material material {get {if (curMaterial == null) {curMaterial = new Material(nightVisionShader);curMaterial.hideFlags = HideFlags.HideAndDontSave;}return curMaterial;}}#endregion// Use this for initializationvoid Start () {if (SystemInfo.supportsImageEffects == false) {enabled = false;return;}if (nightVisionShader != null && nightVisionShader.isSupported == false) {enabled = false;}}void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){if (nightVisionShader != null) {material.SetFloat("_Contrast", contrast);material.SetFloat("_Brightness", brightness);material.SetColor("_NightVisionColor", nightVisionColor);material.SetFloat("_RandomValue", randomValue);material.SetFloat("_Distortion", distortion);material.SetFloat("_Scale", scale);if (vignetteTexture) {material.SetTexture("_VignetteTex", vignetteTexture);}if (scanLineTexture) {material.SetTexture("_ScanLineTex", scanLineTexture);material.SetFloat("_ScanLineTileAmount", scanLineTileAmount);}if (nightVisionNoise) {material.SetTexture("_NoiseTex", nightVisionNoise);material.SetFloat("_NoiseXSpeed", noiseXSpeed);material.SetFloat("_NoiseYSpeed", noiseYSpeed);}Graphics.Blit(sourceTexture, destTexture, material);} else {Graphics.Blit(sourceTexture, destTexture);}}// Update is called once per framevoid Update () {contrast = Mathf.Clamp(contrast, 0.0f, 4.0f);brightness = Mathf.Clamp(brightness, 0.0f, 2.0f);distortion = Mathf.Clamp(distortion, -1.0f, 1.0f);scale = Mathf.Clamp(scale, 0.0f, 3.0f);randomValue = Random.Range(-1.0f, 1.0f);}void OnDisable () {if (curMaterial != null) {DestroyImmediate(curMaterial);}}}
NightVisionEffectShader如下:
Shader "Custom/NightVisionEffectShader" {Properties {_MainTex ("Base (RGB)", 2D) = "white" {}_VignetteTex ("Vignette Texture", 2D) = "white" {}_ScanLineTex ("Scan Line Texture", 2D) = "white" {}_ScanLineTileAmount ("Scale Line Tile Amount", Float) = 4.0_NoiseTex ("Noise Texture", 2D) = "white" {}_NoiseXSpeed ("Noise X Speed", Float) = 100.0_NoiseYSpeed ("Noise Y Speed", Float) = 100.0_NightVisionColor ("Night Vision Color", Color) = (1, 1, 1, 1)_Contrast ("Contrast", Range(0, 4)) = 2_Brightness ("Brightness", Range(0, 2)) = 1_RandomValue ("Random Value", Float) = 0_Distortion ("Distortion", Float) = 0.2_Scale ("Scale (Zoom)", Float) = 0.8}SubShader {Pass {CGPROGRAM#pragma vertex vert_img#pragma fragment frag#include "UnityCG.cginc"uniform sampler2D _MainTex;uniform sampler2D _VignetteTex;uniform sampler2D _ScanLineTex;fixed _ScanLineTileAmount;uniform sampler2D _NoiseTex;fixed _NoiseXSpeed;fixed _NoiseYSpeed;fixed4 _NightVisionColor;fixed _Contrast;fixed _Brightness;fixed _RandomValue;fixed _Distortion;fixed _Scale;float2 barrelDistortion(float2 coord) {// Lens distortion algorithm// See http://www.ssontech.com/content/lensalg.htmfloat2 h = coord.xy - float2(0.5, 0.5);float r2 = h.x * h.x + h.y * h.y;float f = 1.0 + r2 * (_Distortion * sqrt(r2));return f * _Scale * h + 0.5;}fixed4 frag(v2f_img i) : COLOR {// Get the colors from the Render Texture and the uv's// from the v2f_img structhalf2 distortedUV = barrelDistortion(i.uv);fixed4 renderTex = tex2D(_MainTex, distortedUV);fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);// Process scan lines and noisehalf2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount);fixed4 scanLineTex = tex2D(_ScanLineTex, scanLinesUV);half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed),i.uv.y + (_Time.x * _NoiseYSpeed));fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);// Get the luminosity values from the render texture using the YIQ valuesfixed lum = dot(fixed3(0.299, 0.587, 0.114), renderTex.rgb);lum += _Brightness;fixed4 finalColor = (lum * 2) + _NightVisionColor;// Final outputfinalColor = pow(finalColor, _Contrast);finalColor *= vignetteTex;finalColor *= scanLineTex * noiseTex;return finalColor;}ENDCG}} FallBack "Diffuse"}
完成後返回Unity編輯器查看效果。我們需要在面板中設定對應的圖片和屬性,像下面這樣:
擴充連結
關於透鏡形變效果:
- http://www.ssontech.com/content/lensalg.html
對於開發單機遊戲要的職業
你好!以下為答案~(關於職業嘛 本人覺得主要是對BC和C語言資深的人士...)
一、遊戲程式開發的工作主要包括哪些方面
遊戲開發中的程式開發主要由如下幾個方面組成:
1.圖形引擎
2.聲音引擎
3.物理引擎
4.遊戲引擎
5.人工智慧或遊戲邏輯
6.遊戲GUI介面(菜單)
7.遊戲開發工具
8.支援區域網路對戰的網路引擎開發
9.支援互連網對戰的網路引擎開發
下面逐一介紹每個部分:
1.圖形引擎主要包含遊戲中的情境(室內或室外)管理與渲染,角色的動作管理繪製,特效管理與渲染(粒子系統,自然類比(如水紋,植物等類比)),光照和材質處理,LOD(Level Object Detail)管理等,另外還有圖形資料轉換工具開發,這些工具主要用於把美工用DCC軟體(如3DS Max,Maya,Soft XSI,Soft Image3D等)軟體製作的模型和動作資料以及用Photo shop或painter等工具製作的貼圖,轉化成遊戲程式中用的資源檔。
2.聲音引擎主要包含音效(Sound Effect簡稱SE),語音(VOICE),背景音樂(Background music簡稱BGM)的播放。SE是指那些在遊戲中頻繁播放,而且播放時間比較短,但要求能及時無延遲的播放,VOICE是指遊戲中的語音或人聲,這部分對聲音品質要求比較高,基本上用比較高的採樣率錄製和回放聲音,但和SE一樣要求能及時無延遲的播放,SE在有的時候因為記憶體容量的問題,在不影響效果的前提下,可能會降低採樣率,但VOICE由於降低採樣率對效果影響比較大,所以一般VOICE不採用降低採樣率的做法。BGM是指遊戲中一長段迴圈播放(也有不迴圈,只播放一次)的背景音樂,正是由於BGM的這種特性,一般遊戲的背景音樂是讀盤(光碟片或硬碟)來播放。另外一些進階聲音特效,如EAX,數字影院系統(DTS5.1),數字杜比環繞等。
3.物理引擎主要包含遊戲世界中的物體之間、物體和情境之間發生碰撞後的力學類比, 以及發生碰撞後的物體骨骼運動的力學類比(比較著名的物理引擎有havok公司的game dynamics sdk,還有open source 的ODE—Open Dynamics Engine)。
4.遊戲引擎主要是把圖形引擎、聲音引擎、物理引擎整合起來,主要針對某個遊戲製作一個遊戲系統,其包含遊戲關卡編輯器,主要用途是可以可視化的對情境進行調整,光照效果和霧化等效果調整,事件設定,道具擺放,NPC設定,另外還有角色編輯器,主要用於編輯角色的屬性和檢查動作資料的正確性。一般日本遊戲公司的做法,他們會把關卡編輯器和角色編輯器直接做到遊戲中,所有的參數調整都在遊戲中通過調試菜單來進行編輯,所以一般他們把這部分調試菜單的功能做的很強大,同時在螢幕上即時的顯示一些重要的資訊,這樣做的好處是關卡編輯器調整的效果直接就是遊戲的效果,但是對於程式的重用性來說可能不是很好,比如說要用到另外一個遊戲項目中就比較難,除非兩個遊戲類型相同,只要把情境和角色資料換一下,還有做下一代產品也沒有問題,只要根據式樣增加調試菜單的功能就可以了。
5.人工智慧和遊戲邏輯開發,這部分日本和歐美的遊戲開發模式也有很大不同,在歐美遊戲公司中運用指令碼語言開發很普遍,所以這部分程式開發主要是用指令碼語言編寫,而且指令碼程式和遊戲程式的耦合性很低,有單獨的編輯、編譯和調試環境,這樣比較利於遊戲程式和關卡設計開發分開,同時並行開發,所以一般他們都會有專門做關卡設計的程式員崗位。而日......餘下全文>>