Emission
The Smudge API is still changing pretty often. Code on this post is out of date.
In the very first version of the library, the process of drawing data to multiple buffers—for rgb, metallic, height, etc—was hardcoded with a lot of repeated, inflexible code for each channel. This approach worked for a quick proof-of-concept, but as the steps needed to draw a buffer become more complex this approach begins to break down.
Now the buffers are described with a data structure, and the code loops over that structure drawing to each buffer. The new code has much less repetition and is easier to maintain and more flexible. An immediate benefit was that adding support for emission channels was a snap.
Drawing to the emission components is easy too. Just specify emission values when you construct a material. You can also set them using property accessors.
// specify each channel in the constructor
// new Material(r, g, b, a, metallic, smoothness, height, emit_r, emit_g, emit_b)
const exampleMaterial = new Material(.5, 0.0, 0.0, 1.0, .6, .25, .5, 1.0, 0.0, 0.0);
// or using property accessors
const exampleMaterial = new Material(.5, 0.0, 0.0, 1.0, .6, .25, .5);
light_on.emission_red = 1.0;
light_on.emission_green = .0;
light_on.emission_blue = .0;
Below are some renderings that show off a procedural texture with emission components.
And this is the full code that generated the textures used in the renderings.
let pbr = new PBR(undefined, 1024, 1024, 4);
const metal = new Material(0.5, 0.5, 0.5, 1.0, 0.5, 0.25, 0.5);
const panel = new Material(0.5, 0.5, 0.5, 1.0, 0.4, 0.25, 0.5);
const light_off = new Material(.5, 0.0, 0.0, 1.0, .6);
const light_on = new Material(.5, 0.0, 0.0, 1.0, .6);
light_on.emission_red = 1.0;
light_on.emission_green = .2;
light_on.emission_blue = .1;
pbr.clear(metal);
let rows = 32;
let cols = 16;
let padding = 2;
for (let row = 0; row < rows; row++) {
for (let col = 0; col < cols; col++) {
let width = pbr.width / cols;
let height = pbr.height / rows;
let x = col * width;
let y = row * height;
pbr.rect(x + padding, y + padding, width - padding * 2, height - padding * 2, panel);
if (Math.random() > .75) {
pbr.rect(x + padding * 2, y + padding * 2, width - padding * 4, height - padding * 4, light_on);
} else {
pbr.rect(x + padding * 2, y + padding * 2, width - padding * 4, height - padding * 4, light_off);
}
}
}
pbr.show();