103 lines
2.6 KiB
Java
103 lines
2.6 KiB
Java
package renderer.canvas;
|
|
|
|
import basics.math.algebra.Vector;
|
|
import optics.light.Color;
|
|
|
|
public class ContributionBuffer {
|
|
|
|
// linear rgb colors
|
|
private volatile Color[][] buffer;
|
|
// amount of samples for every pixel
|
|
private volatile double[][] samples;
|
|
|
|
private int width;
|
|
private int height;
|
|
|
|
private int maxSample;
|
|
|
|
public ContributionBuffer(int width, int height) {
|
|
this.width = width;
|
|
this.height = height;
|
|
|
|
this.buffer = new Color[width][height];
|
|
this.samples = new double[width][height];
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
for (int y = 0; y < height; y++) {
|
|
this.buffer[x][y] = Color.BLACK;
|
|
}
|
|
}
|
|
}
|
|
|
|
public void contribute(int x, int y, Color color) {
|
|
buffer[x][y] = buffer[x][y].add(color);
|
|
samples[x][y]++;
|
|
|
|
maxSample = Math.max(maxSample, (int) samples[x][y]);
|
|
}
|
|
|
|
/**
|
|
* Set all color values and sample count to zero
|
|
* All other calls to contribute() should be blocked during execution
|
|
*/
|
|
public void clear() {
|
|
for (int x = 0; x < width; x++) {
|
|
for (int y = 0; y < height; y++) {
|
|
// clear color
|
|
Color color = buffer[x][y];
|
|
color.r = color.g = color.b = 0;
|
|
// reset sample count
|
|
samples[x][y] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
private int getRGB(int x, int y) {
|
|
Color linearRGB = buffer[x][y].scale(1.0 / samples[x][y]);
|
|
|
|
linearRGB.colorCorrect();
|
|
|
|
int red = (int) (linearRGB.r* 255.0);
|
|
int green = (int) (linearRGB.g * 255.0);
|
|
int blue = (int) (linearRGB.b * 255.0);
|
|
|
|
red = Math.max(Math.min(red, 255), 0);
|
|
green = Math.max(Math.min(green, 255), 0);
|
|
blue = Math.max(Math.min(blue, 255), 0);
|
|
|
|
return 0xff000000 | red << 16 | green << 8 | blue;
|
|
}
|
|
|
|
public Color getPixel(int x, int y) {
|
|
return buffer[x][y].scale(1.0 / samples[x][y]);
|
|
}
|
|
|
|
public void visualizeSamples(int[] buffer) {
|
|
for (int y = 0; y < height; y++) {
|
|
int col = y * width;
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
buffer[col + x] = Color.diagonal(samples[x][y] / maxSample).getIntRGB();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void blit(int[] buffer) {
|
|
for (int y = 0; y < height; y++) {
|
|
int col = y * width;
|
|
|
|
for (int x = 0; x < width; x++) {
|
|
buffer[col + x] = getRGB(x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
public int getWidth() {
|
|
return width;
|
|
}
|
|
|
|
public int getHeight() {
|
|
return height;
|
|
}
|
|
}
|