# Materials and textures `PBRMaterial` is a conventional view over `materials` and `materialTextures` SOA rows. ```ts const paint = new PBRMaterial(scene, { baseColor: [0.8, 0.05, 0.03, 1], metallic: 0.65, roughness: 0.22, emissive: [0, 0, 0], }); await paint.ready; paint.roughness = 0.5; // direct SAB write paint.baseColor[1] = 0.35; // direct SAB write mesh.material = paint; ``` ## Graph textures ```ts const albedo = new Texture(scene, { source: "/textures/paint.ktx2", size: [2048, 2048, 1], format: "rgba8unorm-srgb", usage: ["sampled", "copyDst"], }); await albedo.ready; const textured = new PBRMaterial(scene, { baseColorTexture: albedo }); ``` Creating or removing a `Texture` rebuilds the single graph loadout so the GPU resource is allocated up front. The source pointer stays on the handle for an importer or application uploader; core never owns image-loading policy. ## Custom WGSL `ShaderMaterial` adds its external WGSL pipeline to the scene graph. Updating the code updates the loadout. ```ts const shader = new ShaderMaterial(scene, { code: ` struct Out { @builtin(position) position: vec4 } @vertex fn vertex(@builtin(vertex_index) id: u32) -> Out { let p = array(vec2(-.2, -.2), vec2(.2, -.2), vec2(0., .2)); var out: Out; out.position = vec4(p[id], 0., 1.); return out; } @fragment fn fragment() -> @location(0) vec4 { return vec4(1., .2, .7, 1.); } `, }); await shader.ready; ```