Noise 贴图的程序化生成:
前排说明:
本文只讲求实现原理及其代码实现,目前代码只完成了GLSL部分,可直接用于 ShaderToy 网站;
后续会在 Unity Shader 中实现,时间未排期,待定随缘上传;
参考资料:
【图形学】谈谈噪声
https://www.shadertoy.com/view/sljBWh
效果图展示:
*动态视频展示待上传视频审核通过再更新; *
基于GLSL 语言的 FragColor:
实现 IDE : Visual Studio Code + GLSL相关插件;
直接贴代码:
#ifdef GL_ES
precision mediump float;
#endif
//使用方法后续文章更新;
float rand(vec2 coord){
return fract(sin(dot(coord, vec2(12.9898, 78.233))) * 43758.5453);
}//据说这个方法的作者不详,但是这个算法应用广泛,有待慢慢考证;
vec2 hash22(vec2 coord)
{
coord = vec2(dot(coord, vec2(127.1, 311.7)), dot(coord, vec2(269.5, 183.3)));
return -1.0 + 2.0 * fract(sin(coord) * 43758.5453123);
}
float noise(vec2 coord)
{
vec2 pi = floor(coord);
vec2 pf = coord - pi;
//旧版缓和曲线公式算法;
//vec2 w = pf * pf * (3.0 - 2.0 * pf);
//新版缓和公式算法;
//vec2 w = 6.0 * pow(pf, 5.0) - 15.0 * pow(pf, 4.0) + 10.0 * pow(pf, 3.0);
vec2 w = pf * pf * pf * ( pf * (6.0 * pf - 15.0) + 10.0);
float aa = mix(dot(hash22(pi + vec2(0.0, 0.0)), pf - vec2(0.0, 0.0)),
dot(hash22(pi + vec2(1.0, 0.0)), pf - vec2(1.0, 0.0)), w.x);
float bb = mix(dot(hash22(pi + vec2(0.0, 1.0)), pf - vec2(0.0, 1.0)),
dot(hash22(pi + vec2(1.0, 1.0)), pf - vec2(1.0, 1.0)), w.x);
float result = mix(aa, bb, w.y);
return result;
}
float fbm(vec2 coord)
{
//Noise大小;
coord *= 8.0;
float f = 0.0;
//五层梯段变化;
f += 1.0000 * noise(coord); coord = 2.0 * coord;
f += 0.5000 * noise(coord); coord = 2.0 * coord;
f += 0.2500 * noise(coord); coord = 2.0 * coord;
f += 0.1250 * noise(coord); coord = 2.0 * coord;
f += 0.0625 * noise(coord); coord = 2.0 * coord;
//调整Noise的对比度;
//f /= 1.9375;
f /= 0.8;
return f;
}
float fbm_abs(vec2 coord)
{
//Noise大小;
coord *= 8.0;
float f = 0.0;
//五层梯段变化;
f += 1.0000 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.5000 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.2500 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.1250 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.0625 * abs(noise(coord)); coord = 2.0 * coord;
//调整Noise的对比度;
//f /= 1.9375;
f /= 0.5;
return f;
}
float fbm_abs_sin(vec2 coord)
{
//Noise大小;
coord *= 8.0;
float f = 0.0;
//五层梯段变化;
f += 1.0000 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.5000 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.2500 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.1250 * abs(noise(coord)); coord = 2.0 * coord;
f += 0.0625 * abs(noise(coord)); coord = 2.0 * coord;
//调整Noise的破碎程度;
f /= 0.06;
f = sin(f + coord.x/20.0);//20 为周期,且当 f /= >0.1;能看出明显周期时起作用;
return f;
}
float noise_itself(vec2 coord)
{
return noise(coord * 12.0);
}
GL_FragColor;/
void main(){
vec2 uv = gl_FragCoord.xy/iResolution.xy - 0.5;
float linerTime = iTime;
//噪波区域 * 4 种;
float noiseself = noise_itself( vec2(uv.x + linerTime/4.0, uv.y + linerTime/16.0));
vec3 noiseSelf = vec3( 0.6 - noiseself );//0.6为对比度;
float fbmnoise = (1.0 - fbm( vec2(uv.x + linerTime/4.0, uv.y + linerTime/16.0)));
vec3 fbmNoise = vec3( fbmnoise * 0.5 );//0.5 降低亮度值;
float noise_fbm_abs = fbm_abs( vec2(uv.x + linerTime/4.0, uv.y + linerTime/16.0));
vec3 noiseFbmAbs = vec3( noise_fbm_abs );
float noise_fbm_abs_sin = fbm_abs_sin( vec2(uv.x + linerTime/4.0, uv.y + linerTime/16.0));
vec3 noiseFbmAbsSin = vec3( noise_fbm_abs_sin );
if(gl_FragCoord.y/iResolution.y < 0.25)
{
gl_FragColor = vec4(noiseFbmAbsSin, 1.0);
}
if(gl_FragCoord.y/iResolution.y < 0.5 && gl_FragCoord.y/iResolution.y >= 0.25)
{
gl_FragColor = vec4(noiseFbmAbs, 1.0);
}
if(gl_FragCoord.y/iResolution.y < 0.75 && gl_FragCoord.y/iResolution.y >= 0.5)
{
gl_FragColor = vec4( fbmNoise, 1.0);
}
if(gl_FragCoord.y/iResolution.y <= 1.0 && gl_FragCoord.y/iResolution.y >= 0.75)
{
gl_FragColor = vec4(noiseSelf, 1.0);
}
}