这篇文章介绍了如何利用各种噪声函数(如2D和3D噪声)在图形渲染中创建复杂的纹理效果。通过应用平滑步骤、混合颜色以及随机数生成技术,实现了在像素坐标上绘制动态变化的圆圈,并结合时间变量产生时间依赖的视觉变化。
效果如下:
shader:
#define backgroundColor vec4(0.)
vec3 random3(vec3 st)
{
st = vec3( dot(st,vec3(127.1,311.7,211.2)/20.),
dot(st,vec3(269.5,183.3, 157.1)), dot(st,vec3(269.5,183.3, 17.1)) );
return -1.0 + 2.0*fract(sin(st)*43758.5453123);
}
vec2 random2(vec2 st){
st = vec2( dot(st,vec2(127.1,311.7)),
dot(st,vec2(269.5,183.3)) );
return -1.0 + 2.000*fract(sin(st)*43758.5453123);
}
float rand(float seed){
return abs(fract(sin(seed)*43758.5453123));
}
float noise3D(vec3 st)
{
vec3 i = floor(st) ;
vec3 f = fract(st);
vec3 u = smoothstep(0.,1.,f);
float valueNowxy01 =mix( mix( dot( random3(i + vec3(0.0,0.0,0.0) ), f - vec3(0.0,0.0,0.0) ),
dot( random3(i + vec3(1.0,0.0,0.0) ), f - vec3(1.0,0.0,0.0) ), u.x),
mix( dot( random3(i + vec3(0.0,1.0,0.0) ), f - vec3(0.0,1.0,0.0) ),
dot( random3(i + vec3(1.0,1.0,0.0) ), f - vec3(1.0,1.0,0.0) ), u.x), u.y);
float valueNowxy02 =mix( mix( dot( random3(i + vec3(0.0,0.0,1.0) ), f - vec3(0.0,0.0,1.0) ),
dot( random3(i + vec3(1.0,0.0,1.0) ), f - vec3(1.0,0.0,1.0) ), u.x),
mix( dot( random3(i + vec3(0.0,1.0,1.0) ), f - vec3(0.0,1.0,1.0) ),
dot( random3(i + vec3(1.0,1.0,1.0) ), f - vec3(1.0,1.0,1.0) ), u.x), u.y);
return abs(mix(valueNowxy01, valueNowxy02, u.z));
}
// Value Noise by Inigo Quilez - iq/2013
// https://www.shadertoy.com/view/lsf3WH
float noise(vec2 st) {
vec2 i = floor(st);
vec2 f = fract(st);
vec2 u = f*f*(3.0-2.0*f);
return mix( mix( dot( random2(i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ),
dot( random2(i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
mix( dot( random2(i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ),
dot( random2(i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}
void DrawCircle (inout vec4 buffer, in vec4 circlesColor, in float radius, in vec2 coord, in vec2 pos){
buffer = mix(circlesColor, buffer, smoothstep(radius, radius + 0.001, distance(vec2(coord.x, coord.y*0.2), pos)));
}
void applyTexture(inout vec4 buffer, in vec2 uv){
vec4 temp = buffer;
float height = clamp((noise(vec2(uv.x*1., iTime*0.4)) +0.5), 0.0, 1.0) ;
float Noise = (noise3D(vec3(vec2(uv.x*1. + noise(vec2(uv.y*7., iTime/2.+uv.y+uv.x*10.))*pow(uv.y,0.8)*1.5
*noise3D(vec3(uv.y*10.,uv.y*7.+uv.x*7., iTime))
, uv.y-iTime*0.3)*15., iTime*1.6))+(0.3 + height*1.9))/(1.4 + 6. * height);
buffer.rg *= pow(pow(1.6,Noise),2.);
buffer.g *= Noise;
buffer = mix( temp, buffer,clamp(uv.y*9.-0.2, 0. , 1.));
buffer.rg *= pow(pow(1.3,Noise),2.);
buffer = mix( backgroundColor,buffer, smoothstep(noise(vec2(iTime,uv.x*10.))*0.15 + pow(uv.y,0.7)/1.,
noise(vec2(iTime,uv.x*10.))*0.15
+pow(uv.y,0.7)/1.+0.15, Noise));
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.y;
vec4 color = backgroundColor;
float colorChanging = step(iResolution.x/(iResolution.y*2.), uv.x);
vec4 changingColor = vec4(uv.x*2. - smoothstep(0.4, 0.9, uv.x) , 0.6 + smoothstep(0.5, 0.9, uv.x),1.-uv.x*0.5,1.);
vec4 circleColor =vec4(0.9, 0.6, 0.3, 1.0);
//circleColor = mix(changingColor,circleColor, colorChanging);
applyTexture(circleColor,uv);
DrawCircle(color, circleColor, 1.7, uv, vec2(iResolution.x/(iResolution.y*2.), 0.5));
//color = vec4(0.9, 0.6, 0.0, 1.0);
// Output to screen
fragColor =color;
}