Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
imjiangjun
pbrt-v4
提交
251754af
P
pbrt-v4
项目概览
imjiangjun
/
pbrt-v4
12 个月 前同步成功
通知
7
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
pbrt-v4
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
251754af
编写于
10月 07, 2020
作者:
M
Matt Pharr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update from book source. No meaningful changes to functionality.
上级
262d4ceb
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
154 addition
and
161 deletion
+154
-161
src/pbrt/base/bssrdf.h
src/pbrt/base/bssrdf.h
+1
-1
src/pbrt/base/light.h
src/pbrt/base/light.h
+6
-4
src/pbrt/interaction.h
src/pbrt/interaction.h
+3
-0
src/pbrt/lights.cpp
src/pbrt/lights.cpp
+96
-117
src/pbrt/lights.h
src/pbrt/lights.h
+39
-30
src/pbrt/media.h
src/pbrt/media.h
+9
-9
未找到文件。
src/pbrt/base/bssrdf.h
浏览文件 @
251754af
...
...
@@ -24,7 +24,7 @@ class TabulatedBSSRDF;
class
BSSRDFHandle
:
public
TaggedPointer
<
TabulatedBSSRDF
>
{
public:
// BSSRDF
Handle Public
Interface
// BSSRDF Interface
using
TaggedPointer
::
TaggedPointer
;
PBRT_CPU_GPU
inline
SampledSpectrum
S
(
const
Point3f
&
p
,
const
Vector3f
&
wi
);
...
...
src/pbrt/base/light.h
浏览文件 @
251754af
...
...
@@ -75,11 +75,9 @@ class LightHandle : public TaggedPointer< // Light Source Types
std
::
string
ToString
()
const
;
PBRT_CPU_GPU
inline
SampledSpectrum
L
(
const
Point3f
&
p
,
const
Normal3f
&
n
,
const
Point2f
&
uv
,
const
Vector3f
&
w
,
// AreaLights only
PBRT_CPU_GPU
inline
SampledSpectrum
L
(
Point3f
p
,
Normal3f
n
,
Point2f
uv
,
Vector3f
w
,
const
SampledWavelengths
&
lambda
)
const
;
PBRT_CPU_GPU
void
PDF_Le
(
const
Interaction
&
intr
,
Vector3f
&
w
,
Float
*
pdfPos
,
Float
*
pdfDir
)
const
;
// InfiniteAreaLights only
PBRT_CPU_GPU
inline
SampledSpectrum
Le
(
const
Ray
&
ray
,
...
...
@@ -96,6 +94,10 @@ class LightHandle : public TaggedPointer< // Light Source Types
// Note shouldn't be called for area lights..
PBRT_CPU_GPU
void
PDF_Le
(
const
Ray
&
ray
,
Float
*
pdfPos
,
Float
*
pdfDir
)
const
;
// AreaLights only
PBRT_CPU_GPU
void
PDF_Le
(
const
Interaction
&
intr
,
Vector3f
&
w
,
Float
*
pdfPos
,
Float
*
pdfDir
)
const
;
};
}
// namespace pbrt
...
...
src/pbrt/interaction.h
浏览文件 @
251754af
...
...
@@ -70,6 +70,9 @@ class Interaction {
Interaction
(
const
Point3f
&
p
,
Float
time
,
MediumHandle
medium
)
:
pi
(
p
),
time
(
time
),
medium
(
medium
)
{}
PBRT_CPU_GPU
Interaction
(
const
Point3f
&
p
,
const
MediumInterface
*
mediumInterface
)
:
pi
(
p
),
mediumInterface
(
mediumInterface
)
{}
PBRT_CPU_GPU
Interaction
(
const
Point3f
&
p
,
Float
time
,
const
MediumInterface
*
mediumInterface
)
:
pi
(
p
),
time
(
time
),
mediumInterface
(
mediumInterface
)
{}
PBRT_CPU_GPU
...
...
src/pbrt/lights.cpp
浏览文件 @
251754af
...
...
@@ -200,8 +200,8 @@ DistantLight *DistantLight::Create(const Transform &renderFromLight,
STAT_MEMORY_COUNTER
(
"Memory/Light image and distributions"
,
imageBytes
);
// ProjectionLight Method Definitions
ProjectionLight
::
ProjectionLight
(
const
Transform
&
renderFromLight
,
const
MediumInterface
&
mediumInterface
,
Image
im
,
ProjectionLight
::
ProjectionLight
(
Transform
renderFromLight
,
MediumInterface
mediumInterface
,
Image
im
,
const
RGBColorSpace
*
imageColorSpace
,
Float
lscale
,
Float
fov
,
Float
phi_v
,
Allocator
alloc
)
:
LightBase
(
LightType
::
DeltaPosition
,
renderFromLight
,
mediumInterface
),
...
...
@@ -209,26 +209,20 @@ ProjectionLight::ProjectionLight(const Transform &renderFromLight,
imageColorSpace
(
imageColorSpace
),
scale
(
lscale
),
distrib
(
alloc
)
{
// Initialize ProjectionLight projection matrix
// _ProjectionLight_ constructor implementation
// Initialize _ProjectionLight_ projection matrix
Float
aspect
=
Float
(
image
.
Resolution
().
x
)
/
Float
(
image
.
Resolution
().
y
);
if
(
aspect
>
1
)
screenBounds
=
Bounds2f
(
Point2f
(
-
aspect
,
-
1
),
Point2f
(
aspect
,
1
));
else
screenBounds
=
Bounds2f
(
Point2f
(
-
1
,
-
1
/
aspect
),
Point2f
(
1
,
1
/
aspect
));
hither
=
1e-3
f
;
Float
yon
=
1e30
f
;
ScreenFromLight
=
Perspective
(
fov
,
hither
,
yon
);
LightFromScreen
=
Inverse
(
ScreenFromLight
);
screenFromLight
=
Perspective
(
fov
,
hither
,
1e30
f
/* yon */
);
lightFromScreen
=
Inverse
(
screenFromLight
);
// Compute
cosine of cone surrounding projection directions
// Compute
projection image area _A_
Float
opposite
=
std
::
tan
(
Radians
(
fov
)
/
2.
f
);
// Area of the image on projection plane.
A
=
4
*
opposite
*
opposite
*
(
aspect
>
1
?
aspect
:
1
/
aspect
);
Point3f
pCorner
(
screenBounds
.
pMax
.
x
,
screenBounds
.
pMax
.
y
,
0
);
Vector3f
wCorner
=
Normalize
(
Vector3f
(
LightFromScreen
(
pCorner
)));
cosTotalWidth
=
wCorner
.
z
;
// Compute sampling distribution for _ProjectionLight_
ImageChannelDesc
channelDesc
=
image
.
GetChannelDesc
({
"R"
,
"G"
,
"B"
});
if
(
!
channelDesc
)
...
...
@@ -236,31 +230,30 @@ ProjectionLight::ProjectionLight(const Transform &renderFromLight,
CHECK_EQ
(
3
,
channelDesc
.
size
());
CHECK
(
channelDesc
.
IsIdentity
());
auto
dwdA
=
[
&
](
const
Point2f
&
p
)
{
Vector3f
w
=
Vector3f
(
L
ightFromScreen
(
Point3f
(
p
.
x
,
p
.
y
,
0
)));
Vector3f
w
=
Vector3f
(
l
ightFromScreen
(
Point3f
(
p
.
x
,
p
.
y
,
0
)));
w
=
Normalize
(
w
);
return
Pow
<
3
>
(
w
.
z
);
};
Array2D
<
Float
>
d
=
image
.
GetSamplingDistribution
(
dwdA
,
screenBounds
);
distrib
=
PiecewiseConstant2D
(
d
,
screenBounds
);
//
scale radiance to 1 nit
//
Set _ProjectionLight::scale_ based on photometric settings
scale
/=
SpectrumToPhotometric
(
&
imageColorSpace
->
illuminant
);
// scale to target photometric power if requested
if
(
phi_v
>
0
)
{
// Update _scale_ for target photometric power
Float
sum
=
0
;
RGB
luminance
=
imageColorSpace
->
LuminanceVector
();
for
(
int
v
=
0
;
v
<
image
.
Resolution
().
y
;
++
v
)
for
(
int
u
=
0
;
u
<
image
.
Resolution
().
x
;
++
u
)
{
for
(
int
y
=
0
;
y
<
image
.
Resolution
().
y
;
++
y
)
for
(
int
x
=
0
;
x
<
image
.
Resolution
().
x
;
++
x
)
{
Point2f
ps
=
screenBounds
.
Lerp
(
{(
u
+
.5
f
)
/
image
.
Resolution
().
x
,
(
v
+
.5
f
)
/
image
.
Resolution
().
y
});
Vector3f
w
=
Vector3f
(
L
ightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
{(
x
+
.5
f
)
/
image
.
Resolution
().
x
,
(
y
+
.5
f
)
/
image
.
Resolution
().
y
});
Vector3f
w
=
Vector3f
(
l
ightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
w
=
Normalize
(
w
);
Float
dwdA
=
Pow
<
3
>
(
w
.
z
);
for
(
int
c
=
0
;
c
<
3
;
++
c
)
sum
+=
image
.
GetChannel
({
u
,
v
},
c
)
*
luminance
[
c
]
*
dwdA
;
sum
+=
image
.
GetChannel
({
x
,
y
},
c
)
*
luminance
[
c
]
*
dwdA
;
}
scale
*=
phi_v
/
(
A
*
sum
/
(
image
.
Resolution
().
x
*
image
.
Resolution
().
y
));
}
...
...
@@ -270,11 +263,14 @@ ProjectionLight::ProjectionLight(const Transform &renderFromLight,
pstd
::
optional
<
LightLiSample
>
ProjectionLight
::
SampleLi
(
LightSampleContext
ctx
,
Point2f
u
,
SampledWavelengths
lambda
,
LightSamplingMode
mode
)
const
{
// Return sample for incident radiance from _ProjectionLight_
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
wi
=
Normalize
(
p
-
ctx
.
p
());
Vector3f
wl
=
renderFromLight
.
ApplyInverse
(
-
wi
);
return
LightLiSample
(
Projection
(
wl
,
lambda
)
/
DistanceSquared
(
p
,
ctx
.
p
()),
wi
,
1
,
Interaction
(
p
,
0
/* time */
,
&
mediumInterface
));
SampledSpectrum
Li
=
Projection
(
wl
,
lambda
)
/
DistanceSquared
(
p
,
ctx
.
p
());
if
(
!
Li
)
return
{};
return
LightLiSample
(
Li
,
wi
,
1
,
Interaction
(
p
,
&
mediumInterface
));
}
Float
ProjectionLight
::
PDF_Li
(
LightSampleContext
,
Vector3f
,
...
...
@@ -282,48 +278,19 @@ Float ProjectionLight::PDF_Li(LightSampleContext, Vector3f,
return
0.
f
;
}
LightBounds
ProjectionLight
::
Bounds
()
const
{
#if 0
// Along the lines of Phi()
Float sum = 0;
for (int v = 0; v < image.Resolution().y; ++v)
for (int u = 0; u < image.Resolution().x; ++u) {
Point2f ps = screenBounds.Lerp({(u + .5f) / image.Resolution().x,
(v + .5f) / image.Resolution().y});
Vector3f w = Vector3f(LightFromScreen(Point3f(ps.x, ps.y, 0)));
w = Normalize(w);
Float dwdA = Pow<3>(w.z);
sum += image.GetChannels({u, v}, rgbChannelDesc).MaxValue() * dwdA;
}
Float phi = scale * A * sum / (image.Resolution().x * image.Resolution().y);
#else
// See comment in SpotLight::Bounds()
Float
sum
=
0
;
for
(
int
v
=
0
;
v
<
image
.
Resolution
().
y
;
++
v
)
for
(
int
u
=
0
;
u
<
image
.
Resolution
().
x
;
++
u
)
sum
+=
std
::
max
({
image
.
GetChannel
({
u
,
v
},
0
),
image
.
GetChannel
({
u
,
v
},
1
),
image
.
GetChannel
({
u
,
v
},
2
)});
Float
phi
=
scale
*
sum
/
(
image
.
Resolution
().
x
*
image
.
Resolution
().
y
);
#endif
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
w
=
Normalize
(
renderFromLight
(
Vector3f
(
0
,
0
,
1
)));
return
LightBounds
(
p
,
w
,
phi
,
0.
f
,
std
::
acos
(
cosTotalWidth
),
false
);
}
std
::
string
ProjectionLight
::
ToString
()
const
{
return
StringPrintf
(
"[ ProjectionLight %s scale: %f A: %f
cosTotalWidth: %f ]"
,
BaseToString
(),
scale
,
A
,
cosTotalWidth
);
return
StringPrintf
(
"[ ProjectionLight %s scale: %f A: %f
]"
,
BaseToString
(),
scale
,
A
);
}
// Takes wl already in light coordinate system!
SampledSpectrum
ProjectionLight
::
Projection
(
const
Vector3f
&
wl
,
SampledSpectrum
ProjectionLight
::
Projection
(
Vector3f
wl
,
const
SampledWavelengths
&
lambda
)
const
{
// Discard directions behind projection light
if
(
wl
.
z
<
hither
)
return
SampledSpectrum
(
0.
);
// Project point onto projection plane and compute RGB
Point3f
ps
=
S
creenFromLight
(
Point3f
(
wl
.
x
,
wl
.
y
,
wl
.
z
));
Point3f
ps
=
s
creenFromLight
(
Point3f
(
wl
.
x
,
wl
.
y
,
wl
.
z
));
if
(
!
Inside
(
Point2f
(
ps
.
x
,
ps
.
y
),
screenBounds
))
return
SampledSpectrum
(
0.
f
);
Point2f
st
=
Point2f
(
screenBounds
.
Offset
(
Point2f
(
ps
.
x
,
ps
.
y
)));
...
...
@@ -331,30 +298,64 @@ SampledSpectrum ProjectionLight::Projection(const Vector3f &wl,
for
(
int
c
=
0
;
c
<
3
;
++
c
)
rgb
[
c
]
=
image
.
LookupNearestChannel
(
st
,
c
);
return
scale
*
RGBIlluminantSpectrum
(
*
imageColorSpace
,
rgb
).
Sample
(
lambda
);
// Return scaled wavelength samples corresponding to RGB
RGBIlluminantSpectrum
s
(
*
imageColorSpace
,
rgb
);
return
scale
*
s
.
Sample
(
lambda
);
}
SampledSpectrum
ProjectionLight
::
Phi
(
const
SampledWavelengths
&
lambda
)
const
{
SampledSpectrum
sum
(
0.
f
);
for
(
int
v
=
0
;
v
<
image
.
Resolution
().
y
;
++
v
)
for
(
int
u
=
0
;
u
<
image
.
Resolution
().
x
;
++
u
)
{
Point2f
ps
=
screenBounds
.
Lerp
(
{(
u
+
.5
f
)
/
image
.
Resolution
().
x
,
(
v
+
.5
f
)
/
image
.
Resolution
().
y
});
Vector3f
w
=
Vector3f
(
LightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
for
(
int
y
=
0
;
y
<
image
.
Resolution
().
y
;
++
y
)
for
(
int
x
=
0
;
x
<
image
.
Resolution
().
x
;
++
x
)
{
// Add pixel $(x,y)$'s contribution to projection light power
// Compute change of variables factor _dwdA_ for projection light pixel
Point2f
ps
=
screenBounds
.
Lerp
(
Point2f
((
x
+
.5
f
)
/
image
.
Resolution
().
x
,
(
y
+
.5
f
)
/
image
.
Resolution
().
y
));
Vector3f
w
=
Vector3f
(
lightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
w
=
Normalize
(
w
);
Float
dwdA
=
Pow
<
3
>
(
w
.
z
);
Float
dwdA
=
Pow
<
3
>
(
CosTheta
(
w
)
);
// Update _sum_ for projection light pixel
RGB
rgb
;
for
(
int
c
=
0
;
c
<
3
;
++
c
)
rgb
[
c
]
=
image
.
GetChannel
({
u
,
v
},
c
);
SampledSpectrum
L
=
RGBIlluminantSpectrum
(
*
imageColorSpace
,
rgb
).
Sample
(
lambda
);
rgb
[
c
]
=
image
.
GetChannel
({
x
,
y
},
c
);
RGBIlluminantSpectrum
s
(
*
imageColorSpace
,
rgb
);
sum
+=
s
.
Sample
(
lambda
)
*
dwdA
;
}
// Return final power for projection light
return
scale
*
A
*
sum
/
(
image
.
Resolution
().
x
*
image
.
Resolution
().
y
);
}
sum
+=
L
*
dwdA
;
LightBounds
ProjectionLight
::
Bounds
()
const
{
#if 0
// Along the lines of Phi()
Float sum = 0;
for (int v = 0; v < image.Resolution().y; ++v)
for (int u = 0; u < image.Resolution().x; ++u) {
Point2f ps = screenBounds.Lerp({(u + .5f) / image.Resolution().x,
(v + .5f) / image.Resolution().y});
Vector3f w = Vector3f(lightFromScreen(Point3f(ps.x, ps.y, 0)));
w = Normalize(w);
Float dwdA = Pow<3>(w.z);
sum += image.GetChannels({u, v}, rgbChannelDesc).MaxValue() * dwdA;
}
Float phi = scale * A * sum / (image.Resolution().x * image.Resolution().y);
#else
// See comment in SpotLight::Bounds()
Float
sum
=
0
;
for
(
int
v
=
0
;
v
<
image
.
Resolution
().
y
;
++
v
)
for
(
int
u
=
0
;
u
<
image
.
Resolution
().
x
;
++
u
)
sum
+=
std
::
max
({
image
.
GetChannel
({
u
,
v
},
0
),
image
.
GetChannel
({
u
,
v
},
1
),
image
.
GetChannel
({
u
,
v
},
2
)});
Float
phi
=
scale
*
sum
/
(
image
.
Resolution
().
x
*
image
.
Resolution
().
y
);
#endif
Point3f
pCorner
(
screenBounds
.
pMax
.
x
,
screenBounds
.
pMax
.
y
,
0
);
Vector3f
wCorner
=
Normalize
(
Vector3f
(
lightFromScreen
(
pCorner
)));
Float
cosTotalWidth
=
CosTheta
(
wCorner
);
return
scale
*
A
*
sum
/
(
image
.
Resolution
().
x
*
image
.
Resolution
().
y
);
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
w
=
Normalize
(
renderFromLight
(
Vector3f
(
0
,
0
,
1
)));
return
LightBounds
(
p
,
w
,
phi
,
0.
f
,
std
::
acos
(
cosTotalWidth
),
false
);
}
LightLeSample
ProjectionLight
::
SampleLe
(
const
Point2f
&
u1
,
const
Point2f
&
u2
,
...
...
@@ -364,7 +365,7 @@ LightLeSample ProjectionLight::SampleLe(const Point2f &u1, const Point2f &u2,
if
(
pdf
==
0
)
return
{};
Vector3f
w
=
Vector3f
(
L
ightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
Vector3f
w
=
Vector3f
(
l
ightFromScreen
(
Point3f
(
ps
.
x
,
ps
.
y
,
0
)));
Ray
ray
=
renderFromLight
(
Ray
(
Point3f
(
0
,
0
,
0
),
Normalize
(
w
),
time
,
mediumInterface
.
outside
));
...
...
@@ -391,7 +392,7 @@ void ProjectionLight::PDF_Le(const Ray &ray, Float *pdfPos, Float *pdfDir) const
*
pdfDir
=
0
;
return
;
}
Point3f
ps
=
S
creenFromLight
(
Point3f
(
w
));
Point3f
ps
=
s
creenFromLight
(
Point3f
(
w
));
if
(
!
Inside
(
Point2f
(
ps
.
x
,
ps
.
y
),
screenBounds
))
{
*
pdfDir
=
0
;
return
;
...
...
@@ -458,7 +459,7 @@ pstd::optional<LightLiSample> GoniometricLight::SampleLi(LightSampleContext ctx,
Vector3f
wi
=
Normalize
(
p
-
ctx
.
p
());
SampledSpectrum
L
=
Scale
(
renderFromLight
.
ApplyInverse
(
-
wi
),
lambda
)
/
DistanceSquared
(
p
,
ctx
.
p
());
return
LightLiSample
(
L
,
wi
,
1
,
Interaction
(
p
,
0
/* time */
,
&
mediumInterface
));
return
LightLiSample
(
L
,
wi
,
1
,
Interaction
(
p
,
&
mediumInterface
));
}
Float
GoniometricLight
::
PDF_Li
(
LightSampleContext
,
Vector3f
,
...
...
@@ -466,6 +467,18 @@ Float GoniometricLight::PDF_Li(LightSampleContext, Vector3f,
return
0.
f
;
}
SampledSpectrum
GoniometricLight
::
Phi
(
const
SampledWavelengths
&
lambda
)
const
{
// integrate over speherical coordinates [0,Pi], [0,2pi]
Float
sumY
=
0
;
int
width
=
image
.
Resolution
().
x
,
height
=
image
.
Resolution
().
y
;
for
(
int
v
=
0
;
v
<
height
;
++
v
)
{
Float
sinTheta
=
std
::
sin
(
Pi
*
Float
(
v
+
.5
f
)
/
Float
(
height
));
for
(
int
u
=
0
;
u
<
width
;
++
u
)
sumY
+=
sinTheta
*
image
.
GetChannels
({
u
,
v
},
wrapMode
).
Average
();
}
return
scale
*
I
.
Sample
(
lambda
)
*
2
*
Pi
*
Pi
*
sumY
/
(
width
*
height
);
}
LightBounds
GoniometricLight
::
Bounds
()
const
{
// Like Phi() method, but compute the weighted max component value of
// the image map.
...
...
@@ -485,18 +498,6 @@ LightBounds GoniometricLight::Bounds() const {
return
LightBounds
(
p
,
Vector3f
(
0
,
0
,
1
),
phi
,
Pi
,
Pi
/
2
,
false
);
}
SampledSpectrum
GoniometricLight
::
Phi
(
const
SampledWavelengths
&
lambda
)
const
{
// integrate over speherical coordinates [0,Pi], [0,2pi]
Float
sumY
=
0
;
int
width
=
image
.
Resolution
().
x
,
height
=
image
.
Resolution
().
y
;
for
(
int
v
=
0
;
v
<
height
;
++
v
)
{
Float
sinTheta
=
std
::
sin
(
Pi
*
Float
(
v
+
.5
f
)
/
Float
(
height
));
for
(
int
u
=
0
;
u
<
width
;
++
u
)
sumY
+=
sinTheta
*
image
.
GetChannels
({
u
,
v
},
wrapMode
).
Average
();
}
return
scale
*
I
.
Sample
(
lambda
)
*
2
*
Pi
*
Pi
*
sumY
/
(
width
*
height
);
}
LightLeSample
GoniometricLight
::
SampleLe
(
const
Point2f
&
u1
,
const
Point2f
&
u2
,
SampledWavelengths
&
lambda
,
Float
time
)
const
{
Float
pdf
;
...
...
@@ -816,9 +817,8 @@ pstd::optional<LightLiSample> UniformInfiniteLight::SampleLi(
LightSamplingMode
mode
)
const
{
Vector3f
wi
=
SampleUniformSphere
(
u
);
Float
pdf
=
UniformSpherePDF
();
return
LightLiSample
(
scale
*
Lemit
.
Sample
(
lambda
),
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
0
/* time */
,
&
mediumInterface
));
return
LightLiSample
(
scale
*
Lemit
.
Sample
(
lambda
),
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
&
mediumInterface
));
}
Float
UniformInfiniteLight
::
PDF_Li
(
LightSampleContext
ctx
,
Vector3f
w
,
...
...
@@ -1094,9 +1094,8 @@ pstd::optional<LightLiSample> PortalImageInfiniteLight::SampleLi(
SampledSpectrum
L
=
ImageLookup
(
uv
,
lambda
);
return
LightLiSample
(
L
,
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
0
/* time */
,
&
mediumInterface
));
return
LightLiSample
(
L
,
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
&
mediumInterface
));
}
Float
PortalImageInfiniteLight
::
PDF_Li
(
LightSampleContext
ctx
,
Vector3f
w
,
...
...
@@ -1202,28 +1201,17 @@ SpotLight::SpotLight(const Transform &renderFromLight,
CHECK_LE
(
falloffStart
,
totalWidth
);
}
pstd
::
optional
<
LightLiSample
>
SpotLight
::
SampleLi
(
LightSampleContext
ctx
,
Point2f
u
,
SampledWavelengths
lambda
,
LightSamplingMode
mode
)
const
{
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
wi
=
Normalize
(
p
-
ctx
.
p
());
Vector3f
wl
=
Normalize
(
renderFromLight
.
ApplyInverse
(
-
wi
));
SampledSpectrum
L
=
scale
*
I
.
Sample
(
lambda
)
*
Falloff
(
wl
)
/
DistanceSquared
(
p
,
ctx
.
p
());
if
(
!
L
)
return
{};
return
LightLiSample
(
L
,
wi
,
1
,
Interaction
(
p
,
0
/* time */
,
&
mediumInterface
));
}
Float
SpotLight
::
PDF_Li
(
LightSampleContext
,
Vector3f
,
LightSamplingMode
mode
)
const
{
return
0.
f
;
}
Float
SpotLight
::
Falloff
(
const
Vector3f
&
wl
)
const
{
Float
cosTheta
=
CosTheta
(
wl
);
if
(
cosTheta
>=
cosFalloffStart
)
return
1
;
return
SmoothStep
(
cosTheta
,
cosFalloffEnd
,
cosFalloffStart
);
return
SmoothStep
(
CosTheta
(
wl
),
cosFalloffEnd
,
cosFalloffStart
);
}
SampledSpectrum
SpotLight
::
Phi
(
const
SampledWavelengths
&
lambda
)
const
{
return
scale
*
I
.
Sample
(
lambda
)
*
2
*
Pi
*
((
1
-
cosFalloffStart
)
+
(
cosFalloffStart
-
cosFalloffEnd
)
/
2
);
}
LightBounds
SpotLight
::
Bounds
()
const
{
...
...
@@ -1246,15 +1234,6 @@ LightBounds SpotLight::Bounds() const {
return
LightBounds
(
p
,
w
,
phi
,
0.
f
,
std
::
acos
(
cosFalloffEnd
),
false
);
}
SampledSpectrum
SpotLight
::
Phi
(
const
SampledWavelengths
&
lambda
)
const
{
// int_0^start sin theta dtheta = 1 - cosFalloffStart
// See notes/sample-spotlight.nb for the falloff part:
// int_start^end smoothstep(cost, end, start) sin theta dtheta =
// (cosStart - cosEnd) / 2
return
scale
*
I
.
Sample
(
lambda
)
*
2
*
Pi
*
((
1
-
cosFalloffStart
)
+
(
cosFalloffStart
-
cosFalloffEnd
)
/
2
);
}
LightLeSample
SpotLight
::
SampleLe
(
const
Point2f
&
u1
,
const
Point2f
&
u2
,
SampledWavelengths
&
lambda
,
Float
time
)
const
{
// Unnormalized probabilities of sampling each part.
...
...
src/pbrt/lights.h
浏览文件 @
251754af
...
...
@@ -36,7 +36,6 @@ PBRT_CPU_GPU inline bool IsDeltaLight(LightType type) {
// LightLiSample Definition
struct
LightLiSample
{
public:
// LightLiSample Public Methods
LightLiSample
()
=
default
;
PBRT_CPU_GPU
...
...
@@ -225,18 +224,19 @@ LightBounds Union(const LightBounds &a, const LightBounds &b);
class
LightBase
{
public:
// LightBase Public Methods
LightBase
(
LightType
flags
,
const
Transform
&
renderFromLight
,
LightBase
(
LightType
type
,
const
Transform
&
renderFromLight
,
const
MediumInterface
&
mediumInterface
);
PBRT_CPU_GPU
LightType
Type
()
const
{
return
type
;
}
PBRT_CPU_GPU
SampledSpectrum
L
(
const
Point3f
&
p
,
const
Normal3f
&
n
,
const
Point2f
&
uv
,
const
Vector3f
&
w
,
const
SampledWavelengths
&
lambda
)
const
{
SampledSpectrum
L
(
Point3f
p
,
Normal3f
n
,
Point2f
uv
,
Vector3f
w
,
const
SampledWavelengths
&
lambda
)
const
{
return
SampledSpectrum
(
0.
f
);
}
PBRT_CPU_GPU
SampledSpectrum
Le
(
const
Ray
&
ray
,
const
SampledWavelengths
&
lambda
)
const
{
SampledSpectrum
Le
(
const
Ray
&
,
const
SampledWavelengths
&
)
const
{
return
SampledSpectrum
(
0.
f
);
}
...
...
@@ -244,15 +244,15 @@ class LightBase {
std
::
string
BaseToString
()
const
;
// LightBase Protected Members
LightType
type
;
MediumInterface
mediumInterface
;
Transform
renderFromLight
;
MediumInterface
mediumInterface
;
};
// PointLight Definition
class
PointLight
:
public
LightBase
{
public:
// PointLight Public Methods
PointLight
(
const
Transform
&
renderFromLight
,
const
MediumInterface
&
mediumInterface
,
PointLight
(
Transform
renderFromLight
,
MediumInterface
mediumInterface
,
SpectrumHandle
I
,
Float
scale
,
Allocator
alloc
)
:
LightBase
(
LightType
::
DeltaPosition
,
renderFromLight
,
mediumInterface
),
I
(
I
,
alloc
),
...
...
@@ -286,8 +286,8 @@ class PointLight : public LightBase {
LightSamplingMode
mode
)
const
{
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
wi
=
Normalize
(
p
-
ctx
.
p
());
return
LightLiSample
(
scale
*
I
.
Sample
(
lambda
)
/
DistanceSquared
(
p
,
ctx
.
p
()),
wi
,
1
,
Interaction
(
p
,
0
/* time */
,
&
mediumInterface
));
SampledSpectrum
Li
=
scale
*
I
.
Sample
(
lambda
)
/
DistanceSquared
(
p
,
ctx
.
p
());
return
LightLiSample
(
Li
,
wi
,
1
,
Interaction
(
p
,
&
mediumInterface
));
}
PBRT_CPU_GPU
...
...
@@ -342,7 +342,7 @@ class DistantLight : public LightBase {
Vector3f
wi
=
Normalize
(
renderFromLight
(
Vector3f
(
0
,
0
,
1
)));
Point3f
pOutside
=
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
);
return
LightLiSample
(
scale
*
Lemit
.
Sample
(
lambda
),
wi
,
1
,
Interaction
(
pOutside
,
0
/* time */
,
&
mediumInterface
));
Interaction
(
pOutside
,
&
mediumInterface
));
}
private:
...
...
@@ -357,9 +357,9 @@ class DistantLight : public LightBase {
class
ProjectionLight
:
public
LightBase
{
public:
// ProjectionLight Public Methods
ProjectionLight
(
const
Transform
&
renderFromLight
,
const
MediumInterface
&
medium
,
Image
image
,
const
RGBColorSpace
*
colorSpace
,
Float
scale
,
Float
fov
,
Float
power
,
Allocator
alloc
);
ProjectionLight
(
Transform
renderFromLight
,
MediumInterface
medium
,
Image
image
,
const
RGBColorSpace
*
colorSpace
,
Float
scale
,
Float
fov
,
Float
power
,
Allocator
alloc
);
static
ProjectionLight
*
Create
(
const
Transform
&
renderFromLight
,
MediumHandle
medium
,
const
ParameterDictionary
&
parameters
,
...
...
@@ -372,7 +372,7 @@ class ProjectionLight : public LightBase {
SampledWavelengths
lambda
,
LightSamplingMode
mode
)
const
;
PBRT_CPU_GPU
SampledSpectrum
Projection
(
const
Vector3f
&
w
,
const
SampledWavelengths
&
lambda
)
const
;
SampledSpectrum
Projection
(
Vector3f
w
,
const
SampledWavelengths
&
lambda
)
const
;
SampledSpectrum
Phi
(
const
SampledWavelengths
&
lambda
)
const
;
...
...
@@ -400,9 +400,9 @@ class ProjectionLight : public LightBase {
const
RGBColorSpace
*
imageColorSpace
;
Float
scale
;
Bounds2f
screenBounds
;
Float
hither
;
Transform
ScreenFromLight
,
L
ightFromScreen
;
Float
A
,
cosTotalWidth
;
Float
hither
=
1e-3
f
;
Transform
screenFromLight
,
l
ightFromScreen
;
Float
A
;
PiecewiseConstant2D
distrib
;
};
...
...
@@ -499,8 +499,8 @@ class DiffuseAreaLight : public LightBase {
std
::
string
ToString
()
const
;
PBRT_CPU_GPU
SampledSpectrum
L
(
const
Point3f
&
p
,
const
Normal3f
&
n
,
const
Point2f
&
uv
,
const
Vector3f
&
w
,
const
SampledWavelengths
&
lambda
)
const
{
SampledSpectrum
L
(
Point3f
p
,
Normal3f
n
,
Point2f
uv
,
Vector3f
w
,
const
SampledWavelengths
&
lambda
)
const
{
if
(
!
twoSided
&&
Dot
(
n
,
w
)
<
0
)
return
SampledSpectrum
(
0.
f
);
...
...
@@ -656,9 +656,8 @@ class ImageInfiniteLight : public LightBase {
// Return radiance value for infinite light direction
SampledSpectrum
L
=
LookupLe
(
uv
,
lambda
);
return
LightLiSample
(
L
,
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
0
/* time */
,
&
mediumInterface
));
return
LightLiSample
(
L
,
wi
,
pdf
,
Interaction
(
ctx
.
p
()
+
wi
*
(
2
*
sceneRadius
),
&
mediumInterface
));
}
LightBounds
Bounds
()
const
{
return
{};
}
...
...
@@ -799,10 +798,6 @@ class SpotLight : public LightBase {
void
Preprocess
(
const
Bounds3f
&
sceneBounds
)
{}
PBRT_CPU_GPU
pstd
::
optional
<
LightLiSample
>
SampleLi
(
LightSampleContext
ctx
,
Point2f
u
,
SampledWavelengths
lambda
,
LightSamplingMode
mode
)
const
;
PBRT_CPU_GPU
Float
Falloff
(
const
Vector3f
&
w
)
const
;
...
...
@@ -826,11 +821,26 @@ class SpotLight : public LightBase {
std
::
string
ToString
()
const
;
PBRT_CPU_GPU
pstd
::
optional
<
LightLiSample
>
SampleLi
(
LightSampleContext
ctx
,
Point2f
u
,
SampledWavelengths
lambda
,
LightSamplingMode
mode
)
const
{
Point3f
p
=
renderFromLight
(
Point3f
(
0
,
0
,
0
));
Vector3f
wi
=
Normalize
(
p
-
ctx
.
p
());
// Compute incident radiance _Li_ for _SpotLight_
Vector3f
wl
=
Normalize
(
renderFromLight
.
ApplyInverse
(
-
wi
));
SampledSpectrum
Li
=
scale
*
I
.
Sample
(
lambda
)
*
Falloff
(
wl
)
/
DistanceSquared
(
p
,
ctx
.
p
());
if
(
!
Li
)
return
{};
return
LightLiSample
(
Li
,
wi
,
1
,
Interaction
(
p
,
&
mediumInterface
));
}
private:
// SpotLight Private Members
DenselySampledSpectrum
I
;
Float
scale
;
Float
cosFalloffStart
,
cosFalloffEnd
;
Float
scale
,
cosFalloffStart
,
cosFalloffEnd
;
};
inline
pstd
::
optional
<
LightLiSample
>
LightHandle
::
SampleLi
(
LightSampleContext
ctx
,
...
...
@@ -847,8 +857,7 @@ inline Float LightHandle::PDF_Li(LightSampleContext ctx, Vector3f wi,
return
Dispatch
(
pdf
);
}
inline
SampledSpectrum
LightHandle
::
L
(
const
Point3f
&
p
,
const
Normal3f
&
n
,
const
Point2f
&
uv
,
const
Vector3f
&
w
,
inline
SampledSpectrum
LightHandle
::
L
(
Point3f
p
,
Normal3f
n
,
Point2f
uv
,
Vector3f
w
,
const
SampledWavelengths
&
lambda
)
const
{
CHECK
(
Type
()
==
LightType
::
Area
);
auto
l
=
[
&
](
auto
ptr
)
{
return
ptr
->
L
(
p
,
n
,
uv
,
w
,
lambda
);
};
...
...
src/pbrt/media.h
浏览文件 @
251754af
...
...
@@ -248,22 +248,22 @@ class CuboidMedium {
if
(
t
>=
t1
)
break
;
// Report scattering event in grid to callback function
if
(
t
<
tMax
)
{
Point3f
p
=
ray
(
t
);
// Compute medium properties at sampled point in grid
SampledSpectrum
Tmaj
=
FastExp
(
-
sigma_maj
*
(
t
-
t0
));
// Compute _density_ and _Le_ at sampled point in grid
SampledSpectrum
d
ensity
=
provider
->
Density
(
p
,
lambda
);
Point3f
p
=
ray
(
t
);
SampledSpectrum
d
=
provider
->
Density
(
p
,
lambda
);
SampledSpectrum
Le
=
provider
->
Le
(
p
,
lambda
);
SampledSpectrum
sigmap_a
=
sigma_a
*
d
,
sigmap_s
=
sigma_s
*
d
;
MediumInteraction
intr
(
renderFromMedium
(
p
),
-
Normalize
(
rRender
.
d
),
rRender
.
time
,
sigma_a
*
density
,
sigma_s
*
density
,
sigma_maj
,
Le
,
this
,
&
phase
);
// Report scattering event in grid to callback function
Point3f
pRender
=
renderFromMedium
(
p
);
MediumInteraction
intr
(
pRender
,
-
Normalize
(
rRender
.
d
),
rRender
.
time
,
sigmap_a
,
sigmap_s
,
sigma_maj
,
Le
,
this
,
&
phase
);
if
(
!
callback
(
MediumSample
(
intr
,
Tmaj
)))
return
;
}
// Update _t0_ after medium interaction
t0
=
t
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录