Support Forum G3D Web Page |
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 . 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 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< UniversalSurfel > | create () |
static shared_ptr< UniversalSurfel > | createEmissive (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 |
More... | |
const Material * | material |
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 Surface * | surface |
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... | |
A Surfel for a surface patch described by a UniversalMaterial.
Computes the Surfel::ExpressiveParameters::boost solely from the lambertianReflectivity coefficient.
|
inherited |
Impulses in the BSDF.
This contains three inline-allocated elements to support reflection and refraction without heap allocation.
|
inline |
|
inline |
float G3D::UniversalSurfel::blinnPhongExponent | ( | ) | const |
An approximate glossy exponent in the Blinn-Phong BSDF for this BSDF.
|
inlinestatic |
|
static |
Primarily useful for constructing skybox surfels.
|
inlinestaticprotectedinherited |
Like std::make_shared, but works for protected constructors.
Call as createShared<myclass>.
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.
|
overridevirtual |
Evaluates the finite portion of .
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 .
It omits the impulses because they would force the return value to infinity.
wi | Unit vector pointing backwards along the direction from which light came ("to the light source") |
wi | Unit vector pointing out in the direction that light will go ("to the eye") |
Implements G3D::Surfel.
|
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)
= finiteScatteringDensity(PathDirection::EYE_TO_SOURCE, wo, wi)
=
|
overridevirtual |
Given w, returns all wo directions that yield impulses in 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.
|
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.
|
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.
|
inlinestatic |
|
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.
|
overridevirtual |
Optimized to avoid numerical integration for lambertian-only and perfectly black surfaces.
Reimplemented from G3D::Surfel.
|
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.
|
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:
lambertianColorPerSteradian | Has units of per-steradian. Lambertian lobe term from the BSDF * cosine angle of incidence. |
glossyWeight | Unitless. This is the PDF adjustment for suboptimal importance sampling. Use it to modulate the glossy ray's contribution as incoming light. |
glossyColor | Unitless. 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"
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().
|
overrideprotectedvirtual |
Called by the default implementation of scatter.
Samples a directional PDF
Samples from some distribution on the sphere. This is optimal if proportional to , where is the finite portion of the BSDF (no impulses) but can be anything that is nonzero where $f$ is nonzero.
Returns w_i = and pdfValue =
Reimplemented from G3D::Surfel.
|
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 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.
scatter(PathDirection::SOURCE_TO_EYE, wi, ..., wo)
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:
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 . For that integral, choose samples and weight as described below, and then multiply each by the corresponding and sum.
This is single-importance sampling based on scattering. it gives good convergence when 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:
Uniformly random hemisphere implementation:
Uniformly random sphere functions:
There are of course a limitless number of ways of implementing the scattering.
Returns true if the weight is nonzero.
|
virtualinherited |
Transform this to world space using the provided xform.
|
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.
float G3D::UniversalSurfel::coverage |
`‘alpha’'
Radiance3 G3D::UniversalSurfel::emission |
|
inherited |
Ratio of complex refractive indices for each side of the interface.
eta ( ) is the real part, which determines the angle of refraction. 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.
|
inherited |
0x1 = light flag
The other 7 bits are reserved for future use.
Referenced by G3D::Surfel::isLight().
|
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.
Color3 G3D::UniversalSurfel::glossyReflectionCoefficient |
F0, the Fresnel reflection coefficient at normal incidence.
Referenced by nonZeroFiniteScattering().
|
staticinherited |
|
staticinherited |
bool G3D::UniversalSurfel::isTransmissive |
|
inherited |
Ratio of complex refractive indices for each side of the interface.
eta ( ) is the real part, which determines the angle of refraction. 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.
|
inherited |
Ratio of complex refractive indices for each side of the interface.
eta ( ) is the real part, which determines the angle of refraction. 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.
Color3 G3D::UniversalSurfel::lambertianReflectivity |
Referenced by nonZeroFiniteScattering().
|
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.
|
inherited |
Point in world space at the geometric center of this surfel.
|
inherited |
Point in world space at the geometric center of this surfel in the previously rendered frame of animation.
Useful for computing velocity.
|
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.
|
inherited |
Primary tangent vector for use in shading anisotropic surfaces.
This is the tangent space after normal mapping has been applied.
|
inherited |
Secondary shading tangent.
float G3D::UniversalSurfel::smoothness |
Zero = very rough, 1.0 = perfectly smooth (mirror).
Equivalent the the parameter of the Generalized Trowbridge-Reitz microfacet BSDF (GTR/GGX).
Transmission is always perfectly smooth
Referenced by nonZeroFiniteScattering().
|
inherited |
|
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.
Vector3 G3D::UniversalSurfel::tangentSpaceNormal |
Color3 G3D::UniversalSurfel::transmissionCoefficient |