Flip device image buffer vertically and horizontally

Hi,
I am trying to implement the whitted sample into my own VS 2019 solution and I get the whitted image flipped both horizontally and vertically. I had a look into OSPREY examples and I realize that they have implemented their own method to flip it by Y axis:

void Render::_flipImage(
    const float* in,
    float* out,
    const ospcommon::math::vec2i& size)
{
    for (int y = 0; y < size.y; ++y)
    {
        const float* inP = in + y * size.x * 4;
        float* outP = out + (size.y - 1 - y) * size.x * 4;
        memcpy(outP, inP, size.x * 4 * sizeof(float));
    }
}

Is there a way to flip the buffer back to normal using CUDA within the device? Alternatively what is the most effective way to do it similarly to OSPREY but for both axis?

You have complete control about how your ray tracer renders the image and can solve that very easily by changing the camera implementation inside your ray generation program.

The standard pinhole camera implementation used inside OptiX SDK examples is placing the launch index (0, 0) at the bottom-left origin of the image, means low memory addresses of the resulting linear buffer are starting at the bottom-left origin of the image.

This matches how OpenGL expects the memory layout when uploading texture images (origin bottom-left), which are used to display the ray traced images inside a window inside the OptiX SDK examples, so the ray traced images get displayed upright correctly.

If the framework you’re using to display ray traced images is expecting the image layout to have low memory addresses at the top-left of an image (DirectX and Vulkan do that), then the simplest method to flip that around without any loss in performance would be to change the ray generation program implementing the pinhole camera in a way that the launch index (0, 0) is in the top-left.

So in case of the optixWhitted example, change the camera.cu line 45 from

    const unsigned int image_index = params.width * idx.y + idx.x;

to

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

to used flipped y-coordinates and the resulting image is flipped vertically.
If you look closely at the flipImage code you posted, that is exactly how that is calculating the start addresses of the source and destination scanlines.

Similarly for the x-coordinate if you want to flip it horizontally (while it’s unclear why that should be required. That wouldn’t make much sense in a display routine from a memory layout perspective.)

(BTW, the line const uint3 dim = optixGetLaunchDimensions(); in that camera.cu is dead code and can be removed. Or if the launch dimensions are always matching params.width and height, then these are redundant and can be replaced by the launch dimensions.)

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.