Materials
ForgedThoughts currently has two layers:
- built-in host BSDF backends:
Lambert,Metal,Dielectric - Forge-defined material overrides and custom BSDF hooks
Example:
material SoftGold {
model: Metal;
color = #ebc757;
fn eval(ctx) {
let ndotl = max(dot(ctx.normal, ctx.wi), 0.0);
return mix(vec3(0.08, 0.06, 0.03), color, ndotl) * (1.0 / 3.14159265);
}
fn pdf(ctx) {
return max(dot(ctx.normal, ctx.wi), 0.0) / 3.14159265;
}
fn sample(ctx) {
return BsdfSample {
wi: ctx.normal,
f: color * (1.0 / 3.14159265),
pdf: 1.0,
delta: 0.0,
apply_cos: 1.0,
transmission: 0.0,
thin_walled: 0.0,
next_ior: ctx.current_ior
};
}
};
Material-local helper functions can also be reused across hooks:
material BrickLike {
model: Lambert;
let brick = vec3(0.68, 0.24, 0.16);
let mortar = vec3(0.8, 0.77, 0.72);
fn mortar_mask(ctx) {
let band_x = smoothstep(-0.12, 0.12, sin(ctx.local_position.x * 11.0));
let band_y = smoothstep(-0.12, 0.12, sin(ctx.local_position.y * 7.0));
return max(band_x, band_y);
}
fn color(ctx) {
return mix(brick, mortar, mortar_mask(ctx));
}
fn roughness(ctx) {
return mix(0.7, 0.95, mortar_mask(ctx));
}
fn normal(ctx) {
let mortar = mortar_mask(ctx);
let groove_x = cos(ctx.local_position.x * 11.0) * 0.18;
let groove_y = cos(ctx.local_position.y * 7.0) * 0.12;
return normalize(ctx.normal + vec3(groove_x * mortar, groove_y * mortar, 0.0));
}
};
Current Forge material hooks:
colorroughnessiorthin_walledemission_coloremission_strengthnormalmediumsubsurfaceevalpdfsample
Current context fields include:
ctx.positionctx.local_positionctx.normalctx.view_dirctx.woctx.wictx.current_iorctx.u1,ctx.u2,ctx.u3insidesample(ctx)
Materials can also be imported from disk or the built-in library:
import "./shared/brick.ft";
import "Gold" as gold;
Then use the imported definitions explicitly:
let scene = Sphere {
material: gold.Gold {}
};
The built-in library currently exposes:
materials/...objects/...scenes/...
Built-ins can be imported either by full path or by bare library name:
import "Glass";
import "materials/gold.ft";
For color-valued material fields, Forge also accepts hex literals as a shorthand for vec3(...):
let gold = Metal {
color: #ebc757,
roughness: 0.18
};
Current reality:
eval/pdf/sampleare integrated most cleanly in the path tracer- the recursive
rayrenderer still has some built-in material branching normal(ctx)perturbs the shading normal only; it does not change SDF intersections or silhouettes- material-local helper functions can be reused across hooks like
color,roughness, andnormal mediumalready affects transmission through simple absorptionsubsurfaceis structured material data but is not yet consumed as real transport
Use normal(ctx) for things like:
- brick and mortar relief
- grooves
- fine surface breakup
True displacement that changes the actual SDF shape is a later feature.