RenderKit / ospray

An Open, Scalable, Portable, Ray Tracing Based Rendering Engine for High-Fidelity Visualization
http://ospray.org
Apache License 2.0
982 stars 178 forks source link

HDRI light example #523

Open 1vx-437312114 opened 2 years ago

1vx-437312114 commented 2 years ago

Hello,

i am trying to render a scene with an OSPRay hdri light using the actual OSPRay Version 2.9 with the C-API.

The hdri - image is loaded with the stb image loader which gives a pointer to a floating point array with the image data as a result.

I tried adding the hdri-light to the scene using the following code (which sadly does not work):

    // load texture image data from hdr file (radiance format)
    // texImageData is a pointer to an floating point array
    int textureWidth, textureHeight, nrChannels;
    float* texImageData = stbi_loadf("umhlanga_sunrise_4k.hdr", &textureWidth, &textureHeight, &nrChannels, 0);

    // create OSPRay data object
    OSPData texData = ospNewSharedData(texImageData, OSP_VEC3F, textureWidth, 0, textureHeight, 0);
    ospCommit(texData);
    ospRelease(texData);

    // create OSPRay texture object
    int format = OSP_TEXTURE_RGB32F;            // HDR ist 32-bit floating point
    int filter = OSP_TEXTURE_FILTER_BILINEAR;   // bilinear filtering

    OSPTexture texture = ospNewTexture("texture2d");
    ospSetParam(texture, "format", OSP_INT, &format);
    ospSetParam(texture, "filter", OSP_INT, &filter);
    ospSetParam(texture, "data", OSP_DATA, &texData);
    ospCommit(texture);
    ospRelease(texture);

    // create OSPRay hdri light and add it to the "world"
    OSPLight hdriLight = ospNewLight("hdri");
    ospSetParam(hdriLight, "map", OSP_TEXTURE, texture);
    ospCommit(hdriLight);
    ospSetObjectAsData(world, "light", OSP_LIGHT, hdriLight);
    ospRelease(hdriLight);

I checked that the texture image data is successfully loaded. But by trying to render the scene, my program simply exits returning -1 to the shell.

Using an OSPRay sun-sky-light or ambient light instead of the hdri light everything works fine and my scene is rendered beautifully.

What am i doing wrong here?

Thank you very much in advance.

Regards.

johguenther commented 2 years ago

There are two issues with above code:

1vx-437312114 commented 2 years ago

Thank you very much for your help! After applying your suggestions to my code everything works now perfectly and the rendered images come out beautifully!

The only thing i had to do in addition to the suggested changes was to manually change the exposure of the hdri - image by multiplying the floating point pixel values by the needed exposure value.

If the values of the hrdi texture are too small, the hrdi light is basically black resulting in no illumination at all. If the values are too high the hrdi light (and therefore background of the rendered image) is completely white giving an overexposure of the scene.

While it is not too much of an additional work to do this, it might be convenient to have an exposure texture parameter in the OSPRay api for hrdi textures.

By the way the hrdi texture light works just as well with non-hrdi images like png and jpg (the pixel values only have to be converted to floating point values by dividing the byte values by 256) with the advantage that no exposure has to be done to the pixel values. While the color accuracy of course is not as precise as with hrdi images, the rendered images are in general more than acceptable.

It might be nice to have a bit more detail in the OSPray documentation on how resource management is done in general (e.g. self managed vs. ospray managed resources, functions needed) because at the moment i find the documentation a bit lacking in this regard. And since there is not so much example / tutorial code included in the OSPRay-SDK and you can't find much on the web (blogs etc.) at the moment i find myself often a bit on the trial and error side.

Even the OSP_LOG_DEBUG level is a bit terse for debugging.

Other than that OSPray works really great and generates beautiful visualizations. Keep on the good work!

Regards.

johguenther commented 2 years ago

Thank you for your feedback.

The HDRI light needs an OSPTexture, which can be of format OSP_TEXTURE_RGBA8 or OSP_TEXTURE_SRGBA, e.g. an 8bit png can directly work without conversion to float. Using LDR images works well if the image is mostly uniform (a neutral room or a overcast sky), but not anymore with bright spots (like a sun), because that needed energy for illumination is clamped and not present in the image.

The HDRI light has a float intensity parameter like all other light sources to help adjusting the brightness. If the illumination is fine but the background is overexposed there are several options to remedy: