shader_type spatial; render_mode diffuse_burley, specular_schlick_ggx; uniform vec4 base_color : source_color; uniform sampler2D stone_map : source_color, filter_linear_mipmap_anisotropic, repeat_enable; uniform bool foliage = false; uniform bool bark = false; uniform bool soil = false; uniform bool paving = false; varying vec3 world; varying vec3 world_normal; float hash(vec3 p) { p=fract(p*.1031); p+=dot(p,p.yzx+33.33); return fract((p.x+p.y)*p.z); } float noise(vec3 p) { vec3 i=floor(p),f=fract(p); f=f*f*(3.0-2.0*f); return mix(mix(mix(hash(i),hash(i+vec3(1,0,0)),f.x),mix(hash(i+vec3(0,1,0)),hash(i+vec3(1,1,0)),f.x),f.y),mix(mix(hash(i+vec3(0,0,1)),hash(i+vec3(1,0,1)),f.x),mix(hash(i+vec3(0,1,1)),hash(i+vec3(1,1,1)),f.x),f.y),f.z); } void vertex() { world=(MODEL_MATRIX*vec4(VERTEX,1.0)).xyz; world_normal=normalize(mat3(MODEL_MATRIX)*NORMAL); if(foliage) { float wind=sin(TIME*.8+world.x*.55+world.z*.32)*sin(TIME*.37+world.z*.6); VERTEX.x+=wind*.065*clamp(world.y*.3,.15,1.0); } } void fragment() { vec3 weights=pow(abs(world_normal),vec3(5.0)); weights/=max(dot(weights,vec3(1.0)),.0001); vec3 p=world*.23; vec3 stone=texture(stone_map,p.zy).rgb*weights.x+texture(stone_map,p.xz).rgb*weights.y+texture(stone_map,p.xy).rgb*weights.z; float grain=noise(world*21.0); float broad=noise(world*.8); float relief=dot(stone,vec3(.333)); ALBEDO=base_color.rgb*mix(vec3(.65),vec3(1.6),stone); ROUGHNESS=.88; if(paving) { ALBEDO=base_color.rgb*mix(vec3(.82),vec3(1.3),stone); } if(soil) { ALBEDO=base_color.rgb*mix(.82,1.12,broad)*mix(.78,1.2,relief); ALBEDO=mix(ALBEDO,vec3(.12,.17,.075),smoothstep(.54,.8,broad)*.16); } if(bark) { float ridges=noise(world*vec3(13,1.2,13)); ALBEDO=base_color.rgb*mix(.45,1.2,ridges)*mix(.8,1.08,grain); relief=ridges; } if(foliage) { ALBEDO=base_color.rgb*mix(.75,1.2,broad); ROUGHNESS=.79; BACKLIGHT=ALBEDO*.32; } vec3 n=NORMAL,dx=dFdx(VERTEX),dy=dFdy(VERTEX); vec3 rx=cross(dy,n),ry=cross(n,dx); float det=dot(dx,rx); vec3 gradient=dFdx(relief)*rx+dFdy(relief)*ry; if(!foliage) { NORMAL=normalize(abs(det)*n-sign(det)*gradient*(bark ? .025 : .016)); } }