参考了shadertoy的一个shader : https://www.shadertoy.com/view/ldSSzV
float freq = ch("Freq");
float amp = ch("Amp");
float rand = ch("Rand");
float amplitude = 0.5;
float frequency = 1.;
float DISPLACEMENT1 = ch('Displacement1');
float DISPLACEMENT2 = ch('Displacement2');
int seed;
float f1;
float f2;
// 大致形状
int T = (int)(1/rand);
wnoise(@P,seed,f1,f2,T,T,T);
@P += f1 * normalize(@N);
// 细节
float hash11(float p) {
return frac(sin(p * 727.1)*435.545);
}
float hash12(vector2 p) {
float h = dot(p,{127.1,311.7});
return frac(sin(h)*437.545);
}
vector hash31(float p) {
vector h = {127.231,491.7,718.423} * p;
return frac(sin(h)*435.543);
}
float mix(float x, y, a)
{
return x*(1-a) + y*a;
}
// 3d noise
float noise_3(vector p) {
vector i = floor(p);
vector f = frac(p);
vector u = f*f*(3.0-2.0*f);
vector2 i2 = set(i.x, i.y) + i.z * {5.0, 5.0};
float a = hash12( i2 + {0.0,0.0} );
float b = hash12( i2 + {1.0,0.0} );
float c = hash12( i2 + {0.0,1.0} );
float d = hash12( i2 + {1.0,1.0} );
float v1 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y);
i2 += {5.0,5.0};
a = hash12( i2 + {0.0,0.0} );
b = hash12( i2 + {1.0,0.0} );
c = hash12( i2 + {0.0,1.0} );
d = hash12( i2 + {1.0,1.0} );
float v2 = mix(mix(a,b,u.x), mix(c,d,u.x), u.y);
return max(mix(v1,v2,u.z),0.0);
}
// fBm
float fbm3(vector p) {
return noise_3(p);
}
float fbm3_high(vector p; float a, f){
float ret = 0.0;
float amp = 1;
float frq = 1.0;
for(int i = 0; i < 4; i++) {
float n = pow(noise_3(p * frq),2.0);
ret += n * amp;
frq *= f;
amp *= a * (pow(n,0.2));
}
return ret;
}
// 1 level
@P += fbm3(@P * 4.0) * DISPLACEMENT1 * normalize(@N);
// 2 level
@P += fbm3_high(@P*4.0,0.4,2.96) * DISPLACEMENT2 * normalize(@N);