Fix color rendering when using MapperQuad

This fix lerps the scalar field values at points of ray intersection,
ensuring rendering of quads pick the correct lerped color instead of
using the same color for the entire quad.
This commit is contained in:
Manish Mathai 2022-03-10 15:05:16 -08:00
parent d15da1c12a
commit 27825778e8
5 changed files with 96 additions and 20 deletions

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:17b032ff1f2cf019b8cc39e5db2f823a8f5c1ceac5bf05ee7c2dd82d2097d19c
size 19720
oid sha256:fa95a5a698a8ec1b80884a31f7a1f339a302e4a32adfb1c33b3e8e713fb4f243
size 67902

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1252a96282b1713a57769d2b7d8bdf3d16f38ad2e02dfeb454e770d42679dedf
size 19398
oid sha256:29aef56293f9909f1f0abd1e3fa598dd4853d04d2a66277959398743337eebd8
size 81058

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:da36149e1a86d54d2f051a48f06b1091306f3a5e972727287e18511371b125a7
size 19659
oid sha256:2b4b6ba29eb3b2a66d9084d6c82523636eaf01472e397ae9d3222f6e4309795d
size 81353

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c27cead7392df7591bb03418e0a6e97e2966577f630a43aad08e38dd93006543
size 26903
oid sha256:471bca272393b52d6000b3446c4d96c7ad4cd6f57affab8023c4ff67a2b720be
size 72052

@ -353,7 +353,7 @@ public:
}; //class CalculateNormals
template <typename Precision>
class GetScalar : public vtkm::worklet::WorkletMapField
class GetLerpedScalar : public vtkm::worklet::WorkletMapField
{
private:
Precision MinScalar;
@ -361,8 +361,11 @@ private:
bool Normalize;
public:
using ControlSignature = void(FieldIn, FieldIn, FieldIn, FieldOut, WholeArrayIn, WholeArrayIn);
using ExecutionSignature = void(_1, _2, _3, _4, _5, _6);
VTKM_CONT
GetScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
GetLerpedScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
: MinScalar(minScalar)
{
Normalize = true;
@ -379,8 +382,66 @@ public:
this->InvDeltaScalar = 1.f / (maxScalar - MinScalar);
}
}
typedef void ControlSignature(FieldIn, FieldOut, WholeArrayIn, WholeArrayIn);
typedef void ExecutionSignature(_1, _2, _3, _4);
template <typename ScalarPortalType, typename IndicesPortalType>
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
const Precision& u,
const Precision& v,
Precision& scalar,
const ScalarPortalType& scalars,
const IndicesPortalType& indicesPortal) const
{
if (hitIndex < 0)
return;
vtkm::Vec<vtkm::Id, 5> pointId = indicesPortal.Get(hitIndex);
Precision aScalar = Precision(scalars.Get(pointId[1]));
Precision bScalar = Precision(scalars.Get(pointId[2]));
Precision cScalar = Precision(scalars.Get(pointId[3]));
Precision dScalar = Precision(scalars.Get(pointId[4]));
Precision uP = 1.0f - u;
Precision vP = 1.0f - v;
scalar = uP * vP * aScalar + u * vP * bScalar + u * v * cScalar + uP * v * dScalar;
if (Normalize)
{
scalar = (scalar - MinScalar) * this->InvDeltaScalar;
}
}
}; //class GetLerpedScalar
template <typename Precision>
class GetNodalScalar : public vtkm::worklet::WorkletMapField
{
private:
Precision MinScalar;
Precision InvDeltaScalar;
bool Normalize;
public:
using ControlSignature = void(FieldIn, FieldOut, WholeArrayIn, WholeArrayIn);
using ExecutionSignature = void(_1, _2, _3, _4);
VTKM_CONT
GetNodalScalar(const vtkm::Float32& minScalar, const vtkm::Float32& maxScalar)
: MinScalar(minScalar)
{
Normalize = true;
if (minScalar >= maxScalar)
{
// support the scalar renderer
Normalize = false;
this->InvDeltaScalar = Precision(0.f);
}
else
{
//Make sure the we don't divide by zero on
//something like an iso-surface
this->InvDeltaScalar = 1.f / (maxScalar - MinScalar);
}
}
template <typename ScalarPortalType, typename IndicesPortalType>
VTKM_EXEC void operator()(const vtkm::Id& hitIndex,
Precision& scalar,
@ -390,7 +451,6 @@ public:
if (hitIndex < 0)
return;
//TODO: this should be interpolated?
vtkm::Vec<vtkm::Id, 5> pointId = indicesPortal.Get(hitIndex);
scalar = Precision(scalars.Get(pointId[0]));
@ -399,7 +459,7 @@ public:
scalar = (scalar - MinScalar) * this->InvDeltaScalar;
}
}
}; //class GetScalar
}; //class GetNodalScalar
} // namespace detail
@ -450,12 +510,28 @@ void QuadIntersector::IntersectionDataImp(Ray<Precision>& rays,
vtkm::worklet::DispatcherMapField<detail::CalculateNormals>(detail::CalculateNormals())
.Invoke(rays.HitIdx, rays.Dir, rays.NormalX, rays.NormalY, rays.NormalZ, CoordsHandle, QuadIds);
vtkm::worklet::DispatcherMapField<detail::GetScalar<Precision>>(
detail::GetScalar<Precision>(vtkm::Float32(scalarRange.Min), vtkm::Float32(scalarRange.Max)))
.Invoke(rays.HitIdx,
rays.Scalar,
vtkm::rendering::raytracing::GetScalarFieldArray(scalarField),
QuadIds);
if (scalarField.IsFieldPoint())
{
vtkm::worklet::DispatcherMapField<detail::GetLerpedScalar<Precision>>(
detail::GetLerpedScalar<Precision>(vtkm::Float32(scalarRange.Min),
vtkm::Float32(scalarRange.Max)))
.Invoke(rays.HitIdx,
rays.U,
rays.V,
rays.Scalar,
vtkm::rendering::raytracing::GetScalarFieldArray(scalarField),
QuadIds);
}
else
{
vtkm::worklet::DispatcherMapField<detail::GetNodalScalar<Precision>>(
detail::GetNodalScalar<Precision>(vtkm::Float32(scalarRange.Min),
vtkm::Float32(scalarRange.Max)))
.Invoke(rays.HitIdx,
rays.Scalar,
vtkm::rendering::raytracing::GetScalarFieldArray(scalarField),
QuadIds);
}
}
void QuadIntersector::IntersectionData(Ray<vtkm::Float32>& rays,