作者riveranb (River)
看板GameDesign
标题[程式] Lava shader example
时间Sat May 27 20:01:36 2017
去年在网路上看到很佛心的人分享一个 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://webptt.com/cn.aspx?n=bbs/GameDesign/M.1495886501.A.596.html
※ 编辑: riveranb (36.236.159.38), 05/27/2017 20:02:58
1F:→ riveranb: 我认为我自己把noise map当成normal map去注解 05/27 20:04
2F:→ riveranb: 然後当成切线空间去解释不太适合,其实就视作乱数位移 05/27 20:04
3F:→ riveranb: 就够清楚了 05/27 20:05
4F:推 cjcat2266: temp分量初始值会在[0.0, 2.9]之间 05/28 03:24
5F:→ cjcat2266: 感觉剩下的程式是在把数值正规化到[0.0 1.0]之间 05/28 03:25
6F:→ cjcat2266: 可是感觉作者magic number用有点随便...像temp.r - 2.0 05/28 03:25
7F:→ cjcat2266: 是[-1.0 0.9]之间的值,算[-1.0 1.0]好了 05/28 03:26
8F:→ cjcat2266: 没必要用100.0f去clamp这个值呀...除非我误会了什麽 05/28 03:26
9F:→ cjcat2266: 如果你单纯写temp.rgb = normalize(temp.rgb)会变如何? 05/28 03:27
10F:→ cjcat2266: 如果效果差不多,那应该就是作者想要在正规化的途中 05/28 03:28
11F:→ cjcat2266: 多掺入一些"搅和" 05/28 03:29
12F:→ cjcat2266: 如果是这样,那就除了本人解释以外,旁人真的只能猜了 05/28 03:30
13F:推 cjcat2266: 原作用另一层流动速度不同的杂讯来曝光各取样点 05/28 11:42
14F:→ cjcat2266: 考量不知为和,不知为何不直接采用两层流动速度不同的 05/28 11:43
15F:→ cjcat2266: perlin noise octave做additive blending 05/28 11:44
16F:→ cjcat2266: 因为那个demo影片看起来效果跟这个方法好像差不多 05/28 11:44
17F:→ cjcat2266: 或许两个方法之间有不明显的差异,真好奇... 05/28 11:45
18F:→ riveranb: 谢谢大大提点,那些if的确像是为了要做normalize 05/29 13:32
19F:→ riveranb: 为了怕误会我说明清楚点,blog中demo影片部分是我写的 05/29 13:33
20F:→ riveranb: 流动控制上的确有改成参数化additive blending 05/29 13:35
21F:→ riveranb: 原作者Mike hartwig只提供重要的code snippet. 05/29 13:36
22F:推 Ahtram: 都看不懂,但是推一下 05/29 18:59
23F:→ cowbaying: 其实应该那个不是什麽关键 就是在固定temp rgb的范围 05/29 20:05
24F:推 cowbaying: 而已... 05/29 20:05
25F:推 cjcat2266: 改成normalize效果有差不多吗? 05/29 22:33
26F:→ cowbaying: 不晓得 要跑看看数值范围 05/30 01:10
27F:→ cowbaying: 他这样跟normalize是不一样的处理方式 05/30 01:10
28F:推 cjcat2266: 我是指两者视觉结果可能差不多,等原po试试吧 05/30 06:40
29F:推 cjcat2266: 题外话,不再弄置底聊天室了吗? 05/30 08:16
30F:→ cowbaying: 对吼 忘了更新... 05/30 15:09
31F:推 cowbaying: 不是 我之前想是至底聊天反而好像降低了发文数... 05/30 15:10
32F:→ cowbaying: 所以先拿掉了 05/30 15:10
33F:推 cjcat2266: 要冲业绩齁 05/30 16:41
34F:→ zseineo: 置底聊天其实也没什麽水量啊XD 不至於到影响发文量才对 05/30 20:02
※ 编辑: riveranb (122.117.152.17), 06/10/2017 13:21:17