狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

Shader入門教程(圖文)

admin
2024年4月1日 9:39 本文熱度 726

自從接觸了shader之后我便深深得愛上了它,因為它獨特的編程思考方式沖擊著我這十幾年的慣性認知。在向各位大佬學習的過程中,每學到一個新的技巧,我都不禁感嘆:“實在是妙!”。本文將整理一些個人常用的shader技巧/方法,只包含片元著色器相關內容。由于本人尚屬初學,所以內容會比較基礎。

簡單幾何圖形

區間(帶通)


兩個階梯函數疊加構成的帶通函數,用數字信號處理的角度去思考貌似是個不錯的選擇

1.  float Band(float v, float start, float end) {

2.      float up = step(start, v);

3.      float down = 1.0 - step(end, v);

4.      return up * down;

5.  }

矩形


x, y兩個方向的帶通函數疊加

1.  float Rect(vec2 uv, float l, float b, float r, float t) {

2.      float x = Band(uv.x, l, r);

3.      float y = Band(uv.y, b, t);

4.      return x * y;

5.  }

圓形


圓形比較容易出現鋸齒,所以用 smoothstep 做平滑處理。
由于 distance() 依賴 sqrt() 開根號,在一些老硬件上會比較耗時,實際使用時可以考慮轉換為和r平方進行比較的公式。

1.  float Circle(vec2 uv, vec2 o, float r, float blur) {

2.      return smoothstep(r, r-blur, distance(uv, o));

3.  }

混合疊加

上述幾何圖形函數的輸出值是0或1的float(經過 smoothstep() 可能會出現中間值,不過此處可以不考慮)。
0或1的float值可以利用加、減、乘來模擬位運算。比如上述區間、矩形幾何圖形都是通過乘法疊加。

加減法例子:ET臉


畫一個大圓當臉,減去兩個小圓當眼睛

1.  float ETFace(vec2 uv, vec2 o) {

2.      float c = Circle(uv, vec2(.0, .0), 0.5, 0.01);

3.      c -= Circle(uv, vec2(-.2, -.2), 0.2, 0.01);

4.      c -= Circle(uv, vec2(.2, -.2), 0.2, 0.01);

5.      return c;

6.  }

坐標空間處理

Cocos Creator以 左上角 為坐標原點,范圍(0, 1)。
shadertoy, GlslEditor中均以 左下角 為坐標原點,范圍(0, 1),接下來所有代碼將使用這個坐標系。

在繪制某些對稱圖形時可能需要將原點調整到屏幕中心,即將(0, 1)區間映射到(-0.5, 0.5)。
根據不同場景也可以將(0, 1)區間映射到(-1, 1),哪個處理起來方便用哪個。

1.  // (0, 1)區間映射到(-1, 1)

2.  uv = uv * 2.0 - 1.0;

也可以用下面的方法從任意區間映射到任意區間

1.  float Remap01(float a, float b, float t) {

2.      return (t-a) / (b-a);

3.  }

4.   

5.   

6.  float Remap(float a, float b, float c, float d, float t) {

7.      return Remap01(a, b, t) * (d-c) + c;

8.  }

長寬適配

不知道這個功能的簡稱是什么,暫且這么稱呼吧。
其作用是在分辨率長寬不等的情況下將坐標空間映射為等邊,映射后原先較長的一邊其自變量區間會被放大。

1.  void main() {

2.      vec2 uv = gl_FragCoord.xy/u_resolution.xy;

3.      uv = uv * 2.0 - 1.0;            // 位移到以中間為原點

4.      uv.x *= u_resolution.x/u_resolution.y;    // x的自變量區間拉長

5.      

6.      float mask = Rect(uv, -0.5, -0.5, 0.5, 0.5);

7.      vec3 color = vec3(mask);

8.      gl_FragColor = vec4(color,1.0);

9.  }

計算角度


atan() 計算角度,圖中將(-PI, PI)區間映射到(0, 1)區間,并且將值對應的灰度輸出。
atan() 計算比較耗時,實際項目中慎用。

1.  #define PI 3.141592653589793

2.   

3.   

4.  void main() {

5.      vec2 uv = gl_FragCoord.xy/u_resolution.xy;

6.      uv = uv * 2.0 - 1.0;

7.      uv.x *= u_resolution.x/u_resolution.y;

8.      

9.      float angle = atan(uv.y, uv.x);

10.    angle = Remap(-PI, PI, 0., 1.0, angle);

11.    vec3 color = vec3(angle);

12.    gl_FragColor = vec4(color,1.0);

13.}

旋轉


uv乘以旋轉矩陣

1.  #define PI 3.141592653589793

2.   

3.   

4.  mat2 Rotate2d(float angle){

5.      return mat2(cos(angle), -sin(angle),

6.             sin(angle), cos(angle));

7.  }

8.   

9.   

10.void main() {

11.    vec2 uv = gl_FragCoord.xy/u_resolution.xy;

12.    uv = uv * 2.0 - 1.0;

13.    uv.x *= u_resolution.x/u_resolution.y;

14.   

15.    uv = Rotate2d(PI / 6.) * uv;

16.    float mask = Rect(uv, -0.5, -0.5, 0.5, 0.5);

17.    vec3 color = vec3(mask);

18.    gl_FragColor = vec4(color,1.0);

19.}

網格化


將屏幕分割成5x5個網格,每個格子里畫一個圓。
原理是將uv拉伸5倍后取小數部分,這樣處理后uv會變成每個網格內的局部坐標,這個技巧被廣泛使用。

1.  void main() {

2.      // ...

3.      uv = fract(uv * 5.);

4.      float mask = Circle(uv, vec2(0.5), 0.5, 0.01);

5.      // ...

6.  }

噪音(隨機化hash)


獲取噪音的方法很多很靈活,輸入一般是和uv相關的變量,輸出(0, 1)范圍的1維或2維值。
只要讓人肉眼難分辨出模式,就是一個好用的噪音函數。
噪音的用途非常廣泛,可以利用噪音降低圖片的人工痕跡,后面會單獨整理一篇文章。

1.  float Noise1(vec2 p) {

2.      return fract(sin(

3.          dot(p, vec2(12.9898,78.233))

4.      ) * 43758.5453123);

5.  }

6.   

7.   

8.  float Noise2(vec2 p) {

9.      p = frac(p * vec2(123.34, 345.45));

10.    p += dot(p, p + 34.345);

11.    return frac(p.x * p.y);

12.}

常用鏈接

  • shadertoy
    可以找到很多大神級shader作品
    http://shadertoy.com/

  • 《The Book Of Shaders》
    很棒的入門書籍,可惜還沒更新完
    https://thebookofshaders.com/

  • 我的博客
    將《The Book Of Shaders》里的GlslEditor嵌入博客用于平時練習
    https://caogtaa.github.io/shader/2020/07/16/shader-playground/


該文章在 2024/4/1 12:46:01 編輯過
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved