saumwacht-godot/scripts/presentation/ringborke.gdshader
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
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>
2026-09-27 20:00:36 +02:00

34 lines
1.3 KiB
Text

shader_type spatial;
render_mode diffuse_burley, specular_schlick_ggx;
uniform sampler2D wood_height : filter_linear_mipmap_anisotropic, repeat_enable;
uniform bool bark = false;
uniform bool leaf = false;
uniform bool endgrain = false;
void fragment() {
float h = texture(wood_height, UV).r;
ALBEDO = COLOR.rgb * (bark ? mix(.48,.85,h) : .80);
if (endgrain) {
vec2 p=(UV-vec2(.5))*2.0;
float a=atan(p.y,p.x), r=length(p);
float phase=r*12.0+.13*sin(a*3.0+r*9.0)+.07*sin(a*7.0-r*8.0);
float edge=abs(sin(phase*3.1415926));
float line=1.0-smoothstep(.12,.28+length(fwidth(p))*45.0,edge);
float fibres=sin(a*113.0+r*38.0)*sin(r*290.0+a*5.0);
float split=0.0;
for(int k=0;k<3;k++) {
float ca=.36+float(k)*2.12;
float dist=abs(atan(sin(a-ca-.012*sin(r*24.0)),cos(a-ca-.012*sin(r*24.0))));
split=max(split,(1.0-smoothstep(.003,.014,dist))*smoothstep(.48+.1*float(k),.91,r));
}
ALBEDO=vec3(.265,.147,.066)*mix(1.20,.56,line)*(1.0+fibres*.07)*mix(1.0,.20,split);
ROUGHNESS=.86;
}
ROUGHNESS = bark ? mix(.74,.96,h) : .84;
if (leaf) { BACKLIGHT = COLOR.rgb*.22; }
if (bark) {
vec3 dx=dFdx(VERTEX), dy=dFdy(VERTEX), n=NORMAL;
vec3 rx=cross(dy,n), ry=cross(n,dx);
float det=dot(dx,rx);
NORMAL=normalize(abs(det)*n-sign(det)*(dFdx(h)*rx+dFdy(h)*ry)*.0018);
}
}