How to flip sutil::ImageBuffer on Y-axis?

I am using the path tracer on a custom renderer and while I am trying to capture the rendered image I get it flipped on the y-axis:

sutil::ImageBuffer buffer;
buffer.data = output_buffer.getHostPointer();
buffer.width = output_buffer.width();
buffer.height = buffer.height();
buffer.pixel_format = sutil::BufferImageFormat::UNSIGNED_BYTE4;

sutil::saveImage(outfile.c_str(), buffer, false);

Is there a way to flip the image on y-axis or flip the imageBuffer?

Typically OpenGL and other display libraries will have (0,0) at the bottom left corner of your screen and Y increases in the up direction, while image file formats consider (0,0) to be at the top left corner of the image, and Y increases when going down.

For this reason, sutil::saveImage() reverses Y when scanning the image out to a file:
for( int j = height - 1; j >= 0; --j )

If your custom renderer was already handling this, or if it is setup so that the screen-displayed image has a top-left origin with Y-down, then you may be accidentally flipping the image twice when writing it to a file, once in your code, and again in sutil::saveImage, and ending up with the output image upside-down.

The simplest solution is to flip your Y coordinate mapping in your raygen program, however if you display interactively via OpenGL or some other API this will flip your displayed image upside down even though it fixes the exported image file. What you want to do is make sure your raygen pixel coordinates match your display coordinates, that both are Y-up, and then let sutil::saveImage() handle correctly flipping your image file so that image viewers will show it right-side-up. If you aren’t using a Y-down pixel coordinate system, the other thing to check is if you’re accidentally mixing left-handed and right-handed 3d coordinates and ending up with a parity error in Y, if that makes sense.


David.

I had flipped the buffer in the pathtracer.cu file in order to have the rendered file properly:

//const unsigned int image_index  = launch_index.y * params.width + launch_index.x;
const unsigned int image_index = params.width * (params.height - 1 - idx.y) + idx.x;

I just realized that I am working on png files and the only I had to do was to change the corresponding code in sutil, rebuild and use the new dll

else if(  ext == "PNG" || ext == "png" )
{
    switch( image.pixel_format )
    {
        case BufferImageFormat::UNSIGNED_BYTE4:
        {
            //stbi_flip_vertically_on_write( true );
            stbi_flip_vertically_on_write( false );

With this I can have the captured files as well at the proper orientation.
Thanks!

1 Like