Date: Thu, 28 Mar 2024 12:39:40 +0000 (UTC) Message-ID: <220437638.7448.1711629580346@ip-10-0-0-233.us-west-2.compute.internal> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_7447_2141046464.1711629580342" ------=_Part_7447_2141046464.1711629580342 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
Bxdfs can help integrators converge more quickly by providing hi=
nts about the domain over which they need to be integrated (the full domain=
being the entire sphere). This is done by the bxdf implementing a RixBXEvaluateDomain
value. This value in=
forms the integrator about the domain on which RixBxdf::EvaluateSample()
and RixBxdf::EvaluateSamplesAtIndex()
would return n=
on-zero values (i.e. a non-zero material response).
Note that the bxdf is still able to generate discrete samples over the whole spherical domain (through&nbs=
p;RixBxdf::GenerateSample()
), =
independently of the hint returned. However, if the bxdf was generatin=
g non-discrete samples outside of the one returned by RixBxdf::GetEvaluateDomain()
), this would=
mean there is an inconsistency between RixBxdf::GenerateSample()
and RixBxdf::EvaluateSample()
or RixBxdf::EvaluateSamplesAtIndex()
, which is not goo=
d for correctness.
The various RixBXEvaluateDomain
enum values (as define=
d in RixBxdf.h
) are detailed below. The entire spherical domai=
n is split into the outside and the inside hemi=
spheres, defined with respect to the geometric normal of the surface (=
the geometric normal pointing toward the outside). Note that each value is a power of two, which means t=
hat the enum acts as a bit field and its values can (should) be OR-ed toget=
her.
k_RixBXEmptyDo=
main =3D 0
This indicates that either:
RixBxdf::EmitLocal()
)k_RixBXOuts=
ideReflect =3D 1
This indicates that the bxdf represents a surface that only reflects lig=
ht from the outside. That is: V
and L
&n=
bsp;lie in the outside hemisphere.
This is useful for closed opaque objects, whose interior will never be s= een.
k_RixBXOut=
sideTransmit =3D 2
This indicates that the bxdf represents a surface that allows light to f=
low from the outside toward the inside. That is:
Note that if used for a closed object, this would allow light to penetra= te inside the object, but not exit it. This would only make sense if the ca= mera lies inside the object.
k_RixBXInsid=
eReflect =3D 4
This indicates that the bxdf represents a surface that only reflects lig= ht from the inside. That is: V and L lie in the <= em>inside hemisphere.
k_RixBXInsi=
deTransmit =3D 8
This indicates that the bxdf represents a surface that allows light to f=
low from the inside toward the outside. That is: L lies in the inside hemisphere, while
V
lies in the outside hemisphere.
Note that if used for a closed object, this would allow light to exit th= e object, but not go through it. This would only make sense if a light is p= laced inside the object.
k_RixBXVolume =3D =
16
This indicates that the bxdf represents a volumetric scattering event. T= his is different from using all of the above, since in the volumetric case,= there is no surface cosine term to consider during integration.
RixBXEvaluateDomain
also defines some (composed) values cor=
responding to the most common cases.
k_RixBXReflect =3D (k_RixBXInsideReflect | k_RixBX=
OutsideReflect)
This is useful for open surfaces with both the 'outside' and 'inside' be= ing reflective.
k_RixBXTransmit =3D (k_RixBXInsideTransmit | k_=
RixBXOutsideTransmit)
This is useful for open surfaces with both the 'outside' and 'inside' be= ing transmissive. This is also useful for closed objects that allow light t= o pass through them (this may require additional indirect bounces)
k_RixBXBoth =3D (k_RixBXReflect | k_RixBXTransmit)
This is the most generic type of surface, allowing light to always be re= flected or transmitted independently of the domains.
k_RixBXOutside =3D (k_RixBXOutsideReflect | k_Ri=
xBXOutsideTransmit)
This describse surfaces that will only consider light coming from the ou= tside.
k_RixBXInside =3D (k_RixBXInsideReflect | k_RixBXIn=
sideTransmit)
This describes surfaces that will only consider light coming from the in= side.
Using only k_RixBXOutsideRefl=
ect
and k_RixBXInsideRefl=
ect
doesn't prevent the bxdf from being reciprocal.
However, if only one of the bits corresponding to k_RixOutsid=
eTransmit
or k_RixInsideTransmit
is set, this indi=
cates that the bxdf only allows the light to go through in a particular dir=
ection, and as such breaks the reciprocity principle. This may lead to non-=
intuive, non-plausible renders, and break bidirectional algorithms.
In particular, when a bxdf is used by bidirectional integrators, the mea=
ning for V
and L
for all calls to =
GenerateSample()
, EvaluateSample()
and =
EvaluateSamplesAtIndex()
may be flipped. For example, when gen=
erating photons, GenerateSample()
will be called with&nbs=
p;V
pointing toward the direction of the light subpat=
h. In this case, non-reciprocal bxdfs needs to make sure they acc=
ount for this when computing material response. This case can be detected b=
y checking the value of RixShadingContext::scTraits.lightPath. If
lightPath
is 1, then V
po=
ints towards the light subpath.
RixBXEvaluateDomain
First, note that using k_RixBXBoth
(or k_Ri=
xBXVolume
) is the best way to ensure your bxdf works properly, as a =
reference. When choosing a different evaluation domain (for evaluation effi=
ciency), you need to make sure the rendered image doesn't change =E2=80=93 =
if it does change, that could mean you are artificially restricting th=
e evaluation domain of your bxdf, and potentially introducing rendering art=
ifacts.
Most of the time, when dealing with closed and non-transmissive (i.e. tr=
anslucent) objects, you should be able to restrict the evaluation domain (u=
sing k_RixBXOutsideReflect
). This would allow the integra=
tor to skip processing light samples that lie behind the surface (on the ot=
her side of the closed object itself for example), reducing the number of b=
xdf evaluations required, as well as the number of transmission rays that n=
eed to be cast.
When dealing with transmissive (i.e. translucent) objects, and only expe=
ct translucent scattering to come from lights placed inside the objects, yo=
u may be able to use k_RixBXInsideTransmit
, without =
k_RixBXOutsideTransmit
.