我实际上正在开发一个实现Path Tracer的框架。我在理解最终图像的编写方式时遇到了问题。结果是正确的,图像看起来很好(样本数量很少):
但是我必须理解代码是如何工作的(因为我)对索引有些奇怪。这是简短的代码:
struct Vec {
double x, y, z; // position, also color (r,g,b)
Vec(double x_ = 0, double y_ = 0, double z_ = 0){ x = x_; y = y_; z = z_; }
};
Vec *c = new Vec[width * height];
for (int y = 0; y<height; y++){// Loop over image rows
for (unsigned short x = 0; x<width; x++) { // Loop cols
Vec r = calculatePixelColor(x,y);
int i = (height - y - 1) * width + x;
c[i] = c[i] + r;
}
}
FILE *ff = fopen("image.ppm", "w"); // Write image to PPM file.
fprintf(ff, "P3\n%d %d\n%d\n", width, height, 255);
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++){
Vec pixel = c[x + y * width];
int red = CLAMP((int)(sqrtf(pixel.x) * 255.0f), 0, 255);
int green = CLAMP((int)(sqrtf(pixel.y) * 255.0f), 0, 255);
int blue = CLAMP((int)(sqrtf(pixel.z) * 255.0f), 0, 255);
fprintf(ff, "%d %d %d ", (red), (green), (blue));
}
fclose(ff);
现在,我们有一个名为c
的Vec指针,其中包含像素的所有信息。此信息根据索引i = (height - y - 1) * width + x;
存储。这意味着Vec * c
开始描述最后一行的图像。因此,c
指向的第一个Vec是图像左下角的像素(如果我没有错)。因此,如果我是对的,这引出了我的问题:fprintf
如何运作?根据文档,它只是从顶部到底部写下流..因此理论上应该翻转图像。诀窍在哪里?