Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore unversioniert; letztere sind unter ../backups gesichert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.4 KiB
Text
55 lines
2.4 KiB
Text
shader_type spatial;
|
|
render_mode diffuse_burley, specular_schlick_ggx;
|
|
uniform vec4 base_color : source_color;
|
|
uniform float base_roughness = .85;
|
|
uniform bool bark = false;
|
|
uniform bool endgrain = false;
|
|
uniform bool moss = false;
|
|
uniform sampler2D oak_color : source_color, filter_linear_mipmap_anisotropic, repeat_enable;
|
|
uniform sampler2D oak_height : filter_linear_mipmap_anisotropic, repeat_enable;
|
|
varying vec3 position_model;
|
|
varying vec3 local_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() { position_model=VERTEX; local_normal=NORMAL; }
|
|
void fragment() {
|
|
vec3 p=position_model;
|
|
float mottling=noise(p*15.0);
|
|
float detail=noise(p*(bark ? vec3(105.0,12.0,105.0) : vec3(70.0)));
|
|
float fade=1.0-smoothstep(.005,.025,length(fwidth(p)));
|
|
detail=mix(.5,detail,fade);
|
|
float fissure=bark ? smoothstep(.36,.50,detail) : detail;
|
|
ALBEDO=base_color.rgb*mix(.64,1.04,mottling)*mix(.72,1.0,fissure);
|
|
if(bark) {
|
|
vec3 w=pow(abs(local_normal),vec3(6.0)); w/=max(dot(w,vec3(1)),.0001);
|
|
vec3 q=p*vec3(1.3,.72,1.3);
|
|
vec3 oak=texture(oak_color,q.zy).rgb*w.x+texture(oak_color,q.xz).rgb*w.y+texture(oak_color,q.xy).rgb*w.z;
|
|
detail=texture(oak_height,q.zy).r*w.x+texture(oak_height,q.xz).r*w.y+texture(oak_height,q.xy).r*w.z;
|
|
ALBEDO=base_color.rgb*(.60+oak*2.0);
|
|
} else {
|
|
ALBEDO=base_color.rgb*mix(.78,1.12,mottling);
|
|
BACKLIGHT=base_color.rgb*.20;
|
|
}
|
|
if(moss) {
|
|
float carpet=noise(p*48.0)*.6+noise(p*11.0)*.4;
|
|
ALBEDO=base_color.rgb*mix(.60,1.2,carpet);
|
|
detail=carpet;
|
|
}
|
|
if(endgrain) {
|
|
vec2 q=UV-vec2(.5); float a=atan(q.y,q.x);
|
|
float radius=length(q)*(1.0+.03*sin(a*3.0)+.02*cos(a*7.0));
|
|
float rings=sin(radius*210.0+sin(a*9.0)*.13)*.5+.5;
|
|
ALBEDO=base_color.rgb*mix(.76,1.08,rings)*mix(.90,1.03,noise(vec3(UV*150.0,0.0)));
|
|
detail=rings;
|
|
}
|
|
ROUGHNESS=clamp(base_roughness+(detail-.5)*.20,.5,1.0);
|
|
METALLIC=0.0;
|
|
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(detail)*rx+dFdy(detail)*ry;
|
|
NORMAL=normalize(abs(det)*n-sign(det)*gradient*(bark ? .006 : .0003));
|
|
}
|