glsl进阶学习7

float hash(vec3 p)
{
 float h=dot(p,vec3(327.73333,10675.23857,1736.4243589));
    return fract(sin(h)*42387.2355837);
}
float noise3D(vec3 p,float res)
{
    p*=res;
    vec3 i=floor(mod(p,res));
    vec3 f=fract(p);
    vec3 u=f*f*(3.0-2.0*f);
    float y1=mix(mix(hash(i),hash(i+vec3(1.,0.,0.)),u.x),
                mix(hash(i+vec3(0.,1.,0.)),hash(i+vec3(1.,1.,0.)),u.x),
                u.y);
    float y2=mix(mix(hash(i+vec3(0.,0.,1.)),hash(i+vec3(1.,0.,1.)),u.x),
                mix(hash(i+vec3(0.,1.,1.)),hash(i+vec3(1.,1.,1.)),u.x),
                u.y);
    return mix(y1,y2,u.z)*2.-1.;
}
float snoise3D(vec3 uv, float res)
{
	const vec3 s = vec3(1e0, 1e2, 1e3);
	
	uv *= res;
	
	vec3 uv0 = floor(mod(uv, res))*s;
	vec3 uv1 = floor(mod(uv+vec3(1.), res))*s;
	
	vec3 f = fract(uv); f = f*f*(3.0-2.0*f);

	vec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z,
		      	  uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z);

	vec4 r = fract(sin(v*1e-1)*1e3);
	float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
	
	r = fract(sin((v + uv1.z - uv0.z)*1e-1)*1e3);//这里补z部分
	float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
	
	return mix(r0, r1, f.z)*2.-1.;
}

对比s版本 上面是很朴素的版本 对每个地方都hash随机 最后mix

s版本则是抓住重点  一开始就构造了uv0 uv1 然后构造出一个v

里面实际上是 i+0 0 0    1 0 0    0 1 0    1 1 0 然后fract一次就是随机一次 然后mix一次得到一个y1 再fract得到y2

最后在mix(y1,y2,z)这明显很优秀嘛

你可能感兴趣的:(glsl)