1. 程式人生 > >unity之shader

unity之shader

unit 光照 面板 直接 固定 檢查 接收 cpu 映射

1.渲染流水線

任務:從一個三維場景出發,生成(或者渲染)一張二維圖像。即:計算機需要從一系列的定點出數據,紋理等信息出發,把這些信息最終轉換程一張人眼可以看到的圖像。而這個工作通常是由CPU和GPU共同完成的。

三個階段:

(1)應用階段(CPU):1.準備場景數據。2.粗粒度剔除工作。3設置模型的渲染狀態,輸出渲染所需要的幾何信息.

應用階段大致可以分為三個階段:

1.把數據加載到顯存中。

2.設置渲染狀態。渲染狀態:定義場景中的網格是怎樣被渲染的。如:使用那個頂點著色器/片元著色器。

3.調用DrawCall。DrawCall是一個命令,發起方為CPU,接收方為GPU。

(2)幾何階段:把定點坐標變換到屏幕空間中,再交給光柵器進行處理。對輸入的渲染圖源進行多部處理後,將會輸出屏幕空間的二維頂點坐標,每個定點對應的深度值,著色等相關信息。

(3)光柵化階段:產生屏幕上的像素,並渲染最終的圖像。光柵化的任主要是決定每個渲染圖源中的那些像素應該被繪制再屏幕上。對上一階段得到的逐定點數據進行插值,然後再進行逐像素處理。

為了避免我們看到的那些正在進行光柵化的圖元,GPU會使用雙重緩沖策略(前置緩沖,後置緩沖)。當場景被渲染到後置緩沖中,GPU會交換前後置緩沖中的內容,前置緩沖事之前顯示在屏幕上的圖像。

技術分享圖片

(1)頂點著色器:處理單位是頂點,輸入進來的每個定點都會調用一次定點著色器。頂點著色器本身不可以創建或者銷毀任何頂點,而且無法得到頂點與頂點之間的關系。完成的工作主要由:坐標變換(把頂點坐標從模型空間轉換到齊次裁剪空間如:mul(UNITY_MVP,v.postion))和逐頂點光照。

(2)裁剪:一個圖元和攝像機事業的關系有三種:完全在視野內,部分在視野內,完全在視野外。

(3)屏幕映射:把每個圖元的x,y坐標轉換到屏幕坐標系下。

(4)三角形設置:計算光柵化一個三角網格所需要的信息。即:得到三角形的每個頂點,需要得到整個三角網格對像素的覆蓋情況。

(5)三角遍歷:檢查每個像素是否被一個三角網絡所覆蓋。根據上一個階段的計算結果來判斷一個三角網格覆蓋了那些像素,並使用三角網格3個頂點的頂點信息對整個覆蓋區域的像素進行插值。

(6)片元著色器:采用的主要技術為紋理采樣。在頂點著色器階段輸出每個頂點對應的紋理坐標,然後經過光柵化階段對三角網格的3個頂點對應的紋理坐標進行插值,就可以得到其覆蓋的片元的紋理坐標。

(7)逐片元操作:幾個主要任務:

1.決定每個片元的可見性。涉及很多測試工作,如:深度測試,模板測試。

2.當某個片元通過了所有測試,就需要把這個片元的顏色值和已經存儲在顏色緩沖區中的顏色進行合並(混合)。

開啟混合功能:GPU會取出資源顏色和目標顏色,將兩種顏色進行混合。

關閉混合功能:會直接使用片元的顏色覆蓋掉顏色緩沖區中的顏色。

對於不透明的物體,即使關閉混合操作,片元著色器計算得到的顏色值可以直接覆蓋掉顏色緩沖區中的像素值。但是對於半透明物體,就需要使用混合操作來使物體看上去濕透明的。

2.Draw Call

(1)CPU和GPU是如何實現並行工作的?

  使用命令緩沖區。命令緩沖區包含了一個命令隊列,由CPU向其中添加命令,而GPU從中讀取命令,讀取和添加命令是相互獨立的。

(2)為什麽Draw Call多了會影響幀率?

  每次調用Draw Call之前,CPU需要向GPU發送很多內容,包括數據,狀態和命令等。

(3)如何減少Draw Call?

  批處理方法。把很多小的Draw Call合並成一個大的Draw Call 。

 在遊戲開發過程中,為了減少Draw Call的開銷,需要註意:

(1)避免使用大量很小的網格,當不可避免地需要使用很小的網格時,可以考慮是否可以合並。

(2)避免使用過多的材質。盡量在不同得網絡之間共用同一個材質。、

3.Shader

1.使用流程:

(1)創建材質。

(2)創建一個Shader,並賦給(1)創建的材質。

(3)把材質賦給要渲染的對象

(4)在材質面板中調節shader的屬性。

2.基礎結構

技術分享圖片

Shader "Custom/MyShader" {
    Properties {
        _Int ("Int", Int) = 2
        _Float("Float",Float) = 1.5
        _Range("Range",Range(0.0,5.0)) = 3.0
        _Color("Color",Color)=(1,1,1,1)
        _Vector("Vector",Vector)=(2,3,5,6)
        _2D("2D",2D) = "" {}
        _Cube("Cube",Cube) = "white" {}
        _3D("3D",3D) = "black" {}
    }
    SubShader {
        //真正意義上的Shader代碼會出現在這裏
        //表面著色器/頂點/片元/固定函數著色器
        ///可選
        //標簽
        Tags { "RenderType"="Opaque" }
        //狀態
        [RenderSetup]
        Pass{
            [Name]
            [Tags]
            [RenderSetup]
        }
        //other pass
    } 
    Fallback "name"
}

技術分享圖片

Tag標簽屬性

技術分享圖片

技術分享圖片

技術分享圖片

53

unity之shader