Hi Vlado,
Thanks for that. The method seems to work correctly, though I still get almost identical artifacts. I can only deduce that I was wrong in my conclusion that mapToScreen was the only culprit. I now find it likely that DefaultVrayShadeInstance::getBasePt returning a single precision Vector is also to blame. This makes sense as the coordinates I'm testing with are in a range close to the accuracy limit of float.
I apologize for my misguided conclusion. If you ever get a chance to revise getBasePt please let me know.
For reference, below is my updated method
Thanks for that. The method seems to work correctly, though I still get almost identical artifacts. I can only deduce that I was wrong in my conclusion that mapToScreen was the only culprit. I now find it likely that DefaultVrayShadeInstance::getBasePt returning a single precision Vector is also to blame. This makes sense as the coordinates I'm testing with are in a range close to the accuracy limit of float.
I apologize for my misguided conclusion. If you ever get a chance to revise getBasePt please let me know.
For reference, below is my updated method
Code:
DefaultVRayShadeInstance *si = dynamic_cast<DefaultVRayShadeInstance*>GET_INTERFACE(rc.rayresult.si, EXT_DEFAULT_SHADE_INSTANCE); if (si) { // Get the world-coordinate point at the start of the motion blur interval Vector offsetPt = si->getBasePt(rc, (which == timeMoment_frameEnd) ? DefaultVRayShadeInstance::baseTime_frameEnd : DefaultVRayShadeInstance::baseTime_frameStart); // Project the point onto the camera at the start of the motion blur interval const VRaySequenceData &sdata = rc.vray->getSequenceData(); double time = (which == timeMoment_frameEnd) ? 1.0 : 0.0; TracePoint offsetPtCam = sdata.cameraImageSampler->interpolateTimePointInverse(TracePoint(offsetPt), time); VR::Vector2 offset_p_img, this_p_img; if (sdata.cameraRaySampler->canDoDOF() & VR::vrayCameraFlags_canDoFrustrum) { Vector2 screenPt; VRayCamera3* cam3 = static_cast<VRayCamera3*>(sdata.cameraRaySampler); if (!cam3->mapTracePointToScreen(offsetPtCam, offset_p_img, time) || !cam3->mapTracePointToScreen(rc.rayresult.getPoint(), this_p_img, 0.5)) { return Vector(0.0F); } } else { if (!sdata.cameraRaySampler->mapToScreen(offsetPtCam, offset_p_img, time) || !sdata.cameraRaySampler->mapToScreen(rc.rayresult.getPoint(), this_p_img, 0.5)) { return Vector(0.0F); } } const VRayFrameData &fdata = rc.vray->getFrameData(); TracePoint origCamPos = fdata.camToWorld.offs; TracePoint offsetCamPos = sdata.cameraImageSampler->interpolateTimePoint(origCamPos, time); const double thisDepth = rc.rayresult.wpointCoeff; const double offsetDepth = (offsetCamPos - offsetPt).length(); double depthDelta = thisDepth - offsetDepth; return Vector( (double)offset_p_img.x - (double)this_p_img.x, (double)offset_p_img.y - (double)this_p_img.y, depthDelta); } return Vector(0.0F);
Comment