update
This commit is contained in:
129
scripts/stoffe.gd
Normal file
129
scripts/stoffe.gd
Normal file
@@ -0,0 +1,129 @@
|
||||
extends RefCounted
|
||||
## Materialien ohne Texturdateien: Holz, Filz und Messing werden im Shader
|
||||
## aus Rauschen gerechnet. Alles, was Maserung, Flecken oder Anlauf ist, sind
|
||||
## Zahlen - keine Bilder. Siehe assets.md. Kein class_name (headless kein Cache).
|
||||
|
||||
const RAUSCHEN := """
|
||||
float hash2(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }
|
||||
float noise2(vec2 p) {
|
||||
vec2 i = floor(p); vec2 f = fract(p); f = f * f * (3.0 - 2.0 * f);
|
||||
return mix(mix(hash2(i), hash2(i + vec2(1, 0)), f.x),
|
||||
mix(hash2(i + vec2(0, 1)), hash2(i + vec2(1, 1)), f.x), f.y);
|
||||
}
|
||||
float fbm2(vec2 p) {
|
||||
float v = 0.0; float a = 0.5;
|
||||
for (int k = 0; k < 4; k++) { v += a * noise2(p); p = p * 2.03 + 17.0; a *= 0.5; }
|
||||
return v;
|
||||
}
|
||||
"""
|
||||
|
||||
## Holz: Jahresringe entlang einer Achse, leicht verzerrt, plus feine
|
||||
## Faser. Weltkoordinaten, damit die Maserung über Teile hinweg durchläuft.
|
||||
const HOLZ := """
|
||||
shader_type spatial;
|
||||
uniform vec4 base_color : source_color = vec4(0.42, 0.27, 0.13, 1.0);
|
||||
uniform vec4 dark_color : source_color = vec4(0.22, 0.13, 0.06, 1.0);
|
||||
uniform float wear : hint_range(0.0, 1.0) = 0.4;
|
||||
uniform float ring_scale = 9.0;
|
||||
varying vec3 wp;
|
||||
""" + RAUSCHEN + """
|
||||
void vertex() { wp = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
|
||||
void fragment() {
|
||||
vec2 p = wp.xz;
|
||||
float verzerrt = p.x * ring_scale + fbm2(p * 2.5) * 3.0;
|
||||
float ring = smoothstep(0.2, 0.8, abs(fract(verzerrt) - 0.5) * 2.0);
|
||||
float faser = noise2(vec2(p.x * 60.0, p.y * 4.0)) * 0.12;
|
||||
vec3 col = mix(dark_color.rgb, base_color.rgb, ring) + faser - 0.06;
|
||||
float flecken = fbm2(p * 6.0 + 40.0);
|
||||
col = mix(col, col * 0.75, smoothstep(0.55, 0.8, flecken) * wear);
|
||||
ALBEDO = col;
|
||||
ROUGHNESS = 0.55 + ring * 0.25 + wear * 0.15;
|
||||
SPECULAR = 0.3;
|
||||
}
|
||||
"""
|
||||
|
||||
## Filz: gleichmässige Fläche mit feinem Flaum, leicht fleckig, an den
|
||||
## Rändern dunkler. Ohne das sähe die Zone aus wie Plastik.
|
||||
const FILZ := """
|
||||
shader_type spatial;
|
||||
uniform vec4 base_color : source_color = vec4(0.07, 0.20, 0.13, 1.0);
|
||||
uniform float wear : hint_range(0.0, 1.0) = 0.5;
|
||||
uniform float radius = 0.68;
|
||||
varying vec3 lp;
|
||||
varying vec3 wp;
|
||||
""" + RAUSCHEN + """
|
||||
void vertex() { lp = VERTEX; wp = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
|
||||
void fragment() {
|
||||
float flaum = noise2(wp.xz * 90.0) * 0.10 + noise2(wp.xz * 300.0) * 0.05;
|
||||
float flecken = fbm2(wp.xz * 3.0) ;
|
||||
float rand = smoothstep(radius * 0.7, radius, length(lp.xz));
|
||||
vec3 col = base_color.rgb * (0.9 + flaum) * (1.0 - flecken * 0.25 * wear) * (1.0 - rand * 0.25);
|
||||
ALBEDO = col;
|
||||
ROUGHNESS = 0.97;
|
||||
SPECULAR = 0.1;
|
||||
}
|
||||
"""
|
||||
|
||||
## Messing: metallisch, mit Anlauf in den Vertiefungen und einem Hauch
|
||||
## Farbschwankung. Die Prägung bleibt ein eigenes Mesh.
|
||||
const MESSING := """
|
||||
shader_type spatial;
|
||||
uniform vec4 base_color : source_color = vec4(0.80, 0.62, 0.26, 1.0);
|
||||
uniform float wear : hint_range(0.0, 1.0) = 0.4;
|
||||
uniform float emission : hint_range(0.0, 2.0) = 0.35;
|
||||
varying vec3 wp;
|
||||
""" + RAUSCHEN + """
|
||||
void vertex() { wp = (MODEL_MATRIX * vec4(VERTEX, 1.0)).xyz; }
|
||||
void fragment() {
|
||||
float anlauf = fbm2(wp.xz * 40.0);
|
||||
vec3 col = base_color.rgb * (0.85 + anlauf * 0.3);
|
||||
col = mix(col, col * vec3(0.7, 0.6, 0.5), smoothstep(0.6, 0.85, anlauf) * wear);
|
||||
ALBEDO = col;
|
||||
METALLIC = 0.9;
|
||||
ROUGHNESS = 0.25 + anlauf * 0.35 * wear;
|
||||
EMISSION = base_color.rgb * 0.6 * emission;
|
||||
}
|
||||
"""
|
||||
|
||||
static var _holz: Shader
|
||||
static var _filz: Shader
|
||||
static var _messing: Shader
|
||||
|
||||
|
||||
static func _shader(code: String) -> Shader:
|
||||
var s := Shader.new()
|
||||
s.code = code
|
||||
return s
|
||||
|
||||
|
||||
static func holz(farbe: Color, dunkel: Color, wear := 0.4, ring_scale := 9.0) -> ShaderMaterial:
|
||||
if _holz == null:
|
||||
_holz = _shader(HOLZ)
|
||||
var m := ShaderMaterial.new()
|
||||
m.shader = _holz
|
||||
m.set_shader_parameter("base_color", farbe)
|
||||
m.set_shader_parameter("dark_color", dunkel)
|
||||
m.set_shader_parameter("wear", wear)
|
||||
m.set_shader_parameter("ring_scale", ring_scale)
|
||||
return m
|
||||
|
||||
|
||||
static func filz(farbe: Color, radius: float, wear := 0.5) -> ShaderMaterial:
|
||||
if _filz == null:
|
||||
_filz = _shader(FILZ)
|
||||
var m := ShaderMaterial.new()
|
||||
m.shader = _filz
|
||||
m.set_shader_parameter("base_color", farbe)
|
||||
m.set_shader_parameter("radius", radius)
|
||||
m.set_shader_parameter("wear", wear)
|
||||
return m
|
||||
|
||||
|
||||
static func messing(emission := 0.35, wear := 0.4) -> ShaderMaterial:
|
||||
if _messing == null:
|
||||
_messing = _shader(MESSING)
|
||||
var m := ShaderMaterial.new()
|
||||
m.shader = _messing
|
||||
m.set_shader_parameter("emission", emission)
|
||||
m.set_shader_parameter("wear", wear)
|
||||
return m
|
||||
Reference in New Issue
Block a user