Support Forum       G3D Web Page     
Public Types | Public Member Functions | Static Public Member Functions | Public Attributes | Static Public Attributes | Protected Member Functions | Static Protected Member Functions | List of all members
G3D::UniversalSurfel Class Reference


A Surfel for a surface patch described by a UniversalMaterial. More...

Inherits G3D::Surfel.

Public Types

typedef SmallArray< Impulse, 2 > ImpulseArray
 Impulses in the BSDF. More...
 

Public Member Functions

 UniversalSurfel ()
 
 UniversalSurfel (const Tri &tri, float u, float v, int triIndex, const CPUVertexArray &vertexArray, bool backside, float du=0, float dv=0)
 
float blinnPhongExponent () const
 An approximate glossy exponent in the Blinn-Phong BSDF for this BSDF. More...
 
virtual Radiance3 emittedRadiance (const Vector3 &wo) const override
 Returns the radiance emitted by this surface in direction wo. More...
 
virtual Color3 finiteScatteringDensity (const Vector3 &wi, const Vector3 &wo, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const override
 Evaluates the finite portion of $f_X(\hat{\omega_\mathrm{i}}, \hat{\omega_\mathrm{o}})$. More...
 
virtual Color3 finiteScatteringDensity (PathDirection pathDirection, const Vector3 &wFrom, const Vector3 &wTo, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const
 Provided as a convenience helper method for implementers of scatter(). More...
 
virtual void getImpulses (PathDirection direction, const Vector3 &wi, ImpulseArray &impulseArray, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const override
 
Given w, returns all wo directions that yield impulses in $f_X(\hat{\omega}, \hat{\omega_\mathrm{o}})$ for PathDirection::SOURCE_TO_EYE paths, and vice versa for PathDirection::EYE_TO_SOURCE paths. More...
 
bool isLight () const
 
True if this surfel was produced by a surface that came from a Light, and thus may have emissive terms that are already accounted for by direct illumination. More...
 
virtual bool nonZeroFiniteScattering () const override
 True if this surfel's finiteScatteringDensity function ever returns a non-zero value. More...
 
virtual Color3 probabilityOfScattering (PathDirection pathDirection, const Vector3 &w, Random &rng, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const override
 Optimized to avoid numerical integration for lambertian-only and perfectly black surfaces. More...
 
virtual Color3 reflectivity (Random &rng, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const override
 Approximate reflectivity of this surface, primarily used for ambient terms. More...
 
virtual void reflectSeparate (PathDirection pathDirection, const Vector3 &w_before, Random &rng, Vector3 &w_lambertian, Color3 &lambertianColorPerSteradian, Vector3 &w_glossy, Color3 &glossyColor, Color3 &glossyWeight) const
 Useful for computing separate wide- and narrow-lobe scattering. More...
 
void sample (const Tri &tri, float u, float v, int triIndex, const CPUVertexArray &vertexArray, bool backside, const class UniversalMaterial *universalMaterial, float du=0, float dv=0, bool twoSided=true)
 
virtual bool scatter (PathDirection pathDirection, const Vector3 &w_before, bool russianRoulette, Random &rng, Color3 &weight, Vector3 &w_after, bool &impulseScattered=ignoreBool, float &probabilityHint=ignore, const ExpressiveParameters &expressiveParameters=ExpressiveParameters()) const
 
Computes the direction of a scattered photon
and a weight that compensates for the way that the the sampling process is performed. More...
 
virtual void transformToWorldSpace (const CoordinateFrame &xform)
 Transform this to world space using the provided xform. More...
 
virtual bool transmissive () const override
 Must return true if a ray is ever scattered to the opposite side of the surface with respect to the Surfel::shadingNormal. More...
 

Static Public Member Functions

static shared_ptr< UniversalSurfelcreate ()
 
static shared_ptr< UniversalSurfelcreateEmissive (const Radiance3 emission, const Point3 &position, const Vector3 &normal)
 Primarily useful for constructing skybox surfels. More...
 
static void operator delete (void *p)
 
static void * operator new (size_t size)
 Allocates with System::malloc to avoid the performance overhead of creating lots of small heap objects using the standard library %malloc. More...
 

Public Attributes

float coverage
 `‘alpha’' More...
 
Radiance3 emission
 
float etaRatio = 1.0f
 Ratio of complex refractive indices for each side of the interface. More...
 
uint8 flags = 0
 0x1 = light flag More...
 
Vector3 geometricNormal
 The normal to the true underlying geometry of the patch that was sampled (e.g., the face normal). More...
 
Color3 glossyReflectionCoefficient
 F0, the Fresnel reflection coefficient at normal incidence. More...
 
bool isTransmissive
 
Color3 kappaNeg
 Ratio of complex refractive indices for each side of the interface.
More...
 
Color3 kappaPos
 Ratio of complex refractive indices for each side of the interface.
More...
 
Color3 lambertianReflectivity
 $ \rho_\mathrm{L} $ More...
 
const Materialmaterial
 The material that generated this Surfel. More...
 
Point3 position
 Point in world space at the geometric center of this surfel. More...
 
Point3 prevPosition
 Point in world space at the geometric center of this surfel in the previously rendered frame of animation. More...
 
Vector3 shadingNormal
 The normal to the patch for shading purposes, i.e., after normal mapping. More...
 
Vector3 shadingTangent1
 Primary tangent vector for use in shading anisotropic surfaces. More...
 
Vector3 shadingTangent2
 Secondary shading tangent. More...
 
float smoothness
 Zero = very rough, 1.0 = perfectly smooth (mirror). More...
 
struct G3D::Surfel::Source source
 
const Surfacesurface
 The surface that generated this Surfel. More...
 
Vector3 tangentSpaceNormal
 
Color3 transmissionCoefficient
 

Static Public Attributes

static float ignore
 
static bool ignoreBool
 

Protected Member Functions

virtual void sampleFiniteDirectionPDF (PathDirection pathDirection, const Vector3 &w_o, Random &rng, const ExpressiveParameters &expressiveParameters, Vector3 &w_i, float &pdfValue) const override
 Called by the default implementation of scatter. More...
 

Static Protected Member Functions

template<class T , class ... ArgTypes>
static shared_ptr< T > createShared (ArgTypes &&... args)
 Like std::make_shared, but works for protected constructors. More...
 

Detailed Description


A Surfel for a surface patch described by a UniversalMaterial.

Computes the Surfel::ExpressiveParameters::boost solely from the lambertianReflectivity coefficient.

See also
UniversalMaterial

Member Typedef Documentation

◆ ImpulseArray

Impulses in the BSDF.

This contains three inline-allocated elements to support reflection and refraction without heap allocation.

Constructor & Destructor Documentation

◆ UniversalSurfel() [1/2]

G3D::UniversalSurfel::UniversalSurfel ( )
inline

◆ UniversalSurfel() [2/2]

G3D::UniversalSurfel::UniversalSurfel ( const Tri tri,
float  u,
float  v,
int  triIndex,
const CPUVertexArray vertexArray,
bool  backside,
float  du = 0,
float  dv = 0 
)
inline

Member Function Documentation

◆ blinnPhongExponent()

float G3D::UniversalSurfel::blinnPhongExponent ( ) const

An approximate glossy exponent in the Blinn-Phong BSDF for this BSDF.

◆ create()

static shared_ptr<UniversalSurfel> G3D::UniversalSurfel::create ( )
inlinestatic

◆ createEmissive()

static shared_ptr<UniversalSurfel> G3D::UniversalSurfel::createEmissive ( const Radiance3  emission,
const Point3 position,
const Vector3 normal 
)
static

Primarily useful for constructing skybox surfels.

◆ createShared()

template<class T , class ... ArgTypes>
static shared_ptr<T> G3D::ReferenceCountedObject::createShared ( ArgTypes &&...  args)
inlinestaticprotectedinherited

Like std::make_shared, but works for protected constructors.

Call as createShared<myclass>.

◆ emittedRadiance()

virtual Radiance3 G3D::UniversalSurfel::emittedRadiance ( const Vector3 wo) const
overridevirtual

Returns the radiance emitted by this surface in direction wo.

This models an emission function.

Defaults to zero. N.B. A "Lambertian emitter", which is often considered the ideal area light source, would return a constant value on the side

Note that this interface is intentionally insufficient for representing a point light, which requires a biradiance function.

If this function returns a non-zero value, then emissive() must return true.

Reimplemented from G3D::Surfel.

◆ finiteScatteringDensity() [1/2]

virtual Color3 G3D::UniversalSurfel::finiteScatteringDensity ( const Vector3 wi,
const Vector3 wo,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
overridevirtual

Evaluates the finite portion of $f_X(\hat{\omega_\mathrm{i}}, \hat{\omega_\mathrm{o}})$.

This is the straightforward abstraction of the BSDF, i.e., "forward BSDF evaluation". It is useful for direct illumination and in the gather kernel of a ray tracer. Note that this does not scale the result by $|\hat{n} \cdot \hat{\omega}_\mathrm{i}|$.

It omits the impulses because they would force the return value to infinity.

Parameters
wiUnit vector pointing backwards along the direction from which light came ("to the light source")
wiUnit vector pointing out in the direction that light will go ("to the eye")

Implements G3D::Surfel.

◆ finiteScatteringDensity() [2/2]

virtual Color3 G3D::Surfel::finiteScatteringDensity ( PathDirection  pathDirection,
const Vector3 wFrom,
const Vector3 wTo,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
virtualinherited

Provided as a convenience helper method for implementers of scatter().

Allows programmatically swapping the directions (which only matters for refraction if the BSDF is reciprocal).

  • finiteScatteringDensity(PathDirection::SOURCE_TO_EYE, wi, wo) = $f_X(\hat{\omega_\mathrm{i}}, \hat{\omega_\mathrm{o}})$
  • finiteScatteringDensity(PathDirection::EYE_TO_SOURCE, wo, wi)= $f_X(\hat{\omega_\mathrm{o}}, \hat{\omega_\mathrm{i}})$

◆ getImpulses()

virtual void G3D::UniversalSurfel::getImpulses ( PathDirection  direction,
const Vector3 w,
ImpulseArray impulseArray,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
overridevirtual


Given w, returns all wo directions that yield impulses in $f_X(\hat{\omega}, \hat{\omega_\mathrm{o}})$ for PathDirection::SOURCE_TO_EYE paths, and vice versa for PathDirection::EYE_TO_SOURCE paths.

Overwrites the impulseArray.

For example, getImpulses(PathDirection::SOURCE_TO_EYE, wi, impulseArray) returns the impulses for scattering a photon emitted from a light.

getImpulses(PathDirection::EYE_TO_SOURCE, wo, impulseArray) returns the impulses for scattering a backwards-traced ray from the ey.

Implements G3D::Surfel.

◆ isLight()

bool G3D::Surfel::isLight ( ) const
inlineinherited


True if this surfel was produced by a surface that came from a Light, and thus may have emissive terms that are already accounted for by direct illumination.

◆ nonZeroFiniteScattering()

virtual bool G3D::UniversalSurfel::nonZeroFiniteScattering ( ) const
inlineoverridevirtual

True if this surfel's finiteScatteringDensity function ever returns a non-zero value.

(May also be true even if it does only ever return zero, however).

Reimplemented from G3D::Surfel.

◆ operator delete()

static void G3D::UniversalSurfel::operator delete ( void *  p)
inlinestatic

◆ operator new()

static void* G3D::UniversalSurfel::operator new ( size_t  size)
inlinestatic

Allocates with System::malloc to avoid the performance overhead of creating lots of small heap objects using the standard library %malloc.

This is actually not used by make_shared, which is the common case.

◆ probabilityOfScattering()

virtual Color3 G3D::UniversalSurfel::probabilityOfScattering ( PathDirection  pathDirection,
const Vector3 w,
Random rng,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
overridevirtual

Optimized to avoid numerical integration for lambertian-only and perfectly black surfaces.

Reimplemented from G3D::Surfel.

◆ reflectivity()

virtual Color3 G3D::UniversalSurfel::reflectivity ( Random rng,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
overridevirtual

Approximate reflectivity of this surface, primarily used for ambient terms.

The default implementation invokes probabilityOfScattering many times and is not very efficient.

Reimplemented from G3D::Surfel.

◆ reflectSeparate()

virtual void G3D::UniversalSurfel::reflectSeparate ( PathDirection  pathDirection,
const Vector3 w_before,
Random rng,
Vector3 w_lambertian,
Color3 lambertianColorPerSteradian,
Vector3 w_glossy,
Color3 glossyColor,
Color3 glossyWeight 
) const
inlinevirtual

Useful for computing separate wide- and narrow-lobe scattering.

Scatters one lambertian (cosine distributed about the shading normal) ray and one glossy (importance sampled by cos * glossy term) ray.

Example of use:

surfel->scatterSeparate(PathDirection::EYE_TO_LIGHT, w_in, rng, w_L, lambertianColor, w_G, glossyColor, glossyWeight);
Irradiance3 E_inL = rayTrace(surfel.position, w_L);
Radiance3 L_inG = rayTrace(surfel.position, w_G) * glossyWeight;
Radiance3 L_indirectOut = E_L * lambertianColor + L_G * glossyColor;
Parameters
lambertianColorPerSteradianHas units of per-steradian. Lambertian lobe term from the BSDF * cosine angle of incidence.
glossyWeightUnitless. This is the PDF adjustment for suboptimal importance sampling. Use it to modulate the glossy ray's contribution as incoming light.
glossyColorUnitless. Glossy lobe term from the BSDF * cosine angle of incidence.

The current implementation does not handle transmission, so it is named "reflectSeparate" instead of "scatterSeparate"

◆ sample()

void G3D::UniversalSurfel::sample ( const Tri tri,
float  u,
float  v,
int  triIndex,
const CPUVertexArray vertexArray,
bool  backside,
const class UniversalMaterial universalMaterial,
float  du = 0,
float  dv = 0,
bool  twoSided = true 
)

Referenced by UniversalSurfel().

◆ sampleFiniteDirectionPDF()

virtual void G3D::UniversalSurfel::sampleFiniteDirectionPDF ( PathDirection  pathDirection,
const Vector3 w_o,
Random rng,
const ExpressiveParameters expressiveParameters,
Vector3 w_i,
float &  pdfValue 
) const
overrideprotectedvirtual

Called by the default implementation of scatter.

Samples a directional PDF

Samples $ \hat{\omega}_i $ from some distribution $ p(\hat{\omega}_i) $ on the sphere. This is optimal if proportional to $ f^*(\hat{\omega}_i, \hat{\omega}_o) \cdot | \hat{\omega}_u \cdot \hat{n}| $, where $ f^* $ is the finite portion of the BSDF (no impulses) but can be anything that is nonzero where $f$ is nonzero.

Returns w_i = $ \hat{\omega}_i $ and pdfValue = $ p(\hat{\omega}_i) $

Reimplemented from G3D::Surfel.

◆ scatter()

virtual bool G3D::Surfel::scatter ( PathDirection  pathDirection,
const Vector3 w_before,
bool  russianRoulette,
Random rng,
Color3 weight,
Vector3 w_after,
bool &  impulseScattered = ignoreBool,
float &  probabilityHint = ignore,
const ExpressiveParameters expressiveParameters = ExpressiveParameters() 
) const
virtualinherited


Computes the direction of a scattered photon
and a weight that compensates for the way that the the sampling process is performed.

For use in Monte Carlo integration of the rendering equation, this computes the cosine-weighted BSDF $ f(\hat{\omega}_i, \hat{\omega}_o) | \hat{\omega}_i \cdot \hat{n}| $ term.

The weight is needed to allow efficient computation of scattering from BSDFs that have no computationally efficient method for exact analytic sampling. The caller should scale the radiance or power transported by the weight.

  • For forward rays (e.g., photon tracing), call: scatter(PathDirection::SOURCE_TO_EYE, wi, ..., wo)
  • For backwards rays (e.g., path tracing), call: scatter(PathDirection::EYE_TO_SOURCE, wo, ..., wi)

Let h(w) be the PDF that the implementation actually samples with respect to. Let g(w) = f(w_before, w_after) |w_after.dot(n)|, the function that scatter samples. [Note: g(w) is not a PDF; just the terms from the integrand of the rendering equation]

The function produces two outputs:

w = sample with chosen with respect to pdf h(w)
weight = g(w) / h(w)

Note that the weight might be zero even if the photon scatters, for example, a perfectly "red" photon striking a perfectly "green" surface would have a weight of zero.

The probabilityHint is for use by photon mappers to decrease convergence time. If the a priori probability density of scattering in this direction was infinity, it returns 1.0. If the density was 0.0, it returns 0. For finite densities it scales between them.

If russianRoulette is true, then with probability proportional to the initial weight paths will be terminated. Nonterminated paths have weights increased proportionally to maintain the mean. (This is useful for photon mapping and pure path tracing.) The weight will be zero if the path terminates.

Note that because they are driven by the finite portion of the BSDF, weights returned must be non-negative and finite, but are not bounded. However, an efficient importance-sampling implementation will return weights close to 1.0.

The default implementation relies on getIncoming() and inefficient cosine (vs. importance) sampling against evaluateFiniteScatteringDensity(). Thus although it will work for any evaluateFiniteScatteringDensity() implementation, it is desirable to optimize the implementation of scatter() in subclasses where possible.

Consider this in the context of Monte Carlo integration of $ \int_{\mathbf{S}^2} L(X, \hat{\omega}) f(\hat{\omega}, \hat{\omega}') |\hat{\omega} \cdot \hat{n}| d\hat{\omega} $. For that integral, choose $ k $ samples and weight as described below, and then multiply each by the corresponding $ L(X, \hat{\omega}) / k $ and sum.

This is single-importance sampling based on scattering. it gives good convergence when $ L(X, \hat{\omega}) $ is uniform, and is often the best we can do and is at least correct otherwise.

Here are several different ways of implementing this method for a common example of a perfectly lambertian (f() = 1 / pif()) BRDF.

A noise-minimizing implementation:

// Direction:
// g(w) / h(w)
// weight = ( abs(w.dot(n)) * f(w) ) / (abs(w.dot(n)) * 2 / (2*pif()))
// weight = ( abs(w.dot(n)) / pif() ) / (abs(w.dot(n)) * 2 / (2*pif()))
weight = Color3::one();

Uniformly random hemisphere implementation:

// Direction:
// g(w) / h(w)
// weight = abs(w.dot(n)) * f(w)) / (1.0 / (2.0f * pif()));
// weight = abs(w.dot(n)) * (Color3::one() / pif()) / (1.0 / (2.0f * pif()));
weight = abs(w.dot(n)) * 2.0f;

Uniformly random sphere functions:

// Direction:
// g(w) / h(w)
// weight = abs(w.dot(n)) * f(w) / (1.0 / (4.0f * pif()));
// weight = abs(w.dot(n)) * (Color3::one() / pif()) * max(0, sign(w.dot(n))) / (1.0 / (4.0f * pif()));
weight = abs(w.dot(n)) * max(0, sign(w.dot(n))) * 4.0f;

There are of course a limitless number of ways of implementing the scattering.

Returns true if the weight is nonzero.

◆ transformToWorldSpace()

virtual void G3D::Surfel::transformToWorldSpace ( const CoordinateFrame xform)
virtualinherited

Transform this to world space using the provided xform.

◆ transmissive()

virtual bool G3D::UniversalSurfel::transmissive ( ) const
overridevirtual

Must return true if a ray is ever scattered to the opposite side of the surface with respect to the Surfel::shadingNormal.

This may conservatively always return true (which is the default implementation). Setting this correctly doubles the efficiency of the default implementation of other methods.

There is no equivalent reflective() method because all physical transmissive surfaces are also reflective, so it would rarely be false in practice.

Reimplemented from G3D::Surfel.

Member Data Documentation

◆ coverage

float G3D::UniversalSurfel::coverage

`‘alpha’'

◆ emission

Radiance3 G3D::UniversalSurfel::emission

◆ etaRatio

float G3D::Surfel::etaRatio = 1.0f
inherited

Ratio of complex refractive indices for each side of the interface.

eta ( $\eta$) is the real part, which determines the angle of refraction. kappa ( $\kappa$) is the imaginary part, which determines absorption within the medium.

For a non-transmissive medium, eta should be NaN() and kappa should be Color3::inf().

The "Pos" versions are for the material on the side of the surface that the geometricNormal faces towards. The "Neg" versions are for the material on the side opposite the geometricNormal.

We ignore the frequency-variation in eta, since three color samples isn't enough to produce meaningful chromatic dispersion anyway.

◆ flags

uint8 G3D::Surfel::flags = 0
inherited

0x1 = light flag

The other 7 bits are reserved for future use.

Referenced by G3D::Surfel::isLight().

◆ geometricNormal

Vector3 G3D::Surfel::geometricNormal
inherited

The normal to the true underlying geometry of the patch that was sampled (e.g., the face normal).

This is often useful for ray bumping.

Always a unit vector.

◆ glossyReflectionCoefficient

Color3 G3D::UniversalSurfel::glossyReflectionCoefficient

F0, the Fresnel reflection coefficient at normal incidence.

Referenced by nonZeroFiniteScattering().

◆ ignore

float G3D::Surfel::ignore
staticinherited

◆ ignoreBool

bool G3D::Surfel::ignoreBool
staticinherited

◆ isTransmissive

bool G3D::UniversalSurfel::isTransmissive

◆ kappaNeg

Color3 G3D::Surfel::kappaNeg
inherited

Ratio of complex refractive indices for each side of the interface.

eta ( $\eta$) is the real part, which determines the angle of refraction. kappa ( $\kappa$) is the imaginary part, which determines absorption within the medium.

For a non-transmissive medium, eta should be NaN() and kappa should be Color3::inf().

The "Pos" versions are for the material on the side of the surface that the geometricNormal faces towards. The "Neg" versions are for the material on the side opposite the geometricNormal.

We ignore the frequency-variation in eta, since three color samples isn't enough to produce meaningful chromatic dispersion anyway.

◆ kappaPos

Color3 G3D::Surfel::kappaPos
inherited

Ratio of complex refractive indices for each side of the interface.

eta ( $\eta$) is the real part, which determines the angle of refraction. kappa ( $\kappa$) is the imaginary part, which determines absorption within the medium.

For a non-transmissive medium, eta should be NaN() and kappa should be Color3::inf().

The "Pos" versions are for the material on the side of the surface that the geometricNormal faces towards. The "Neg" versions are for the material on the side opposite the geometricNormal.

We ignore the frequency-variation in eta, since three color samples isn't enough to produce meaningful chromatic dispersion anyway.

◆ lambertianReflectivity

Color3 G3D::UniversalSurfel::lambertianReflectivity

$ \rho_\mathrm{L} $

Referenced by nonZeroFiniteScattering().

◆ material

const Material* G3D::Surfel::material
inherited

The material that generated this Surfel.

May be nullptr. This is a raw pointer because incrementing a shared_ptr is expensive during material sampling.

◆ position

Point3 G3D::Surfel::position
inherited

Point in world space at the geometric center of this surfel.

◆ prevPosition

Point3 G3D::Surfel::prevPosition
inherited

Point in world space at the geometric center of this surfel in the previously rendered frame of animation.

Useful for computing velocity.

◆ shadingNormal

Vector3 G3D::Surfel::shadingNormal
inherited

The normal to the patch for shading purposes, i.e., after normal mapping.

e.g., the interpolated vertex normal or normal-mapped normal.

Always a unit vector.

◆ shadingTangent1

Vector3 G3D::Surfel::shadingTangent1
inherited

Primary tangent vector for use in shading anisotropic surfaces.

This is the tangent space after normal mapping has been applied.

◆ shadingTangent2

Vector3 G3D::Surfel::shadingTangent2
inherited

Secondary shading tangent.

See also
shadingTangent1

◆ smoothness

float G3D::UniversalSurfel::smoothness

Zero = very rough, 1.0 = perfectly smooth (mirror).

Equivalent the the $1 - \alpha$ parameter of the Generalized Trowbridge-Reitz microfacet BSDF (GTR/GGX).

Transmission is always perfectly smooth

See also
blinnPhongExponent

Referenced by nonZeroFiniteScattering().

◆ source

struct G3D::Surfel::Source G3D::Surfel::source
inherited

◆ surface

const Surface* G3D::Surfel::surface
inherited

The surface that generated this Surfel.

May be nullptr. This is a raw pointer because incrementing a shared_ptr is expensive during material sampling.

◆ tangentSpaceNormal

Vector3 G3D::UniversalSurfel::tangentSpaceNormal

◆ transmissionCoefficient

Color3 G3D::UniversalSurfel::transmissionCoefficient

documentation generated on Wed Nov 24 2021 08:02:01 using doxygen 1.8.15