Render Images
Render images are special images which are renderings of scene through the Polyscope viewport. These are useful when using Polyscope to visualize renders from your own custom renderers, such as ray tracers, SDF-field implicit tracers, or neural field renderers.
Render images always show the image in fullscreen viewport. Additional, depth and transparency allow the image to be composited with other scene content, so that you can still see your usual Polyscope meshes and point clouds in the scene along with the outputs of your renderer.
Sample: A colored box and scalar torus, displayed as render images from a user’s custom implicit surface renderer.
Floating Quantities
Render images are floating quantities, which means they can be added to the scene at the root level, or added to any kind of structure.
It is most common to add render image quantities at the root level. However, it might still be useful to add render images to structures, to associate the rendering with a particular structure, e.g. as a separate rendering of each point cloud in the scene.
See the floating quantity introduction for more info.
Image Array Layout
Images are always passed as arrays of length width*height
, flattened such that the rows are stored contiguously. For multi-channel image data like colors or normals, this becomes a width*height
array of tuples, or a width*height x 3
matrix, etc. The ImageOrigin
enum controls the row layout order; most commonly the first element is the upper-left of the image.
Remember that Polyscope’s data adaptors allow many container types to be used as input. For instance, an RGB color image could be stored as a such as std::vector<std::array<float,3>>
, with .size() == width*height
, or an Eigen::MatrixXd
with dimensions width*height x 3
, etc.
Image Origin
When registering an image quantity, you also need to specify whether the image should be interpreted such that the first row is the “top” row of the image (ImageOrigin::UpperLeft
), or the first row is the “bottom” row of the image (ImageOrigin::LowerLeft
). This is a confusing issue, as there are many overlapping conventions of coordinate systems and buffer layouts for images.
Most of the time, ImageOrigin::UpperLeft
is the right choice.
Depth Render Image Quantity
A depth render image quantity takes a depth value per-pixel, and (optionally) a world-space normal per-pixel. The depth image will be rendered with surface shading using Polyscope’s materials.
Example:
size_t width = 1024; size_t height = 768;
std::vector<float> depthVals(width * height, 0.44); // placeholder data
std::vector<std::array<float, 3>> normalVals(width * height, std::array<float, 3>{0.44, 0.55, 0.66});
std::vector<std::array<float, 3>> normalValsEmpty;
polyscope::DepthRenderImageQuantity* im = polyscope::addDepthRenderImageQuantity(
"render im depth", width, height, depthVals, normalVals, polyscope::ImageOrigin::UpperLeft);
im->setEnabled(true);
// with no normals
polyscope::DepthRenderImageQuantity* imNoNormal = polyscope::addDepthRenderImageQuantity(
"render im depth no normal", width, height, depthVals, normalValsEmpty, polyscope::ImageOrigin::UpperLeft);
imNoNormal->setEnabled(true);
polyscope::show(3);
If normals are not given, they will be computed internally via screen-space derivatives.
This can be called at the root level, like polyscope::addDepthRenderImageQuantity()
, or on a structure, like cameraView->addDepthRenderImageQuantity()
.
DepthRenderImageQuantity* addDepthRenderImageQuantity(std::string name, size_t width, size_t height, const T1& depthData, const T2& normalData, ImageOrigin imageOrigin)
Add a depth render image.
width
andheight
are dimensions in pixelsdepthData
is a flattened array of depth scalars per pixel. Useinf
for any pixels which missed the scene. The type should be adaptable to afloat
scalar array. See the note above about image array layouts.normalData
is an optional flattened array of world-space normals per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts. If not given, pass an empty array.imageOrigin
is the row origin convention, see above
Depth values should be radial ray distance from the camera origin, not perpendicular distance from the image plane.
Color Render Image Quantity
A color render image quantity takes a depth value per-pixel, (optionally) a world-space normal per-pixel, and a color value per-pixel. The depth image will be rendered with surface shading using Polyscope’s materials, colored according to the given color.
Color vs. Raw Color Render Images
A color render image applies materials shading and lighting to the image, just like Polyscope usually does for meshes and other objects. A raw color render image does not do any additional shading, and simply displays the given colors directly onto the screen.
Example:
size_t width = 1024; size_t height = 768;
std::vector<float> depthVals(width * height, 0.44); // placeholder data
std::vector<std::array<float, 3>> normalVals(width * height, std::array<float, 3>{0.44, 0.55, 0.66});
std::vector<std::array<float, 3>> colorVals(width * height, std::array<float, 3>{0.44, 0.55, 0.66});
polyscope::ColorRenderImageQuantity* im = polyscope::addColorRenderImageQuantity(
"render im color", width, height, depthVals, normalVals, colorVals, polyscope::ImageOrigin::UpperLeft);
im->setEnabled(true);
polyscope::show(3);
If normals are not given, they will be computed internally via screen-space derivatives.
This can be called at the root level, like polyscope::addColorRenderImageQuantity()
, or on a structure, like cameraView->addColorRenderImageQuantity()
.
ColorRenderImageQuantity* addColorRenderImageQuantity(std::string name, size_t width, size_t height, const T1& depthData, const T2& normalData, const T3& colorData, ImageOrigin imageOrigin)
Add a depth render image, annotated with additional color values per-pixel.
width
andheight
are dimensions in pixelsdepthData
is a flattened array of depth scalars per pixel. Useinf
for any pixels which missed the scene. The type should be adaptable to afloat
scalar array . See the note above about image array layouts.normalData
is an optional flattened array of world-space normals per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts. If not given, pass an empty array.colorData
is a flattened array of colors per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts.imageOrigin
is the row origin convention, see above
Depth values should be radial ray distance from the camera origin, not perpendicular distance from the image plane.
RGB values are interpreted in the range [0,1]
.
Color Quantity Options
These options and behaviors are available for all types of color quantities on any structure.
Parameter | Meaning | Getter | Setter | Persistent? |
---|---|---|---|---|
enabled | is the quantity enabled? | bool isEnabled() |
setEnabled(bool newVal) |
yes |
(all setters return this
to support chaining. setEnabled() returns generic quantity, so chain it last)
Scalar Render Image Quantity
A scalar render image quantity takes a depth value per-pixel, (optionally) a world-space normal per-pixel, and a scalar value per-pixel. The depth image will be rendered with surface shading using Polyscope’s materials, with the scalar value shaded and colormapped as a scalar quantity.
Example:
size_t width = 1024; size_t height = 768;
std::vector<float> depthVals(width * height, 0.44); // placeholder data
std::vector<std::array<float, 3>> normalVals(width * height, std::array<float, 3>{0.44, 0.55, 0.66});
std::vector<float> scalarVals(width * height, 0.44);
polyscope::ScalarRenderImageQuantity* im = polyscope::addScalarRenderImageQuantity(
"render im scalar", width, height, depthVals, normalVals, scalarVals, polyscope::ImageOrigin::UpperLeft);
im->setEnabled(true);
polyscope::show(3);
If normals are not given, they will be computed internally via screen-space derivatives.
This can be called at the root level, like polyscope::addScalarRenderImageQuantity()
, or on a structure, like cameraView->addScalarRenderImageQuantity()
.
ScalarRenderImageQuantity* addScalarRenderImageQuantity(std::string name, size_t width, size_t height, const T1& depthData, const T2& normalData, const T3& scalarData, ImageOrigin imageOrigin, DataType type = DataType::STANDARD)
Add a depth render image, annotated with additional scalar values per-pixel.
width
andheight
are dimensions in pixelsdepthData
is a flattened array of depth scalars per pixel. Useinf
for any pixels which missed the scene. The type should be adaptable to afloat
scalar array. See the note above about image array layouts.normalData
is an optional flattened array of world-space normals per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts.colorData
is a flattened array of colors per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts.imageOrigin
is the row origin convention, see abovetype
is the scalar datatype as for other scalar quantities
Depth values should be radial ray distance from the camera origin, not perpendicular distance from the image plane.
Scalar Quantity Options
These options and behaviors are available for all types of scalar quantities on any structure.
Parameter | Meaning | Getter | Setter | Persistent? |
---|---|---|---|---|
enabled | is the quantity enabled? | bool isEnabled() |
setEnabled(bool newVal) |
yes |
color map | the color map to use | std::string getColorMap() |
setColorMap(std::string newMap) |
yes |
map range | the lower and upper limits used when mapping the data in to the color map | std::pair<double,double> getMapRange() |
setMapRange(std::pair<double,double>) and resetMapRange() |
no |
isolines enabled | are isolines shaded (default=false ) |
bool getIsolinesEnabled() |
setIsolinesEnabled(bool newVal) |
yes |
isoline width | width of isoline stripes, in data units | float getIsolineWidth() |
setIsolineWidth(float newVal) |
yes |
isoline darkness | darkness of isoline stripes (default=0.7 ) |
float getIsolineDarkness() |
setIsolineDarkness(float newVal) |
yes |
(all setters return this
to support chaining. setEnabled() returns generic quantity, so chain it last)
Raw Color Render Image Quantity
A raw color render image quantity takes a depth value per-pixel and a color value per-pixel. The colors will be directly displayed onscreen, with depth compositing into the scene.
Example:
size_t width = 1024; size_t height = 768;
std::vector<float> depthVals(width * height, 0.44); // placeholder data
std::vector<std::array<float, 3>> colorVals(width * height, std::array<float, 3>{0.44, 0.55, 0.66});
polyscope::RawColorRenderImageQuantity* im = polyscope::addRawColorRenderImageQuantity(
"render im raw color", width, height, depthVals, colorVals, polyscope::ImageOrigin::UpperLeft);
im->setEnabled(true);
polyscope::show(3);
Color vs. Raw Color Render Images
A color render image applies materials shading and lighting to the image, just like Polyscope usually does for meshes and other objects. A raw color render image does not do any additional shading, and simply displays the given colors directly onto the screen.
This can be called at the root level, like polyscope::addRawColorRenderImageQuantity()
, or on a structure, like cameraView->addRawColorRenderImageQuantity()
.
RawColorRenderImageQuantity* addRawColorRenderImageQuantity(std::string name, size_t width, size_t height, const T1& depthData, const T2& colorData, ImageOrigin imageOrigin)
Add a raw color render image described by pixel color and depth.
width
andheight
are dimensions in pixelsdepthData
is a flattened array of depth scalars per pixel. Useinf
for any pixels which missed the scene. The type should be adaptable to afloat
scalar array. See the note above about image array layouts.colorData
is a flattened array of colors per pixel. The type should be adaptable to a 3-vector array offloat
s. See the note above about image array layouts.imageOrigin
is the row origin convention, see above
Depth values should be radial ray distance from the camera origin, not perpendicular distance from the image plane.
RGB values are interpreted in the range [0,1]
.
Raw Color Alpha Render Image Quantity
Just like the above ColorRenderImageQuantity
, but with an additional alpha channel which gets alpha-composited onto the scene.
Example:
size_t width = 1024; size_t height = 768;
std::vector<float> depthVals(width * height, 0.44); // placeholder data
std::vector<std::array<float, 4>> colorAlphaVals(width * height, std::array<float, 4>{0.44, 0.55, 0.66, 0.77});
polyscope::RawColorAlphaRenderImageQuantity* im = polyscope::addRawColorAlphaRenderImageQuantity(
"render im raw color alpha", width, height, depthVals, colorAlphaVals, polyscope::ImageOrigin::UpperLeft);
im->setEnabled(true);
im->setIsPremultiplied(true);
polyscope::show(3);
RawColorAlphaRenderImageQuantity* addRawColorAlphaRenderImageQuantity(std::string name, size_t width, size_t height, const T1& depthData, const T2& colorData, ImageOrigin imageOrigin)
Add a raw color render image described by RGBA pixel color and depth.
width
andheight
are dimensions in pixelsdepthData
is a flattened array of depth scalars per pixel. Useinf
for any pixels which missed the scene. The type should be adaptable to afloat
scalar array. See the note above about image array layouts.colorData
is a flattened array of rgba colors per pixel. The type should be adaptable to a 4-vector array offloat
s. See the note above about image array layouts.imageOrigin
is the row origin convention, see above
Depth values should be radial ray distance from the camera origin, not perpendicular distance from the image plane.
RGBA values are interpreted in the range [0,1]
.
By default, alpha values are interpreted to be non-premultiplied. Use rawColorAlphaRenderImage->setIsPremultiplied(true);
to directly pass premultiplied alpha images.
Render Image Options
These options are common to all render images
Parameter | Meaning | Getter | Setter | Persistent? |
---|---|---|---|---|
transparency | the image transparency | float getTransparency() |
setTransparency(float val) |
yes |
material | what material to use | std::string getMaterial() |
setMaterial(std::string name) |
yes |
allow compositing | if true, multiple renders can composite with each other | bool getAllowFullscreenCompositing() |
setAllowFullscreenCompositing(bool val) |
yes |
Raw color render images ignore material-related settings.