Files
Universe/src/Universe.App/Graphics/Shaders/noise.glsl
2026-10-30 14:48:06 +01:00

56 lines
2.5 KiB
GLSL

uniform sampler3D uNoise;
const mat3 octaveRotation = mat3(0.0,-0.8,-0.6, 0.8,0.36,-0.48, 0.6,-0.48,0.64);
float noise3(vec3 p) {
vec3 i = floor(p);
vec3 f = fract(p);
f = f*f*f*(f*(f*6.0-15.0)+10.0);
return texture(uNoise, (i+f+0.5)/64.0).a;
}
float preciseNoise3(vec3 p) {
ivec3 i=ivec3(floor(p));
vec3 f=fract(p);
f=f*f*f*(f*(f*6.0-15.0)+10.0);
float a=mix(texelFetch(uNoise,i&63,0).a,texelFetch(uNoise,(i+ivec3(1,0,0))&63,0).a,f.x);
float b=mix(texelFetch(uNoise,(i+ivec3(0,1,0))&63,0).a,texelFetch(uNoise,(i+ivec3(1,1,0))&63,0).a,f.x);
float c=mix(texelFetch(uNoise,(i+ivec3(0,0,1))&63,0).a,texelFetch(uNoise,(i+ivec3(1,0,1))&63,0).a,f.x);
float d=mix(texelFetch(uNoise,(i+ivec3(0,1,1))&63,0).a,texelFetch(uNoise,(i+ivec3(1,1,1))&63,0).a,f.x);
return mix(mix(a,b,f.y),mix(c,d,f.y),f.z);
}
float gradientNoise3(vec3 p) {
ivec3 i=ivec3(floor(p));
vec3 f=fract(p), t=f*f*f*(f*(f*6.0-15.0)+10.0);
float a=mix(dot(texelFetch(uNoise,i&63,0).rgb,f),dot(texelFetch(uNoise,(i+ivec3(1,0,0))&63,0).rgb,f-vec3(1,0,0)),t.x);
float b=mix(dot(texelFetch(uNoise,(i+ivec3(0,1,0))&63,0).rgb,f-vec3(0,1,0)),dot(texelFetch(uNoise,(i+ivec3(1,1,0))&63,0).rgb,f-vec3(1,1,0)),t.x);
float c=mix(dot(texelFetch(uNoise,(i+ivec3(0,0,1))&63,0).rgb,f-vec3(0,0,1)),dot(texelFetch(uNoise,(i+ivec3(1,0,1))&63,0).rgb,f-vec3(1,0,1)),t.x);
float d=mix(dot(texelFetch(uNoise,(i+ivec3(0,1,1))&63,0).rgb,f-vec3(0,1,1)),dot(texelFetch(uNoise,(i+ivec3(1,1,1))&63,0).rgb,f-vec3(1,1,1)),t.x);
return clamp(mix(mix(a,b,t.y),mix(c,d,t.y),t.z)*1.7,-1.0,1.0);
}
float fbm(vec3 p) {
float result=0.0, amplitude=0.5;
for(int i=0;i<5;i++) {
result += noise3(p)*amplitude;
p = octaveRotation*p*2.03 + vec3(17.1,9.2,13.5);
amplitude *= 0.5;
}
return result;
}
float terrainHeight(vec3 direction, vec3 offset, int octaves) {
vec3 p = direction*3.2 + offset;
vec3 warp = vec3(preciseNoise3(p*0.82+vec3(5.2,1.3,9.7)),
preciseNoise3(p*0.82+vec3(19.1,7.7,2.4)),
preciseNoise3(p*0.82+vec3(3.4,21.8,11.6)));
float continent=preciseNoise3(p*0.47);
p=direction*52.0+offset+warp*2.6;
float weight=1.0, amplitude=0.58, sum=0.0;
for(int i=0;i<7;i++) {
if(i>=octaves) break;
float ridge = 1.0-abs(gradientNoise3(p));
ridge = ridge*ridge*ridge*weight;
sum += ridge*amplitude;
weight=0.55+0.45*ridge;
p=octaveRotation*p*2.03 + vec3(17.1,9.2,13.5);
amplitude*=0.50;
}
return (sum-0.42)*0.95+continent*0.16;
}