fix rendering depths and divide by zero

This commit is contained in:
mclarsen 2021-02-23 14:36:58 -08:00
parent ee6aaee181
commit cac09110d8
10 changed files with 47 additions and 14 deletions

@ -286,7 +286,7 @@ void Camera::ResetToBounds(const vtkm::Bounds& dataBounds,
vtkm::Float32 diagonalLength = vtkm::Magnitude(totalExtent);
this->SetPosition(center + directionOfProjection * diagonalLength * 1.0f);
this->SetFieldOfView(60.0f);
this->SetClippingRange(0.1f * diagonalLength, diagonalLength * 10.0f);
this->SetClippingRange(0.1f * diagonalLength, diagonalLength * 5.0f);
// Reset for 2D camera
this->SetViewRange2D(db);

@ -27,11 +27,13 @@ namespace internal
class SurfaceConverter : public vtkm::worklet::WorkletMapField
{
vtkm::Matrix<vtkm::Float32, 4, 4> ViewProjMat;
bool Is3d;
public:
VTKM_CONT
SurfaceConverter(const vtkm::Matrix<vtkm::Float32, 4, 4> viewProjMat)
SurfaceConverter(const vtkm::Matrix<vtkm::Float32, 4, 4> viewProjMat, bool is3d)
: ViewProjMat(viewProjMat)
, Is3d(is3d)
{
}
@ -51,7 +53,18 @@ public:
ColorBufferPortalType& colorBuffer,
const vtkm::Id& index) const
{
vtkm::Vec<Precision, 3> intersection = origin + inDepth * dir;
vtkm::Vec<Precision, 3> intersection;
// For reasons I can't explain atm, the view direction
// is different for for 2d and 3d so that it matches the
// gl depth buffer values for annotations
if (Is3d)
{
intersection = origin + inDepth * dir;
}
else
{
intersection = origin + inDepth * (-dir);
}
vtkm::Vec4f_32 point;
point[0] = static_cast<vtkm::Float32>(intersection[0]);
point[1] = static_cast<vtkm::Float32>(intersection[1]);
@ -105,7 +118,8 @@ VTKM_CONT void WriteToCanvas(const vtkm::rendering::raytracing::Ray<Precision>&
vtkm::MatrixMultiply(camera.CreateProjectionMatrix(canvas->GetWidth(), canvas->GetHeight()),
camera.CreateViewMatrix());
vtkm::worklet::DispatcherMapField<SurfaceConverter>(SurfaceConverter(viewProjMat))
bool is3d = camera.GetMode() == vtkm::rendering::Camera::MODE_3D;
vtkm::worklet::DispatcherMapField<SurfaceConverter>(SurfaceConverter(viewProjMat, is3d))
.Invoke(rays.PixelIdx,
colors,
rays.Distance,

@ -55,6 +55,11 @@ void LineRenderer::RenderLine(const vtkm::Vec3f_64& point0,
vtkm::Id dx = vtkm::Abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
vtkm::Id dy = -vtkm::Abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
vtkm::Id err = dx + dy, err2 = 0;
const vtkm::Id xStart = x0;
const vtkm::Id yStart = y0;
const vtkm::Float32 pdist = vtkm::Sqrt(vtkm::Float32(dx * dx) + vtkm::Float32(dy * dy));
auto colorPortal =
vtkm::rendering::Canvas::ColorBufferType(Canvas->GetColorBuffer()).WritePortal();
auto depthPortal =
@ -63,9 +68,19 @@ void LineRenderer::RenderLine(const vtkm::Vec3f_64& point0,
while (x0 >= 0 && x0 < Canvas->GetWidth() && y0 >= 0 && y0 < Canvas->GetHeight())
{
vtkm::Float32 t = (dx == 0) ? 1.0f : (static_cast<vtkm::Float32>(x0) - p0[0]) / (p1[0] - p0[0]);
vtkm::Float32 deltaX = static_cast<vtkm::Float32>(x0 - xStart);
vtkm::Float32 deltaY = static_cast<vtkm::Float32>(y0 - yStart);
// Depth is wrong, but its far less wrong that it used to be.
// These depth values are in screen space, which have been
// potentially tranformed by a perspective correction.
// To interpolated the depth correctly, there must be a perspective correction.
// I haven't looked, but the wireframmer probably suffers from this too.
// Additionally, this should not happen on the CPU. Annotations take
// far longer than the the geometry.
vtkm::Float32 t = pdist == 0.f ? 1.0 : vtkm::Sqrt(deltaX * deltaX + deltaY * deltaY) / pdist;
t = vtkm::Min(1.f, vtkm::Max(0.f, t));
vtkm::Float32 z = vtkm::Lerp(z0, z1, t);
vtkm::Id index = y0 * Canvas->GetWidth() + x0;
vtkm::Vec4f_32 currentColor = colorPortal.Get(index);
vtkm::Float32 currentZ = depthPortal.Get(index);
@ -85,6 +100,7 @@ void LineRenderer::RenderLine(const vtkm::Vec3f_64& point0,
writeColor[2] = currentColor[2] + colorC[2] * alpha;
writeColor[3] = 1.f * alpha + currentColor[3]; // we are always drawing opaque lines
// keep the current z. Line z interpolation is not accurate
// Matt: this is correct. Interpolation is wrong
depth = currentZ;
}

@ -379,7 +379,7 @@ public:
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar > maxScalar)
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;

@ -366,7 +366,7 @@ public:
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar > maxScalar)
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;

@ -28,7 +28,7 @@ void RayOperations::MapCanvasToRays(Ray<vtkm::Float32>& rays,
(void)valid; // this can be a false negative for really tiny spatial domains.
vtkm::worklet::DispatcherMapField<detail::RayMapCanvas>(
detail::RayMapCanvas(inverse, width, height, camera.GetPosition()))
.Invoke(rays.PixelIdx, rays.MaxDistance, canvas.GetDepthBuffer());
.Invoke(rays.PixelIdx, rays.MaxDistance, rays.Origin, canvas.GetDepthBuffer());
}
}
}

@ -70,12 +70,13 @@ public:
DoubleInvWidth = 2.f / static_cast<vtkm::Float32>(width);
}
using ControlSignature = void(FieldIn, FieldInOut, WholeArrayIn);
using ExecutionSignature = void(_1, _2, _3);
using ControlSignature = void(FieldIn, FieldInOut, FieldIn, WholeArrayIn);
using ExecutionSignature = void(_1, _2, _3, _4);
template <typename Precision, typename DepthPortalType>
VTKM_EXEC void operator()(const vtkm::Id& pixelId,
Precision& maxDistance,
const Vec<Precision, 3>& origin,
const DepthPortalType& depths) const
{
vtkm::Vec4f_32 position;
@ -94,7 +95,8 @@ public:
p[0] = position[0] / position[3];
p[1] = position[1] / position[3];
p[2] = position[2] / position[3];
p = p - Origin;
p = p - origin;
maxDistance = vtkm::Magnitude(p);
}

@ -277,6 +277,7 @@ void RayTracer::RenderOnDevice(Ray<Precision>& rays)
logger->AddLogData("shapes", NumberOfShapes);
logger->AddLogData("num_rays", rays.NumRays);
size_t numShapes = Intersectors.size();
if (NumberOfShapes > 0)
{

@ -257,7 +257,7 @@ public:
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar > maxScalar)
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;

@ -251,7 +251,7 @@ public:
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar > maxScalar)
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;
@ -315,7 +315,7 @@ public:
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar > maxScalar)
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;