[程式] Lava shader example

看板GameDesign (遊戲設計)作者 (River)時間8年前 (2017/05/27 20:01), 8年前編輯推噓9(9025)
留言34則, 5人參與, 最新討論串1/2 (看更多)
去年在網路上看到很佛心的人分享一個 lava shader 今天剛好在整理這一部份寫成blog 就分享來這裡 因為也有幾行關鍵的數學判斷我看不懂 所以希望板上的大神如果願意的話幫我解惑一下 XD 另外覺得我有寫錯的部份也可以交流討論討論 http://riveragamer.blogspot.tw/2017/05/lava-shader-code.html shader codes的話就跳過vertex shader 只貼fragment shader (排版不佳傷眼, 不好意思XD) ===================================== struct PS_OUTPUT { float4 RGBColor : COLOR0; // Pixel color }; float time; sampler2D tex0; sampler2D tex1; PS_OUTPUT pixelMain( float2 TexCoord : TEXCOORD0, float4 Position : POSITION ) { PS_OUTPUT Output; // tex0 是作者準備的noise map, 作者將它視為normal map去應用 float4 noise = tex2D( tex0, TexCoord ); // sample color map // 計算 2 組UV位移分量, 時間參數在此代入影響 float2 T1 = TexCoord + float2(1.5,-1.5)*time*0.02; float2 T2 = TexCoord + float2(-0.5,2.0)*time*0.01; // noise.xyz 分別代表tangent space(我譯為切線空間)中的x, z, y軸分量 // (xz平面視為水平面) // T1.xy = noize.xy * 2 + T1.xy; // 也就是noise空間的 xz 水平位移量影響T1 T1.x += (noise.x)*2.0; T1.y += (noise.y)*2.0; // T2.xy = noize.yz * 2 + T2.xy; // 也就是noize空間的 yz 垂直面位移量影響T2 T2.x += (noise.y)*0.2; T2.y += (noise.z)*0.2; // 由T1再次對 tex0 (noise map)做fetch, // 取得T1擾動影響後alpha結果 (p = noise.a) float p = tex2D( tex0, T1*2.0).a; // 以T2由 tex1 (lava炎漿貼圖) 去取得炎漿的原色 float4 col = tex2D( tex1, T2*2.0 ); // 神奇的數學來了, 我頭開始痛惹 // col 被 p * 2 影響後再加上自身 col * col - 0.1, // 明顯是一個高亮度曝光的動作 float4 temp = col*(float4(p,p,p,p)*2.0)+(col*col-0.1); // 這 3 個 if condition 我真的無法解釋 = =, // 但最關鍵的就在這辣rrrrr if(temp.r > 1.0 ) { temp.bg += clamp(temp.r-2.0,0.0,100.0); } if(temp.g > 1.0 ) { temp.rb += temp.g-1.0; } if(temp.b > 1.0 ) { temp.rg += temp.b-1.0; } // Jobs done. QQ Output.RGBColor = temp; return Output; } -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 36.236.159.38 ※ 文章網址: https://www.ptt.cc/bbs/GameDesign/M.1495886501.A.596.html ※ 編輯: riveranb (36.236.159.38), 05/27/2017 20:02:58

05/27 20:04, , 1F
我認為我自己把noise map當成normal map去註解
05/27 20:04, 1F

05/27 20:04, , 2F
然後當成切線空間去解釋不太適合,其實就視作亂數位移
05/27 20:04, 2F

05/27 20:05, , 3F
就夠清楚了
05/27 20:05, 3F

05/28 03:24, , 4F
temp分量初始值會在[0.0, 2.9]之間
05/28 03:24, 4F

05/28 03:25, , 5F
感覺剩下的程式是在把數值正規化到[0.0 1.0]之間
05/28 03:25, 5F

05/28 03:25, , 6F
可是感覺作者magic number用有點隨便...像temp.r - 2.0
05/28 03:25, 6F

05/28 03:26, , 7F
是[-1.0 0.9]之間的值,算[-1.0 1.0]好了
05/28 03:26, 7F

05/28 03:26, , 8F
沒必要用100.0f去clamp這個值呀...除非我誤會了什麼
05/28 03:26, 8F

05/28 03:27, , 9F
如果你單純寫temp.rgb = normalize(temp.rgb)會變如何?
05/28 03:27, 9F

05/28 03:28, , 10F
如果效果差不多,那應該就是作者想要在正規化的途中
05/28 03:28, 10F

05/28 03:29, , 11F
多摻入一些"攪和"
05/28 03:29, 11F

05/28 03:30, , 12F
如果是這樣,那就除了本人解釋以外,旁人真的只能猜了
05/28 03:30, 12F

05/28 11:42, , 13F
原作用另一層流動速度不同的雜訊來曝光各取樣點
05/28 11:42, 13F

05/28 11:43, , 14F
考量不知為和,不知為何不直接採用兩層流動速度不同的
05/28 11:43, 14F

05/28 11:44, , 15F
perlin noise octave做additive blending
05/28 11:44, 15F

05/28 11:44, , 16F
因為那個demo影片看起來效果跟這個方法好像差不多
05/28 11:44, 16F

05/28 11:45, , 17F
或許兩個方法之間有不明顯的差異,真好奇...
05/28 11:45, 17F

05/29 13:32, , 18F
謝謝大大提點,那些if的確像是為了要做normalize
05/29 13:32, 18F

05/29 13:33, , 19F
為了怕誤會我說明清楚點,blog中demo影片部分是我寫的
05/29 13:33, 19F

05/29 13:35, , 20F
流動控制上的確有改成参數化additive blending
05/29 13:35, 20F

05/29 13:36, , 21F
原作者Mike hartwig只提供重要的code snippet.
05/29 13:36, 21F

05/29 18:59, , 22F
都看不懂,但是推一下
05/29 18:59, 22F

05/29 20:05, , 23F
其實應該那個不是什麼關鍵 就是在固定temp rgb的範圍
05/29 20:05, 23F

05/29 20:05, , 24F
而已...
05/29 20:05, 24F

05/29 22:33, , 25F
改成normalize效果有差不多嗎?
05/29 22:33, 25F

05/30 01:10, , 26F
不曉得 要跑看看數值範圍
05/30 01:10, 26F

05/30 01:10, , 27F
他這樣跟normalize是不一樣的處理方式
05/30 01:10, 27F

05/30 06:40, , 28F
我是指兩者視覺結果可能差不多,等原po試試吧
05/30 06:40, 28F

05/30 08:16, , 29F
題外話,不再弄置底聊天室了嗎?
05/30 08:16, 29F

05/30 15:09, , 30F
對吼 忘了更新...
05/30 15:09, 30F

05/30 15:10, , 31F
不是 我之前想是至底聊天反而好像降低了發文數...
05/30 15:10, 31F

05/30 15:10, , 32F
所以先拿掉了
05/30 15:10, 32F

05/30 16:41, , 33F
要衝業績齁
05/30 16:41, 33F

05/30 20:02, , 34F
置底聊天其實也沒什麼水量啊XD 不至於到影響發文量才對
05/30 20:02, 34F
※ 編輯: riveranb (122.117.152.17), 06/10/2017 13:21:17
文章代碼(AID): #1PAMgbMM (GameDesign)
討論串 (同標題文章)
文章代碼(AID): #1PAMgbMM (GameDesign)