[MetalKit]Using MetalKit part 13使用MetalKit13

本系列文章是對 http://metalkit.org 上面MetalKit內容的全面翻譯和學習.

MetalKit系統文章目錄


讓我們從第12部分 Part 12繼續.使用上次我們工作的同一個playground,我們今天將學習光照和3D物體.記得前幾周我們做出的日食嗎?它又回來了! 好吧,這次我們將移除太陽,只關注行星.

首先,讓我們清理內核,使其只包含下面的代碼:

int width = output.get_width();
int height = output.get_height();
float2 uv = float2(gid) / float2(width, height);
uv = uv * 2.0 - 1.0;
float radius = 0.5;
float distance = length(uv) - radius;
output.write(distance < 0 ? float4(1) : float4(0), gid);

你一定認出幾周前的這些代碼了.我們惟一改變的是將圓外面的顏色替換為黑色,并將圓內部改為白色.輸出的黑乎乎應該是這個樣子:

chapter13_0.png

目前還不錯.行星看起來相當扁平,光照分布的太均勻看起來不真實.讓我接下來修復它.幾何學告訴我們,為了找到球面上的點,我們需要球體公式:


chapter13_2.png

在我們的例子中,x0, y0z0都是0因為我們的球體在屏幕中間.算出z值就可以得到planet行星顏色的值,所以讓我們用下面這幾行來替換內核中的最后一行:

float planet = float(sqrt(radius * radius - uv.x * uv.x - uv.y * uv.y));
planet /= radius;
output.write(distance < 0 ? float4(planet) : float4(0), gid);

輸出圖像應該像起來像這樣:

chapter13_1.png

正如你期待的那樣,顏色從中間的純白色變為圓外面的純黑色.為此,我們必須用顏色除以radius半徑,來使z值規范化到[0,1]區間內,它能給我們全范圍的光照效果.我們實際偽造了一個燈光源放在(0,0,1).讓引出了新話題:lighting燈光.

lighting燈光讓我們的顏色真正活起來.為了在我們的場景中有一個燈光,我們需要計算每個坐標的normal法線.法向量是垂直于表面,告訴我們表面"指向"哪個坐標.用下面幾行替換最后兩千:

float3 normal = normalize(float3(uv.x, uv.y, planet));
output.write(distance < 0 ? float4(float3(normal), 1) : float4(0), gid);

注意,我們在planet行星變量中已經有z值了.輸出的圖片看起來應該這樣:

chapter13_5.png

這可能不是我們想要看到的,但至少我們知道在每個規格化坐標處計算顏色時法線看起來是什么樣子了.下一步,讓我們創建一個光源放置在我們左側(負x),后面(正z)一點.用下面幾行替換最后一行:

float3 source = normalize(float3(-1, 0, 1));
float light = dot(normal, source);
output.write(distance < 0 ? float4(float3(light), 1) : float4(0), gid); 

我們采用了一種基本的光照模型叫做朗伯特 Lambertian(漫反射)光照,其中我們將法線乘以規格化光源.我們將在以后的文章中學習更多光照知識,但是如果你對學習光照模型很有興趣,可以參考這里 here的眾多資源.輸出的圖片看起來應該這樣:

chapter13_3.png

還記得上一次內核給我們了一個計時器uniform嗎?讓我們用起來玩玩!用這行替換source行:

float3 source = normalize(float3(cos(timer), sin(timer), 1));

通過使用cossin函數,我們給光源一個圓周運動.xy都是按圓的參數方程從-11.輸出的圖片看起來應該這樣:

chapter13_6.gif

我們來仔細看看,場景中的物體被照亮(天空中的行星),然而,物體仍然呈現出單一的表面.我們有兩種方法可以讓它看起來更真實:使用紋理,或者給plante顏色加上一些噪點.
源代碼source code 已發布在Github上.
下次見!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 關于本系列這是Unity3D Shader入門指南系列的第二篇,本系列面向的對象是新接觸Shader開發的Unit...
    JumboWu閱讀 1,594評論 0 2
  • 今天讀經,又讀到了以利亞的故事。 對于以利亞,我以往的印象,都是他是一個大能的先知,行了許多神跡,讓天三年零六個月...
    胖紅帽閱讀 935評論 0 0
  • 你,還記得年少時的夢想嗎? 這樣昏黃的午后 我的心又開始躁動不安起來 想奔跑,聽耳旁的風吹散光 想發呆,看眼角的光...
    若潯閱讀 170評論 0 0
  • 每個人都有自己的思想,有的人思想保守一點、有的人思想激進一點、有的人思想還會中性一點。由于每個人不同的思想類型,導...
    悠然叨叨叨閱讀 290評論 0 0