@@ -744,44 +744,55 @@ namespace spartan
744744
745745 unordered_map<Renderer_Option, float >& Renderer::GetOptions ()
746746 {
747- // local scratchpad to avoid permanently overwriting m_options (master user settings)
747+ // local scratchpad
748748 static unordered_map<Renderer_Option, float > resolved_options;
749-
750- // start fresh every frame with the master settings
751749 resolved_options = m_options;
752750
753- // get camera
754751 if (!World::GetCamera () || !World::GetCamera ()->GetEntity ())
755752 return resolved_options;
756753
757754 Vector3 cam_pos = World::GetCamera ()->GetEntity ()->GetPosition ();
758- const float blend_radius = 5 .0f ; // dirty hardcoded blend distance
755+
756+ // how many meters deep you must be to reach 100% volume influence
757+ // 0.1f means "at 10cm depth, I am fully active"
758+ const float blend_depth = 0 .5f ;
759759
760- // iterate all entities
761760 const auto & entities = World::GetEntities ();
762761 for (const auto & entity : entities)
763762 {
764- // skip if no volume
765763 Volume* volume = entity->GetComponent <Volume>();
766- if (!volume)
767- continue ;
764+ if (!volume) continue ;
768765
769- // check distance
770- const math::BoundingBox& box = volume->GetBoundingBox ();
771- float dist = box.GetClosestPoint (cam_pos).Distance (cam_pos);
766+ // 1. transform local box to world space
767+ // (crucial: otherwise you compare world camera vs local box at 0,0,0)
768+ const math::BoundingBox& local_box = volume->GetBoundingBox ();
769+ const Matrix& transform = entity->GetMatrix ();
770+ math::BoundingBox world_box = local_box * transform; // or local_box.Transform(transform)
772771
773- // skip if too far
774- if (dist > blend_radius )
772+ // 2. fast early exit
773+ if (!world_box. Contains (cam_pos) )
775774 continue ;
776775
777- // calculate alpha (1.0 inside, 0.0 at radius)
778- float alpha = 1 .0f - clamp (dist / blend_radius, 0 .0f , 1 .0f );
776+ // 3. calculate depth (distance to nearest face inside)
777+ // since we are inside, all these deltas are positive
778+ Vector3 d_min = cam_pos - world_box.GetMin ();
779+ Vector3 d_max = world_box.GetMax () - cam_pos;
780+
781+ // the "depth" is the smallest distance to any of the 6 faces
782+ float depth = min (d_min.x , d_max.x );
783+ depth = min (depth, min (d_min.y , d_max.y ));
784+ depth = min (depth, min (d_min.z , d_max.z ));
785+
786+ // 4. calculate alpha
787+ // depth 0.0 (surface) -> alpha 0.0
788+ // depth 0.5 (inside) -> alpha 1.0
789+ float alpha = clamp (depth / blend_depth, 0 .0f , 1 .0f );
779790
780- // blend overrides onto the scratchpad
791+ // 5. blend
781792 for (const auto & [option, vol_value] : volume->GetOptions ())
782793 {
783794 float & current_val = resolved_options[option];
784- current_val = lerp (current_val, vol_value, alpha);
795+ current_val = lerp (current_val, vol_value, alpha);
785796 }
786797 }
787798
0 commit comments