欢迎继续一起踏上 The Journey of Chaos, 关于 Shader 生成技术的一些基础性学习。噪声会分为以下几篇内容学习
-
PsrdNoise 应用 FlowNoise(本篇)
-
CurlNoise
-
FBM深入
在了解完 PsrdNoise基本原理后,作者提出了一个名为 FlowNoise的用法,其主要思路就是用上一层的梯度值扭曲下一层噪声的坐标。 也就是以下函数中的第 4 个参数作用于第二层的第一个参数.
noise = PsrdNoise(coord, peroid, rotation, gradient)
通过这种玩法可以达到 Ken Perlin and Fabrice Neyret 在 Siggraph的湍流 turbulent 漩涡图案。下图为 这种思路我看最早是 IQ提出来的,他称之为 Domain Warping, IQ的原文 iquilezles.org/articles/wa… 下图为 IQ通过 做出来的图形
2503075401
Flow Noise
用上一层的梯度值扭曲下一层噪声的坐标, 这个有点不直观,查看下面的演示。 最关键的就是下面这段代码,通过先生成噪声,然后将上层的噪声去扭曲下一层的坐标,另外为了看出分别,warp的程度从上到下依次递减,从grid和 arrow也可以看出来
float warpamount = clamp(1.1-st.t*1.2, 0.0, 1.0); n += 0.4 * psrdnoise(v, p, alpha, g); gsum = g; vec2 warped_v = v*2.0+0.15*warpamount*gsum; n += 0.2 * psrdnoise(warped_v, p*2.0, alpha*2.0, g); vec3 noisecolor = vec3(n);
如烟, 如电
依然,warp的程度从上到下依次递减, 上面这个烟雾就是通过 FBM组合出来,就是不断的将 uv放大,并把值缩小,核心代码结构非常类似,优美
float warp = 0.13*clamp(1.1-st.t*1.2, 0.0, 1.0); float n = 0.5; warped_v = v * 1.0 + warp*gsum; n += 0.4 * psrdnoise(warped_v, p, alpha, g); gsum += g * 1.0; warped_v = v * 2.0 + warp*gsum; n += 0.2 * psrdnoise(warped_v, p, alpha + n , g); gsum += g * 0.5; warped_v = v * 4.0 + warp*gsum; n += 0.1 * psrdnoise(warped_v, p, alpha + n, g); gsum += g * 0.25; warped_v = v * 8.0 + warp*gsum; n += 0.05 * psrdnoise(warped_v, p, alpha + n, g);
当然我们可以通过 for循环来组织分型层次
float warp = 0.13; // Nice "puffy clouds" warping float n = 0.0; // noise float w = 1.0; // 分型度数 float s = 1.0; // scale gsum = vec2(0.0); for(float i = 0.0; i<5.0; i++) { n += w*psrdnoise(s*v + warp*gsum, s*p, s*alpha, g); gsum += w * g; w *= 0.5; s *= 2.0; } return vec3(1.0) * (0.5+0.4*n);
这个时候如果我们把最后一句话变成反向,类似于取反,会得到蓝色闪电?
return vec3(0.322,0.384,0.878) * (0.5 - 0.4 * n);
2503072045
恶心的绿色涌动
上面这张效果看起来挺恶心的,其高光的效果赋予了很强的体积感。 实现原理非常简单. 首先首先为梯度增加一个 1.0 的 z值,然后判断这个向量与 vec3(1.0) 反射光的方向是否趋同,如果与反射光方向越相似越应该是亮面。 于是乎其核心代码如下
vec3 N = normalize(vec3(gsum, 1.0)); vec3 L = normalize(vec3(1.0)); float s = pow(max(dot(N,L), 0.0), 10.0); // Shiny! vec3 scolor = vec3(0.929,0.941,0.157); vec3 ncolor = n*vec3(0.5, 1.0, 0.2); // Gooey green return mix(ncolor, scolor, s);
资料
- ken perlin noise userpages.cs.umbc.edu/olano/s2002…