Rendering Discrepancy: PixelFilter Impact on Object Positioning
Shijou87 opened this issue · comments
Hello,
I've observed that the scivis renderer doesn't accurately position the image; there's a slight pixel shift in both the x and y coordinates. Upon investigation, I've identified an issue with the default pixel filter employed by the renderer, specifically OSP_PIXELFILTER_GAUSS. This leads to image misalignment when transitioning from OSP_PIXELFILTER_POINT. The problem is resolved when using OSP_PIXELFILTER_POINT, ensuring the image displays at the correct location.
In the provided example, I rendered a basic plane using the scivis renderer. The first render in blue utilized OSP_PIXELFILTER_POINT, while the second in red omitted OSP_PIXELFILTER_POINT (employing OSP_PIXELFILTER_GAUSS), showcasing the pixel shift correction.
Generally, I expect that the location of the rendered object should remain unaltered by the filtering process. Do you agree ?
Below is a code snippet that you can use to replicate the problem:
void planeRendering(
unsigned int width, unsigned int height,
const char* filename,
float cameraHeight
) {
OSPGeometry mesh = ospNewGeometry("mesh");
std::vector<float> vertices = {
0, 0, 0,
0, (float) height, 0,
(float) width, (float) height, 0,
(float) width, 0, 0
};
OSPData verticesData = ospNewSharedData1D(vertices.data(), OSP_VEC3F, vertices.size()/3);
ospCommit(verticesData);
ospSetObject(mesh, "vertex.position", verticesData);
std::vector<unsigned int> vertexIndices = { 0, 1, 2, 3 };
OSPData vertexIndicesData = ospNewSharedData1D(vertexIndices.data(), OSP_VEC4UI, vertexIndices.size()/4);
ospCommit(vertexIndicesData);
ospSetObject(mesh, "index", vertexIndicesData);
std::vector<float> normals = {
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
};
std::vector<float> colors = {
1, 0, 0,
1, 0, 0,
1, 0, 0,
1, 0, 0
};
OSPData normalsData = ospNewSharedData1D(normals.data(), OSP_VEC3F, normals.size()/3);
ospCommit(normalsData);
OSPData colorData = ospNewSharedData1D(colors.data(), OSP_VEC3F, colors.size()/3);
ospCommit(colorData);
ospSetObject(mesh, "vertex.normal", normalsData);
ospSetObject(mesh, "color", colorData);
ospCommit(mesh);
OSPGroup group = ospNewGroup();
OSPInstance instance = ospNewInstance(group);
OSPGeometricModel geometricModel = ospNewGeometricModel(mesh);
ospCommit(geometricModel);
std::vector<OSPGeometricModel> planes = {geometricModel};
OSPData instanceData = ospNewSharedData1D(planes.data(), OSP_GEOMETRIC_MODEL, planes.size());
ospCommit(instanceData);
ospSetObject(group, "geometry", instanceData);
ospCommit(group);
ospCommit(instance);
OSPCamera camera = ospNewCamera("orthographic");
std::array<float, 3> cameraPos = {(float) width/2, (float) height/2, -1};
std::array<float, 3> camDir = {0, 0, 1};
std::array<float, 3> camUp = {0, 1, 0};
ospSetParam(camera, "position", OSP_VEC3F, cameraPos.data());
ospSetParam(camera, "direction", OSP_VEC3F, camDir.data());
ospSetParam(camera, "up", OSP_VEC3F, camUp.data());
ospSetFloat(camera, "aspect", width / height);
ospSetFloat(camera, "height", cameraHeight);
ospCommit(camera);
OSPLight ambient = ospNewLight("ambient");
ospSetVec3f(ambient, "color",1.f,1.f,1.f);
ospCommit(ambient);
OSPWorld world = ospNewWorld();
OSPData instances = ospNewSharedData1D(&instance, OSP_INSTANCE, 1);
ospCommit(instances);
ospSetObject(world, "instance", instances);
OSPData lights = ospNewSharedData1D(&ambient, OSP_LIGHT, 1);
ospSetObject(world, "light", lights);
ospCommit(world);
OSPRenderer renderer = ospNewRenderer("scivis");
// comment this line to test OSP_PIXELFILTER_GAUSS
ospSetInt(renderer,"pixelFilter",OSP_PIXELFILTER_POINT);
ospCommit(renderer);
OSPFrameBuffer framebuffer = ospNewFrameBuffer(width,
height,
OSP_FB_RGBA32F,
OSP_FB_COLOR | OSP_FB_ALBEDO | OSP_FB_NORMAL | OSP_FB_ACCUM | OSP_FB_VARIANCE);
OSPFuture future = ospRenderFrame(framebuffer, renderer, camera, world);
ospWait(future, OSP_FRAME_FINISHED);
ospRelease(future);
const float* rgbaf = reinterpret_cast<const float*>(ospMapFrameBuffer(framebuffer, OSP_FB_COLOR));
writePPM(filename, {width,height}, rgbaf);
}
Thanks for reporting and for the reproducer!
If you let multiple frames accumulate (or use pixelSamples
>1) then the shift will vanish (and with OSP_PIXELFILTER_GAUSS
the edges will be slightly blurred). But I agree that the first sample/frame looks odd. We'll look into implementing a better initial behavior.