uniform int uBiomesEnabled; uniform int uBiomeHasTexture; uniform sampler2D uBiomeTexture; uniform sampler2DArray uBiomeColors; uniform vec3 uBiomeTargets[4]; uniform float uBiomeTolerances[4]; uniform float uForestScale; vec4 biomeWeights(vec3 direction){ vec3 color; if(uBiomeHasTexture!=0)color=texture(uBiomeTexture,planetUv(direction)).rgb; else { float n=noise3(direction*5.0+uNoiseOffset); color=abs(direction.y)>.91?vec3(235,238,240)/255.0:n<-.2&&abs(direction.y)<.6?vec3(205,181,120)/255.0:n<.1?vec3(145,150,80)/255.0:vec3(45,80,35)/255.0; } vec4 weights=vec4(0); for(int i=0;i<4;i++){ float d=length(color-uBiomeTargets[i])*57.7350269; float t=uBiomeTolerances[i];weights[i]=t<=0.0?(d<.00001?1.0:0.0):1.0-smoothstep(t*.8,t,d); } return weights/max(1.0,dot(weights,vec4(1))); } vec4 biomeTriColor(float layer,vec3 p,vec3 weights){ vec4 color=texture(uBiomeColors,vec3(p.yz,layer))*weights.x+texture(uBiomeColors,vec3(p.xz,layer))*weights.y+texture(uBiomeColors,vec3(p.xy,layer))*weights.z; color.rgb=pow(color.rgb,vec3(2.2));return color; } vec3 biomeTriNormal(float layer,vec3 p,vec3 n,vec3 weights){ vec3 x=texture(uBiomeColors,vec3(p.yz,layer+4.0)).xyz*2.0-1.0; vec3 y=texture(uBiomeColors,vec3(p.xz,layer+4.0)).xyz*2.0-1.0; vec3 z=texture(uBiomeColors,vec3(p.xy,layer+4.0)).xyz*2.0-1.0; return normalize(vec3(sign(n.x)*x.z,x.x,x.y)*weights.x+vec3(y.x,sign(n.y)*y.z,y.y)*weights.y+vec3(z.x,z.y,sign(n.z)*z.z)*weights.z); }