成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

著色器入門:符號距離函數(shù)!

開發(fā) 后端
在本文中,我將介紹我用來學習編寫簡單著色器的步驟,并努力讓你們相信著色器并不難入門!

[[441677]]

大家好!不久前我學會了如何使用著色器制作有趣的閃亮旋轉(zhuǎn)八面體:

我的著色器能力仍然非常基礎(chǔ),但事實證明制作這個有趣的旋轉(zhuǎn)八面體比我想象中要容易得多(從其他人那里復制了很多代碼片段!)。

我在做這件事時, 從一個非常有趣的叫做 符號距離函數(shù)教程:盒子和氣球 的教程中學到了“符號距離函數(shù)”的重要思路。

在本文中,我將介紹我用來學習編寫簡單著色器的步驟,并努力讓你們相信著色器并不難入門!

更高級著色器的示例

如果你還沒有看過用著色器做的真正有趣的事情,這里有幾個例子:

  1. 這個非常復雜的著色器就像一條河流的真實視頻:https://www.shadertoy.com/view/Xl2XRW
  2. 一個更抽象(更短!)有趣的著色器,它有很多發(fā)光的圓圈:https://www.shadertoy.com/view/lstSzj

步驟一:我的第一個著色器

我知道你可以在 shadertoy 上制作著色器,所以我去了 https://www.shadertoy.com/new。它們提供了一個默認著色器,

代碼如下:

  1. void mainImage( out vec4 fragColor, in vec2 fragCoord )
  2. {
  3. // 規(guī)范像素坐標 (從 0 到 1)
  4. vec2 uv = fragCoord / iResolution.xy;
  5.  
  6. // 隨時間改變像素顏色
  7. vec3 col = 0.5 + 0.5 * cos(iTime + uv.xyx + vec3(0, 2, 4));
  8.  
  9. // 輸出到屏幕
  10. fragColor = vec4(col, 1.0);
  11. }

雖然還沒有做什么令人興奮的事情,但它已經(jīng)教會了我著色器程序的基本結(jié)構(gòu)!

思路:將一對坐標(和時間)映射到一個顏色

這里的思路是獲得一對坐標作為輸入(fragCoord),你需要輸出一個 RGBA 向量作為此坐標的顏色。該函數(shù)也可以使用當前時間(iTime),圖像從而可以隨時間變化。

這種編程模型(將一對坐標和時間映射到其中)的巧妙之處在于,它非常容易并行化。我對 GPU 了解不多,但我的理解是,這種任務(一次執(zhí)行 10000 個微不足道的可并行計算)正是 GPU 擅長的事情。

步驟二:使用 shadertoy-render 加快開發(fā)迭代

玩了一段時間的 shadertoy 之后,我厭倦了每次保存我的著色器時都必須在 shadertoy 網(wǎng)站上單擊“重新編譯”。

我找到了一個名為 shadertoy-render 命令行工具,它會在每次保存時實時查看文件并更新動畫。現(xiàn)在我可以運行:

  1. shadertoy-render.py circle.glsl

并更快地開發(fā)迭代!

步驟三:畫一個圓圈

接下來我想 —— 我擅長數(shù)學!我可以用一些基本的三角學來畫一個會彈跳的彩虹圈!

我知道圓的方程為(x^2 + y^2 = 任意正數(shù)!),所以我寫了一些代碼來實現(xiàn)它:

代碼如下:(你也可以 在 shadertoy 上查看

  1. void mainImage( out vec4 fragColor, in vec2 fragCoord )
  2. {
  3. // 規(guī)范像素坐標 (從 0 到 1)
  4. vec2 uv = fragCoord / iResolution.xy;
  5. // 繪制一個中心位置依賴于時間的圓
  6. vec2 shifted = uv - vec2((sin(iGlobalTime) + 1) / 2, (1 + cos(iGlobalTime)) / 2);
  7. if (dot(shifted, shifted) < 0.03) {
  8. // 改變像素顏色
  9. vec3 col = 0.5 + 0.5 * cos(iGlobalTime + uv.xyx + vec3(0, 2, 4));
  10. fragColor = vec4(col, 1.0);
  11. } else {
  12. // 使圓之外的其他像素都是黑色
  13. fragColor = vec4(0,0, 0, 1.0);
  14. }
  15. }

代碼將坐標向量 fragCoord 與自身點積,這與計算 x^2 + y^2 相同。我還在這個圓圈的中心玩了一點花活 – 圓心為 vec2((sin(iGlobalTime) + 1)/ 2,(1 + cos(faster)) / 2,這意味著圓心也隨著時間沿另一個圓移動。

著色器是一種學習數(shù)學的有趣方式!

我覺得有意思的(即使我們沒有做任何超級高級的事情!)是這些著色器為我們提供了一種有趣的可視化方式學習數(shù)學 - 我用 sin 和 cos 來使某些東西沿著圓移動,如果你想更直觀地了解三角函數(shù)的工作方式, 也許編寫著色器會是一種有趣的方法!

我喜歡的是,可以獲得有關(guān)數(shù)學代碼的即時視覺反饋 - 如果你把一些東西乘以 2,圖像里的東西會變得更大!或更小!或更快!或更慢!或更紅!

但是我們?nèi)绾巫鲆恍┱嬲腥さ氖虑槟兀?/h3>

這個會彈跳的圓圈很好,但它與我見過的其他人使用著色器所做的非常奇特的事情相去甚遠。那么下一步要做什么呢?

思路:不要使用 if 語句,而是使用符號距離函數(shù)!

在我上面的圓圈代碼中,我基本上是這樣寫的:

  1. if (dot(uv, uv) < 0.03) {
  2. // 圓里的代碼
  3. } else {
  4. // 圓外的代碼
  5. }

但問題(也是我感到卡住的原因)是不清楚如何將它推廣到更復雜的形狀!編寫大量的 if 語句似乎不太好用。那人們要如何渲染這些 3d 形狀呢?

所以!符號距離函數(shù)Signed distance function 是定義形狀的另一種方式。不是使用硬編碼的 if 語句,而是定義一個 函數(shù),該函數(shù)告訴你,對于世界上的任何一個點,該點與你的形狀有多遠。比如,下面是球體的符號距離函數(shù)。

  1. float sdSphere( vec3 p, float center )
  2. {
  3. return length(p) - center;
  4. }

符號距離函數(shù)非常棒,因為它們:

  • 易于定義!
  • 易于組合!如果你想要一個被切去一塊的球體, 你可以用一些簡單的數(shù)學來計算并集/交集/差集。
  • 易于旋轉(zhuǎn)/拉伸/彎曲!

制作旋轉(zhuǎn)陀螺的步驟

當我開始時,我不明白需要編寫什么代碼來制作一個閃亮的旋轉(zhuǎn)東西。結(jié)果表明如下是基本步驟:

  1. 為想要的形狀創(chuàng)建一個符號距離函數(shù)(在我的例子里是八面體)
  2. 光線追蹤符號距離函數(shù),以便可以在 2D 圖片中顯示它(或沿光線行進?我使用的教程稱之為光線追蹤,我還不明白光線追蹤和光線行進之間的區(qū)別)
  3. 編寫代碼處理形狀的表面紋理并使其發(fā)光

我不打算在本文中詳細解釋符號距離函數(shù)或光線追蹤,因為我發(fā)現(xiàn)這個 關(guān)于符號距離函數(shù)的神奇教程 非常友好,老實說,它比我做的更好,它解釋了如何執(zhí)行上述 3 個步驟,并且代碼有大量的注釋,非常棒。

步驟四:復制教程代碼并開始更改內(nèi)容

我在這里使用了久負盛名的編程實踐,即“復制代碼并以混亂的方式更改內(nèi)容,直到得到我想要的結(jié)果”。

最后一堆閃亮的旋轉(zhuǎn)八面體著色器在這里:https://www.shadertoy.com/view/wdlcR4

為了做到這一點,我基本上只是復制了關(guān)于符號距離函數(shù)的教程,該函數(shù)根據(jù)符號距離函數(shù)呈現(xiàn)形狀,并且:

  • 將 sdfBalloon 更改為 sdfOctahedron,并使八面體旋轉(zhuǎn)而不是在我的符號距離函數(shù)中靜止不動
  • 修改 doBalloonColor 著色功能,使其有光澤
  • 有很多八面體而不是一個

使八面體旋轉(zhuǎn)!

下面是我用來使八面體旋轉(zhuǎn)的代碼!事實證明這真的很簡單:首先從 這個頁面 復制一個八面體符號距離函數(shù),然后添加一個 rotate 使其根據(jù)時間旋轉(zhuǎn),然后它就可以旋轉(zhuǎn)了!

  1. vec2 sdfOctahedron( vec3 currentRayPosition, vec3 offset ){
  2. vec3 p = rotate((currentRayPosition), offset.xy, iTime * 3.0) - offset;
  3. float s = 0.1; // s 是啥?
  4. p = abs(p);
  5. float distance = (p.x + p.y + p.z - s) * 0.57735027;
  6. float id = 1.0;
  7. return vec2( distance, id );
  8. }

用一些噪音讓它發(fā)光

我想做的另一件事是讓我的形狀看起來閃閃發(fā)光/有光澤。我使用了在 這個 GitHub gist 中找到的噪聲函數(shù)使表面看起來有紋理。

以下是我如何使用噪聲函數(shù)的代碼。基本上,我只是隨機地將參數(shù)更改為噪聲函數(shù)(乘以 2?3?1800?隨你!),直到得到喜歡的效果。

  1. float x = noise(rotate(positionOfHit, vec2(0, 0), iGlobalTime * 3.0).xy * 1800.0);
  2. float x2 = noise(lightDirection.xy * 400.0);
  3. float y = min(max(x, 0.0), 1.0);
  4. float y2 = min(max(x2, 0.0), 1.0);
  5. vec3 balloonColor = vec3(y, y + y2, y + y2);

編寫著色器很有趣!

上面就是全部的步驟了!讓這個八面體旋轉(zhuǎn)并閃閃發(fā)光使我很開心。如果你也想用著色器制作有趣的動畫,希望本文能幫助你制作出很酷的東西!

通常對于不太了解的主題,我可能在文章中說了至少一件關(guān)于著色器的錯誤事情,請讓我知道錯誤是什么!

再說一遍,如下是我用到的兩個資源:

  1. “符號距離函數(shù)教程:盒子和氣球”:https://www.shadertoy.com/view/Xl2XWt(修改和玩起來真的很有趣)
  2. 可以將大量符號距離函數(shù)復制并粘貼到你的代碼中:http://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm

   

 

責任編輯:龐桂玉 來源: Linux中國
相關(guān)推薦

2017-01-11 19:15:55

Android著色器Tint

2013-01-30 15:37:19

CSS著色器HTML5

2021-03-18 08:03:58

SteamMesa緩存

2023-04-12 07:46:24

JavaScriptWebGL

2023-10-16 15:58:54

開源Blender

2017-05-08 11:41:37

WebGLThree.js

2013-04-15 14:23:21

2022-09-26 12:28:16

OpenGLAPI使用移動應用

2023-11-15 14:15:03

開源Blender

2023-03-16 14:33:23

WebGL初始化繪制

2023-05-06 07:23:57

2022-10-10 09:01:21

JavaQuarkus

2025-01-08 10:17:11

2009-12-29 16:21:46

silverlight

2025-06-03 14:14:59

智能技術(shù)AI

2024-02-26 00:00:00

前端工具Space.js

2019-07-10 16:45:49

LinuxLinux游戲游戲性能

2023-09-04 06:52:28

AMD銳龍GPU

2024-11-15 09:00:00

云計算云平臺

2012-05-22 01:20:14

SyntaxHighlJavaScriptJava
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 久久激情视频 | 四虎影院久久 | 岛国av一区二区 | 精品视频www | 国产成人精品一区二区三区四区 | www.久| 国产在线精品一区二区 | av在线一区二区 | 亚洲欧洲激情 | 亚洲精品在线免费观看视频 | 欧美日韩久久精品 | 成人精品在线观看 | 99久久夜色精品国产亚洲96 | 久热精品免费 | 久久精品国产一区二区电影 | 精品视频一区二区三区在线观看 | 中文字幕亚洲欧美日韩在线不卡 | 综合色久| 国产精品激情 | 91.xxx.高清在线 | 国产黄色在线 | 欧美在线一区二区三区 | a免费在线 | 国产在线观看一区二区 | 美女中文字幕视频 | 精品国产一级 | 国产 亚洲 网红 主播 | 久久影音先锋 | 欧美一级片在线观看 | 欧美日韩国产精品一区 | 久久综合成人精品亚洲另类欧美 | 午夜视频精品 | 午夜免费精品视频 | 中文字幕av中文字幕 | 人妖av| 欧美精品一二三区 | 免费观看的av| 给我免费的视频在线观看 | 日韩av一区二区在线观看 | 亚洲综合无码一区二区 | 日韩中文字幕视频在线观看 |