Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract canvas size code from Scene into separate CanvasConfig class #1560

Merged
merged 6 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions chunky/src/java/se/llbit/chunky/renderer/DefaultRenderManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,7 @@ private void updateRenderState(Scene scene) {
* @return the current rendering speed in samples per second (SPS)
*/
private int samplesPerSecond() {
int canvasWidth = bufferedScene.canvasWidth();
int canvasHeight = bufferedScene.canvasHeight();
long pixelsPerFrame = (long) canvasWidth * canvasHeight;
long pixelsPerFrame = bufferedScene.canvasConfig.getPixelCount();
double renderTime = bufferedScene.renderTime / 1000.0;
return (int) ((bufferedScene.spp * pixelsPerFrame) / renderTime);
}
Expand Down Expand Up @@ -423,19 +421,21 @@ protected void finalizeFrame(boolean force) {
if (filter instanceof PixelPostProcessingFilter) {
PixelPostProcessingFilter pixelFilter = (PixelPostProcessingFilter) filter;

int width = bufferedScene.width;
int height = bufferedScene.height;
int width = bufferedScene.canvasConfig.getWidth();
int height = bufferedScene.canvasConfig.getHeight();
int totalPixelCount = bufferedScene.canvasConfig.getPixelCount();

double[] sampleBuffer = bufferedScene.getSampleBuffer();
double exposure = bufferedScene.getExposure();

// Split up to 10 tasks per thread
int tasksPerThread = 10;
int pixelsPerTask = (bufferedScene.width * bufferedScene.height) / (pool.threads * tasksPerThread - 1);
int pixelsPerTask = (totalPixelCount / (pool.threads * tasksPerThread - 1));
ArrayList<RenderWorkerPool.RenderJobFuture> jobs = new ArrayList<>(pool.threads * tasksPerThread);

for (int i = 0; i < bufferedScene.width * bufferedScene.height; i += pixelsPerTask) {
for (int i = 0; i < totalPixelCount; i += pixelsPerTask) {
int start = i;
int end = Math.min(bufferedScene.width * bufferedScene.height, i + pixelsPerTask);
int end = Math.min(totalPixelCount, i + pixelsPerTask);
jobs.add(pool.submit(worker -> {
double[] pixelbuffer = new double[3];

Expand Down Expand Up @@ -572,7 +572,8 @@ public RenderStatus getRenderStatus() {
@Override
public void withSampleBufferProtected(SampleBufferConsumer consumer) {
synchronized (bufferedScene) {
consumer.accept(bufferedScene.getSampleBuffer(), bufferedScene.width, bufferedScene.height);
consumer.accept(bufferedScene.getSampleBuffer(),
bufferedScene.canvasConfig.getWidth(), bufferedScene.canvasConfig.getHeight());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,12 @@ public String getDescription() {
public void render(DefaultRenderManager manager) throws InterruptedException {
Scene scene = manager.bufferedScene;

int width = scene.width;
int height = scene.height;
int width = scene.canvasConfig.getWidth();

int fullWidth = scene.getFullWidth();
int fullHeight = scene.getFullHeight();
int cropX = scene.getCropX();
int cropY = scene.getCropY();
int fullWidth = scene.canvasConfig.getCropWidth();
int fullHeight = scene.canvasConfig.getCropHeight();
int cropX = scene.canvasConfig.getCropX();
int cropY = scene.canvasConfig.getCropY();

int sppPerPass = manager.context.sppPerPass();

Expand Down
11 changes: 5 additions & 6 deletions chunky/src/java/se/llbit/chunky/renderer/PreviewRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,12 @@ public void render(DefaultRenderManager manager) throws InterruptedException {

Scene scene = manager.bufferedScene;

int width = scene.width;
int height = scene.height;
int width = scene.canvasConfig.getWidth();

int fullWidth = scene.getFullWidth();
int fullHeight = scene.getFullHeight();
int cropX = scene.getCropX();
int cropY = scene.getCropY();
int fullWidth = scene.canvasConfig.getCropWidth();
int fullHeight = scene.canvasConfig.getCropHeight();
int cropX = scene.canvasConfig.getCropX();
int cropY = scene.canvasConfig.getCropY();

Camera cam = scene.camera();
double halfWidth = fullWidth / (2.0 * fullHeight);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ protected void submitTiles(DefaultRenderManager manager, BiConsumer<WorkerState,
}

private void initTiles(DefaultRenderManager manager) {
Scene bufferedScene = manager.bufferedScene;
int width = bufferedScene.width;
int height = bufferedScene.height;
Scene scene = manager.bufferedScene;
int tileWidth = manager.context.tileWidth();
int width = scene.canvasConfig.getWidth();
int height = scene.canvasConfig.getHeight();

if (prevWidth != width || prevHeight != height) {
prevWidth = width;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public String getExtension() {

@Override
public void write(OutputStream out, Scene scene, TaskTracker taskTracker) throws IOException {
try (TaskTracker.Task task = taskTracker.task("Writing PFM rows", scene.canvasHeight());
try (TaskTracker.Task task = taskTracker.task("Writing PFM rows", scene.canvasConfig.getHeight());
PfmFileWriter writer = new PfmFileWriter(out)) {
writer.write(scene, task);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@ public AlphaBuffer.Type getTransparencyType() {
public void write(OutputStream out, Scene scene, TaskTracker taskTracker) throws IOException {
try (TaskTracker.Task task = taskTracker.task("Writing PNG");
PngFileWriter writer = new PngFileWriter(out)) {
int width = scene.canvasConfig.getWidth();
int height = scene.canvasConfig.getHeight();
BitmapImage backBuffer = scene.getBackBuffer();
AlphaBuffer alpha = scene.getAlphaBuffer();
if (alpha.getType() == getTransparencyType()) {
writer.write(backBuffer.data, alpha.getBuffer(), scene.canvasWidth(), scene.canvasHeight(), task);
writer.write(backBuffer.data, alpha.getBuffer(), width, height, task);
} else {
writer.write(backBuffer.data, scene.canvasWidth(), scene.canvasHeight(), task);
writer.write(backBuffer.data, width, height, task);
}
if (scene.camera().getProjectionMode() == ProjectionMode.PANORAMIC
&& scene.camera().getFov() >= 179
Expand Down Expand Up @@ -86,10 +88,10 @@ private void writePanoramaMetaData(Scene scene, PngFileWriter writer) throws IOE
"XML:com.adobe.xmp",
String.format(
PNG_PANORAMA_META_ADOBE_RDF_XML,
scene.canvasHeight(),
scene.canvasWidth(),
scene.canvasHeight(),
scene.canvasWidth()
scene.canvasConfig.getHeight(),
scene.canvasConfig.getWidth(),
scene.canvasConfig.getHeight(),
scene.canvasConfig.getWidth()
)
));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,30 +65,30 @@ public void load(DataInputStream inputStream, Scene scene, TaskTracker taskTrack
throws IOException, IllegalStateException {
double[] samples = scene.getSampleBuffer();

try (TaskTracker.Task task = taskTracker.task("Loading render dump", scene.width * scene.height)) {
try (TaskTracker.Task task = taskTracker.task("Loading render dump", scene.canvasConfig.getPixelCount())) {
readHeader(inputStream, scene);
readSamples(inputStream, scene, (index, r, g, b) -> {
int offset = index * 3;
samples[offset + 0] = r;
samples[offset + 1] = g;
samples[offset + 2] = b;
}, i -> task.updateInterval(i, scene.width));
}, i -> task.updateInterval(i, scene.canvasConfig.getWidth()));
}
}

@Override
public void save(DataOutputStream outputStream, Scene scene, TaskTracker taskTracker)
throws IOException {
try (TaskTracker.Task task = taskTracker.task("Saving render dump", scene.width * scene.height)) {
try (TaskTracker.Task task = taskTracker.task("Saving render dump", scene.canvasConfig.getPixelCount())) {
writeHeader(outputStream, scene);
writeSamples(outputStream, scene, i -> task.updateInterval(i, scene.width));
writeSamples(outputStream, scene, i -> task.updateInterval(i, scene.canvasConfig.getWidth()));
}
}

@Override
public void merge(DataInputStream inputStream, Scene scene, TaskTracker taskTracker)
throws IOException, IllegalStateException {
try (TaskTracker.Task task = taskTracker.task("Merging render dump", scene.width * scene.height)) {
try (TaskTracker.Task task = taskTracker.task("Merging render dump", scene.canvasConfig.getPixelCount())) {
int sceneSpp = scene.spp;
long previousRenderTime = scene.renderTime;

Expand All @@ -104,7 +104,7 @@ public void merge(DataInputStream inputStream, Scene scene, TaskTracker taskTrac
samples[offset + 0] = (samples[offset + 0] * sceneSpp + r * dumpSpp) * sinv;
samples[offset + 1] = (samples[offset + 1] * sceneSpp + g * dumpSpp) * sinv;
samples[offset + 2] = (samples[offset + 2] * sceneSpp + b * dumpSpp) * sinv;
}, i -> task.updateInterval(i, scene.width));
}, i -> task.updateInterval(i, scene.canvasConfig.getWidth()));

scene.spp += sceneSpp;
scene.renderTime += previousRenderTime;
Expand All @@ -115,7 +115,7 @@ protected void readHeader(DataInputStream inputStream, Scene scene) throws IOExc
int width = inputStream.readInt();
int height = inputStream.readInt();

if (width != scene.canvasWidth() || height != scene.canvasHeight()) {
if (width != scene.canvasConfig.getWidth() || height != scene.canvasConfig.getHeight()) {
throw new IllegalStateException("Scene size does not match dump size");
}

Expand All @@ -124,8 +124,8 @@ protected void readHeader(DataInputStream inputStream, Scene scene) throws IOExc
}

protected void writeHeader(DataOutputStream outputStream, Scene scene) throws IOException {
outputStream.writeInt(scene.width);
outputStream.writeInt(scene.height);
outputStream.writeInt(scene.canvasConfig.getWidth());
outputStream.writeInt(scene.canvasConfig.getHeight());
outputStream.writeInt(scene.spp);
outputStream.writeLong(scene.renderTime);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ protected void readSamples(DataInputStream inputStream, Scene scene,
double r, g, b;

// Warning: This format writes in column major order
for (int x = 0; x < scene.width; x++) {
for (int y = 0; y < scene.height; y++) {
pixelIndex = (y * scene.width + x);
for (int x = 0; x < scene.canvasConfig.getWidth(); x++) {
for (int y = 0; y < scene.canvasConfig.getHeight(); y++) {
pixelIndex = (y * scene.canvasConfig.getWidth() + x);
r = inputStream.readDouble();
g = inputStream.readDouble();
b = inputStream.readDouble();
Expand All @@ -90,9 +90,9 @@ protected void writeSamples(DataOutputStream outputStream, Scene scene,
int done = 0;

// Warning: This format writes in column major order
for (int x = 0; x < scene.width; ++x) {
for (int y = 0; y < scene.height; ++y) {
offset = (y * scene.width + x) * 3;
for (int x = 0; x < scene.canvasConfig.getWidth(); ++x) {
for (int y = 0; y < scene.canvasConfig.getHeight(); ++y) {
offset = (y * scene.canvasConfig.getWidth() + x) * 3;
outputStream.writeDouble(samples[offset + 0]);
outputStream.writeDouble(samples[offset + 1]);
outputStream.writeDouble(samples[offset + 2]);
Expand Down
20 changes: 11 additions & 9 deletions chunky/src/java/se/llbit/chunky/renderer/scene/AlphaBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,21 @@ void computeAlpha(Scene scene, Type type, TaskTracker taskTracker) {

try (TaskTracker.Task task = taskTracker.task("Computing alpha channel")) {
this.type = type;
buffer = ByteBuffer.allocate(scene.width * scene.height * type.byteSize);
int width = scene.canvasConfig.getWidth();
int height = scene.canvasConfig.getHeight();
buffer = ByteBuffer.allocate(scene.canvasConfig.getPixelCount() * type.byteSize);

AtomicInteger done = new AtomicInteger(0);
Chunky.getCommonThreads().submit(() -> {
IntStream.range(0, scene.width).parallel().forEach(x -> {
IntStream.range(0, width).parallel().forEach(x -> {
WorkerState state = new WorkerState();
state.ray = new Ray();

for (int y = 0; y < scene.height; y++) {
computeAlpha(scene, x, y, state);
for (int y = 0; y < height; y++) {
computeAlpha(scene, x, y, width, height, state);
}

task.update(scene.width, done.incrementAndGet());
task.update(width, done.incrementAndGet());
});
}).get();
} catch (InterruptedException | ExecutionException e) {
Expand All @@ -95,10 +97,10 @@ void computeAlpha(Scene scene, Type type, TaskTracker taskTracker) {
/**
* Compute the alpha channel based on sky visibility.
*/
public void computeAlpha(Scene scene, int x, int y, WorkerState state) {
public void computeAlpha(Scene scene, int x, int y, int width, int height, WorkerState state) {
Ray ray = state.ray;
double halfWidth = scene.width / (2.0 * scene.height);
double invHeight = 1.0 / scene.height;
double halfWidth = width / (2.0 * height);
double invHeight = 1.0 / height;

// Rotated grid supersampling.
double[][] offsets = new double[][]{
Expand All @@ -124,6 +126,6 @@ public void computeAlpha(Scene scene, int x, int y, WorkerState state) {
}
occlusion /= 4.0;

type.writer.write(buffer, y * scene.width + x, occlusion);
type.writer.write(buffer, y * width + x, occlusion);
}
}
Loading
Loading