Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-07 10:11:39

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file celeritas/optical/surface/SmearRoughnessSampler.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include "corecel/math/ArrayUtils.hh"
0010 #include "corecel/random/distribution/IsotropicDistribution.hh"
0011 #include "corecel/random/distribution/PowerDistribution.hh"
0012 #include "geocel/Types.hh"
0013 
0014 namespace celeritas
0015 {
0016 namespace optical
0017 {
0018 //---------------------------------------------------------------------------//
0019 /*!
0020  * Sample a facet normal from a smear roughness model.
0021  *
0022  * The smear roughness model is parameterized by a single roughness value
0023  * in [0,1] where:
0024  *
0025  * - 0 roughness is polished (specular spike reflection)
0026  * - 1 roughness is rough (diffuse reflection)
0027  *
0028  * A smear direction is uniformly sampled within a sphere of radius 1, which is
0029  * then scaled by the roughness parameter and added to the global normal.
0030  */
0031 class SmearRoughnessSampler
0032 {
0033   public:
0034     // Construct from roughness and global normal
0035     inline CELER_FUNCTION SmearRoughnessSampler(Real3 const& normal,
0036                                                 real_type roughness);
0037 
0038     // Sample facet normal
0039     template<class Engine>
0040     inline CELER_FUNCTION Real3 operator()(Engine& rng) const;
0041 
0042   private:
0043     Real3 normal_;
0044     real_type roughness_;
0045     PowerDistribution<> sample_r_{2};
0046 };
0047 
0048 //---------------------------------------------------------------------------//
0049 // INLINE DEFINITIONS
0050 //---------------------------------------------------------------------------//
0051 /*!
0052  * Construct from roughness and global normal.
0053  */
0054 CELER_FUNCTION SmearRoughnessSampler::SmearRoughnessSampler(
0055     Real3 const& normal, real_type roughness)
0056     : normal_(normal), roughness_(roughness)
0057 {
0058     CELER_EXPECT(0 <= roughness_ && roughness_ <= 1);
0059     CELER_EXPECT(is_soft_unit_vector(normal_));
0060 }
0061 
0062 //---------------------------------------------------------------------------//
0063 /*!
0064  * Sample a facet normal via the smear roughness model.
0065  */
0066 template<class Engine>
0067 CELER_FUNCTION Real3 SmearRoughnessSampler::operator()(Engine& rng) const
0068 {
0069     real_type r = sample_r_(rng);
0070     Real3 local_normal = normal_;
0071     axpy(r * roughness_, IsotropicDistribution{}(rng), &local_normal);
0072 
0073     return make_unit_vector(local_normal);
0074 }
0075 
0076 //---------------------------------------------------------------------------//
0077 }  // namespace optical
0078 }  // namespace celeritas