-
Notifications
You must be signed in to change notification settings - Fork 40
Volume selection and edge detection possible improvement #201
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -55,22 +55,20 @@ VISRTX_DEVICE const SpatialFieldGPUData &getSpatialFieldData( | |||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| VISRTX_DEVICE void volumeSamplerInit( | ||||||||||||||||
| VolumeSamplingState *samplerState, | ||||||||||||||||
| const SpatialFieldGPUData &field) | ||||||||||||||||
| VolumeSamplingState *samplerState, const SpatialFieldGPUData &field) | ||||||||||||||||
| { | ||||||||||||||||
| optixDirectCall<void>( | ||||||||||||||||
| uint32_t(field.samplerCallableIndex) + static_cast<uint32_t>(SpatialFieldSamplerEntryPoints::Init), | ||||||||||||||||
| optixDirectCall<void>(uint32_t(field.samplerCallableIndex) | ||||||||||||||||
| + static_cast<uint32_t>(SpatialFieldSamplerEntryPoints::Init), | ||||||||||||||||
| samplerState, | ||||||||||||||||
| &field); | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| VISRTX_DEVICE float volumeSamplerSample( | ||||||||||||||||
| const VolumeSamplingState *samplerState, | ||||||||||||||||
| VISRTX_DEVICE float volumeSamplerSample(const VolumeSamplingState *samplerState, | ||||||||||||||||
| const SpatialFieldGPUData &field, | ||||||||||||||||
| const vec3 &position) | ||||||||||||||||
| { | ||||||||||||||||
| return optixDirectCall<float>( | ||||||||||||||||
| uint32_t(field.samplerCallableIndex) + static_cast<uint32_t>(SpatialFieldSamplerEntryPoints::Sample), | ||||||||||||||||
| return optixDirectCall<float>(uint32_t(field.samplerCallableIndex) | ||||||||||||||||
| + static_cast<uint32_t>(SpatialFieldSamplerEntryPoints::Sample), | ||||||||||||||||
| samplerState, | ||||||||||||||||
| &position); | ||||||||||||||||
| } | ||||||||||||||||
|
|
@@ -95,12 +93,30 @@ VISRTX_DEVICE vec4 classifySample(const VolumeGPUData &v, float s) | |||||||||||||||
| return retval; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| VISRTX_DEVICE uint32_t colorToMaterialID( | ||||||||||||||||
| const vec3 &color, uint32_t numBins = 16) | ||||||||||||||||
| { | ||||||||||||||||
| // Quantize RGB color to create a material ID | ||||||||||||||||
| // Each channel is divided into numBins levels | ||||||||||||||||
| const uint32_t r = | ||||||||||||||||
| static_cast<uint32_t>(glm::clamp(color.x, 0.f, 1.f) * (numBins - 1)); | ||||||||||||||||
| const uint32_t g = | ||||||||||||||||
| static_cast<uint32_t>(glm::clamp(color.y, 0.f, 1.f) * (numBins - 1)); | ||||||||||||||||
| const uint32_t b = | ||||||||||||||||
| static_cast<uint32_t>(glm::clamp(color.z, 0.f, 1.f) * (numBins - 1)); | ||||||||||||||||
|
|
||||||||||||||||
| // Pack into a single ID: each channel gets log2(numBins) bits | ||||||||||||||||
| return (r * numBins * numBins) + (g * numBins) + b; | ||||||||||||||||
| } | ||||||||||||||||
|
|
||||||||||||||||
| VISRTX_DEVICE void _rayMarchVolume(ScreenSample &ss, | ||||||||||||||||
| const VolumeHit &hit, | ||||||||||||||||
| box1 interval, | ||||||||||||||||
| vec3 *color, | ||||||||||||||||
| float &opacity, | ||||||||||||||||
| float invSamplingRate) | ||||||||||||||||
| float invSamplingRate, | ||||||||||||||||
| float *outDepth = nullptr, | ||||||||||||||||
| uint32_t *outMaterialID = nullptr) | ||||||||||||||||
| { | ||||||||||||||||
| const auto &volume = *hit.volume; | ||||||||||||||||
| ///////////////////////////////////////////////////////////////////////////// | ||||||||||||||||
|
|
@@ -125,6 +141,9 @@ VISRTX_DEVICE void _rayMarchVolume(ScreenSample &ss, | |||||||||||||||
| curand_uniform(&ss.rs) * (interval.upper - interval.lower); | ||||||||||||||||
|
|
||||||||||||||||
| constexpr float OPACITY_THRESHOLD = 0.99f; | ||||||||||||||||
|
||||||||||||||||
| constexpr float OPACITY_THRESHOLD = 0.99f; | |
| constexpr float OPACITY_THRESHOLD = 0.99f; | |
| // Note: This depth threshold (1% opacity) is intentionally higher than the | |
| // minimum segment opacity used elsewhere for objID assignment (0.1%). For | |
| // depth/material reporting we only consider the volume "hit" once it has a | |
| // clearly visible contribution along the ray, to avoid noisy, near-transparent | |
| // samples influencing the first-hit depth and material ID. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feels like we are trying to reimplement part of the existing logic of detail::rayMarchVolume. I feel most of the changes could be done there instead.
Copilot
AI
Jan 19, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition checks volumeID != ~0u but volumeID is initialized to ~0 (which defaults to int type) on line 342. This comparison should use ~0 instead of ~0u for type consistency, or volumeID should be explicitly initialized as ~0u.
| if (!objIDSet && segmentOpacity > MIN_SEGMENT_OPACITY && volumeID != ~0u) { | |
| if (!objIDSet && segmentOpacity > MIN_SEGMENT_OPACITY && volumeID != ~0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That one does not seem to be unused. It would need to be dropped and the related code.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -63,8 +63,7 @@ void computeEdgesImage( | |
| return; | ||
| } | ||
|
|
||
| // Check if any neighbor has a different object ID (including | ||
| // background) | ||
| // Check if any neighbor has a different object ID | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was the previous comment wrong? The related code doesn't look it changed. |
||
| bool isEdge = false; | ||
|
|
||
| for (int dy = -1; dy <= 1 && !isEdge; ++dy) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,7 +110,7 @@ struct Viewport : public Window | |
| bool m_showAxes{true}; | ||
| float m_depthVisualMinimum{0.f}; | ||
| float m_depthVisualMaximum{1.f}; | ||
| float m_edgeThreshold{0.5f}; | ||
| float m_edgeThreshold{0.5f}; // 0.0 = 1px radius, 1.0 = 5px radius | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does not seem to be used elsewhere in this PR. Experiments left-over? |
||
| bool m_edgeInvert{false}; | ||
|
|
||
| float m_fov{40.f}; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The colorToMaterialID function lacks documentation explaining its purpose, parameters, and return value. Given its role in material identification for edge detection, a docstring would clarify why RGB quantization is used and how the numBins parameter affects the result.