<p>It doesn't matter. All that matters is that you can store information per pixel. </p>

<p>In most cases this means allocating a <code>x*y</code> array of <code>int</code>s (for 3 byte-sized channels of RGB) to store the pixel values and then feed it into your image compression library of choice to save it out to disk.</p>

CC BY-SA 3.0
2016-11-10T09:40:12.813Z
2016-11-10T09:40:12.813Z
ratchet freak
<p>Depends if you are talking about CPU or GPU ray tracer. For CPU you generally simply allocate an array of width * height float4's (i.e. for RGB &amp; alpha) and for GPU you allocate a texture (e.g. R16G16B16A16F or R32G32B32A32F format). It depends on your case if you really need the alpha though. The target on CPU is then simply accessed by image[(x+y*width)*4] (image=float array), and on GPU image[uint2(x, y)] (image=UAV).</p>

<p>You generally want this target to be a float format (16-bit or 32-bit) to be able to handle high dynamic range (HDR) of luminance in the scene (think of a scene illuminated by Sun = ~100,000 Lux vs Moon = ~1 Lux), that gets then <a href="https://en.wikipedia.org/wiki/Exposure_value" rel="nofollow noreferrer">exposed</a> using camera settings, <a href="https://en.wikipedia.org/wiki/Tone_mapping" rel="nofollow noreferrer">tone mapped</a> and converted to <a href="https://en.wikipedia.org/wiki/SRGB" rel="nofollow noreferrer">sRGB space</a> to be viewable on regular 8bpc devices.</p>

<p>If you are with a very strict with memory budget, you may allocate LDR target (e.g. R8G8B8A8_UNORM) and perform camera exposure, tone mapping &amp; sRGB conversion before writing the result to the render target. This has bunch of issues though, e.g. you would need the camera exposure value prior to rendering, which can be a challenge for camera auto-exposure, so it's generally adviced to use HDR target instead.</p>

CC BY-SA 3.0
2016-11-11T01:53:34.100Z
I would also mention that LDR is probably more suited to eye-side ray-tracing as you don't need to accumulate a lot of small parts that often.
akaltar
CC BY-SA 3.0
2016-11-10T14:31:59.117Z
2016-11-10T14:31:59.117Z
JarkkoL
<p>Do you use MFC? If so, here's a code snippet to write a red gradient image using MFC's CImage. The top of the image is redder. Because <a href="https://msdn.microsoft.com/library/52861e3d-bf7e-481f-a240-90e88f76c490.aspx#cimage__create" rel="nofollow noreferrer">height is positive</a>, it's a <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd407212(v=vs.85).aspx" rel="nofollow noreferrer">bottom-up DIB</a> and higher values of y (in GetPixelAddress()) point to earlier scanlines (i.e. lower in the image):</p>

<pre><code>    const unsigned int imageWidth = 100;
    const unsigned int imageHeight = 255;
    CImage img;
    img.Create(imageWidth,imageHeight,24,0);
    for(unsigned int x = 0; x &lt; imageWidth; ++x)
    {
        for(unsigned int y = 0; y &lt; imageHeight; ++y)
        {
            // Note BGR, not RGB!
            unsigned char* pixelP = static_cast&lt;unsigned char*&gt;(img.GetPixelAddress(x,imageHeight - 1 - y));
            pixelP[0] = 0;
            pixelP[1] = 0;
            pixelP[2] = y;
        }
    }

    HRESULT hr = img.Save("c:\\red.bmp",Gdiplus::ImageFormatBMP);
</code></pre>

<p>There's many image formats, and many different ways to do this. I'll probably migrate away from CImage at some future point...</p>

CC BY-SA 3.0
2016-11-10T11:28:06.017Z
2016-11-10T11:39:00.527Z
2016-11-10T11:39:00.527Z
PeteUK
<p>I have begun learning how to create a Ray Tracer and 1 thing I am confused about is <strong>how the pixel color from a Ray Tracer is stored into an image</strong>. Do we use <code>SetPixel</code> for a Bitmap? Do we use a third party library like <a href="http://www.libpng.org/pub/png/libpng.html" rel="nofollow noreferrer">libpng?</a></p>

<p>Most tutorials don't really explain this well online, so if anyone can explain what the most common method for this is that would be great.</p>

CC BY-SA 3.0
2016-11-29T13:47:18.257Z
[OpenEXR](http://openexr.com/index.html) is widely used in industry, with everything you'd expect: HDR, 32-bit float and 'half' float channel support, and support for color management, which is critical when you're using profiles to make sure the colors on your monitor match up with rushes you're viewing on, say, a projector. A lot of what it offers might not be useful to you, but the software is free, and there are plenty of minimal examples.
Brett Hale
<raytracing><c++><image>
How are the colors for each pixel from a Ray Tracer stored in an Image?
Arjan Singh
# How are the colors for each pixel from a Ray Tracer stored in an Image?

(Asked by: username_0 on 2016-11-10)

I have begun learning how to create a Ray Tracer and 1 thing I am confused about is **how the pixel color from a Ray Tracer is stored into an image**. Do we use `SetPixel` for a Bitmap? Do we use a third party library like [libpng?](http://www.libpng.org/pub/png/libpng.html)

Most tutorials don't really explain this well online, so if anyone can explain what the most common method for this is that would be great.

**Tags:** raytracing, c++, image

> **Comments:**
> **username_1**: [OpenEXR](http://openexr.com/index.html) is widely used in industry, with everything you'd expect: HDR, 32-bit float and 'half' float channel support, and support for color management, which is critical when you're using profiles to make sure the colors on your monitor match up with rushes you're viewing on, say, a projector. A lot of what it offers might not be useful to you, but the software is free, and there are plenty of minimal examples.  

---

## 3 answers

### Answer by username_2 on 2016-11-10. Score: 3 | Accepted answer

It doesn't matter. All that matters is that you can store information per pixel.

In most cases this means allocating a `x*y` array of `int`s (for 3 byte-sized channels of RGB) to store the pixel values and then feed it into your image compression library of choice to save it out to disk.


---

### Answer by username_3 on 2016-11-10. Score: 3

Depends if you are talking about CPU or GPU ray tracer. For CPU you generally simply allocate an array of width \* height float4's (i.e. for RGB & alpha) and for GPU you allocate a texture (e.g. R16G16B16A16F or R32G32B32A32F format). It depends on your case if you really need the alpha though. The target on CPU is then simply accessed by image[(x+y\*width)\*4] (image=float array), and on GPU image[uint2(x, y)] (image=UAV).

You generally want this target to be a float format (16-bit or 32-bit) to be able to handle high dynamic range (HDR) of luminance in the scene (think of a scene illuminated by Sun = ~100,000 Lux vs Moon = ~1 Lux), that gets then [exposed](https://en.wikipedia.org/wiki/Exposure_value) using camera settings, [tone mapped](https://en.wikipedia.org/wiki/Tone_mapping) and converted to [sRGB space](https://en.wikipedia.org/wiki/SRGB) to be viewable on regular 8bpc devices.

If you are with a very strict with memory budget, you may allocate LDR target (e.g. R8G8B8A8\_UNORM) and perform camera exposure, tone mapping & sRGB conversion before writing the result to the render target. This has bunch of issues though, e.g. you would need the camera exposure value prior to rendering, which can be a challenge for camera auto-exposure, so it's generally adviced to use HDR target instead.

> **Comments:**
> **username_4**: I would also mention that LDR is probably more suited to eye-side ray-tracing as you don't need to accumulate a lot of small parts that often.  

---

### Answer by username_5 on 2016-11-10. Score: 1

Do you use MFC? If so, here's a code snippet to write a red gradient image using MFC's CImage. The top of the image is redder. Because [height is positive](https://msdn.microsoft.com/library/52861e3d-bf7e-481f-a240-90e88f76c490.aspx#cimage__create), it's a [bottom-up DIB](https://msdn.microsoft.com/en-us/library/windows/desktop/dd407212(v=vs.85).aspx) and higher values of y (in GetPixelAddress()) point to earlier scanlines (i.e. lower in the image):

```
    const unsigned int imageWidth = 100;
    const unsigned int imageHeight = 255;
    CImage img;
    img.Create(imageWidth,imageHeight,24,0);
    for(unsigned int x = 0; x < imageWidth; ++x)
    {
        for(unsigned int y = 0; y < imageHeight; ++y)
        {
            // Note BGR, not RGB!
            unsigned char* pixelP = static_cast<unsigned char*>(img.GetPixelAddress(x,imageHeight - 1 - y));
            pixelP[0] = 0;
            pixelP[1] = 0;
            pixelP[2] = y;
        }
    }

    HRESULT hr = img.Save("c:\\red.bmp",Gdiplus::ImageFormatBMP);

```

There's many image formats, and many different ways to do this. I'll probably migrate away from CImage at some future point...


---

