Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
imjiangjun
pbrt-v4
提交
db69a235
P
pbrt-v4
项目概览
imjiangjun
/
pbrt-v4
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
db69a235
编写于
1月 14, 2021
作者:
M
Matt Pharr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update from book source. No functional changes.
上级
24067ca2
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
85 addition
and
119 deletion
+85
-119
src/pbrt/cpu/integrators.h
src/pbrt/cpu/integrators.h
+2
-1
src/pbrt/util/math.h
src/pbrt/util/math.h
+3
-5
src/pbrt/util/sampling.h
src/pbrt/util/sampling.h
+80
-113
未找到文件。
src/pbrt/cpu/integrators.h
浏览文件 @
db69a235
...
...
@@ -69,7 +69,8 @@ class Integrator {
Integrator
(
PrimitiveHandle
aggregate
,
std
::
vector
<
LightHandle
>
lights
)
:
aggregate
(
aggregate
),
lights
(
lights
)
{
// Integrator constructor implementation
Bounds3f
sceneBounds
=
aggregate
.
Bounds
();
Bounds3f
sceneBounds
=
aggregate
?
aggregate
.
Bounds
()
:
Bounds3f
();
LOG_VERBOSE
(
"Scene bounds %s"
,
sceneBounds
);
for
(
auto
&
light
:
lights
)
{
light
.
Preprocess
(
sceneBounds
);
if
(
light
.
Type
()
==
LightType
::
Infinite
)
...
...
src/pbrt/util/math.h
浏览文件 @
db69a235
...
...
@@ -105,9 +105,8 @@ template <int N>
class
SquareMatrix
;
// Math Inline Functions
PBRT_CPU_GPU
inline
Float
Lerp
(
Float
t
,
Float
a
,
Float
b
)
{
return
(
1
-
t
)
*
a
+
t
*
b
;
PBRT_CPU_GPU
inline
Float
Lerp
(
Float
x
,
Float
a
,
Float
b
)
{
return
(
1
-
x
)
*
a
+
x
*
b
;
}
// http://www.plunk.org/~hatch/rightway.php
...
...
@@ -566,8 +565,7 @@ InnerProduct(T... terms) {
return
Float
(
ip
);
}
PBRT_CPU_GPU
inline
bool
Quadratic
(
float
a
,
float
b
,
float
c
,
float
*
t0
,
float
*
t1
)
{
PBRT_CPU_GPU
inline
bool
Quadratic
(
float
a
,
float
b
,
float
c
,
float
*
t0
,
float
*
t1
)
{
// Handle case of $a=0$ for quadratic solution
if
(
a
==
0
)
{
*
t0
=
*
t1
=
-
c
/
b
;
...
...
src/pbrt/util/sampling.h
浏览文件 @
db69a235
...
...
@@ -61,13 +61,12 @@ Float SampleCatmullRom2D(pstd::span<const Float> nodes1, pstd::span<const Float>
Float
*
pdf
=
nullptr
);
// Sampling Inline Functions
PBRT_CPU_GPU
inline
int
SampleDiscrete
(
pstd
::
span
<
const
Float
>
weights
,
Float
u
,
Float
*
pdf
=
nullptr
,
Float
*
uRemapped
=
nullptr
)
{
PBRT_CPU_GPU
inline
int
SampleDiscrete
(
pstd
::
span
<
const
Float
>
weights
,
Float
u
,
Float
*
pmf
=
nullptr
,
Float
*
uRemapped
=
nullptr
)
{
// Handle empty _weights_ for discrete sampling
if
(
weights
.
empty
())
{
if
(
p
d
f
!=
nullptr
)
*
p
d
f
=
0
;
if
(
p
m
f
!=
nullptr
)
*
p
m
f
=
0
;
return
-
1
;
}
...
...
@@ -86,26 +85,24 @@ inline int SampleDiscrete(pstd::span<const Float> weights, Float u, Float *pdf =
if
(
offset
==
weights
.
size
())
offset
=
weights
.
size
()
-
1
;
// Compute P
D
F and remapped _u_ value, if necessary
// Compute P
M
F and remapped _u_ value, if necessary
Float
p
=
weights
[
offset
]
/
sumWeights
;
if
(
p
d
f
!=
nullptr
)
*
p
d
f
=
p
;
if
(
p
m
f
!=
nullptr
)
*
p
m
f
=
p
;
if
(
uRemapped
!=
nullptr
)
*
uRemapped
=
std
::
min
(
u
/
p
,
OneMinusEpsilon
);
return
offset
;
}
PBRT_CPU_GPU
inline
Float
LinearPDF
(
Float
x
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
LinearPDF
(
Float
x
,
Float
a
,
Float
b
)
{
DCHECK
(
a
>=
0
&&
b
>=
0
);
if
(
x
<
0
||
x
>
1
)
return
0
;
return
2
*
Lerp
(
x
,
a
,
b
)
/
(
a
+
b
);
}
PBRT_CPU_GPU
inline
Float
SampleLinear
(
Float
u
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
SampleLinear
(
Float
u
,
Float
a
,
Float
b
)
{
DCHECK
(
a
>=
0
&&
b
>=
0
);
if
(
u
==
0
&&
a
==
0
)
return
0
;
...
...
@@ -113,76 +110,87 @@ inline Float SampleLinear(Float u, Float a, Float b) {
return
std
::
min
(
x
,
OneMinusEpsilon
);
}
PBRT_CPU_GPU
inline
Float
InvertLinearSample
(
Float
x
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
InvertLinearSample
(
Float
x
,
Float
a
,
Float
b
)
{
return
x
*
(
a
*
(
2
-
x
)
+
b
*
x
)
/
(
a
+
b
);
}
PBRT_CPU_GPU
inline
Float
ExponentialPDF
(
Float
x
,
Float
a
)
{
PBRT_CPU_GPU
inline
Float
ExponentialPDF
(
Float
x
,
Float
a
)
{
DCHECK_GT
(
a
,
0
);
return
a
*
std
::
exp
(
-
a
*
x
);
}
PBRT_CPU_GPU
inline
Float
SampleExponential
(
Float
u
,
Float
a
)
{
PBRT_CPU_GPU
inline
Float
SampleExponential
(
Float
u
,
Float
a
)
{
DCHECK_GT
(
a
,
0
);
return
-
std
::
log
(
1
-
u
)
/
a
;
}
PBRT_CPU_GPU
inline
Float
InvertExponentialSample
(
Float
x
,
Float
a
)
{
PBRT_CPU_GPU
inline
Float
InvertExponentialSample
(
Float
x
,
Float
a
)
{
DCHECK_GT
(
a
,
0
);
return
1
-
std
::
exp
(
-
a
*
x
);
}
PBRT_CPU_GPU
inline
Float
NormalPDF
(
Float
x
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
Gaussian
(
x
,
mu
,
sigma
);
}
PBRT_CPU_GPU
inline
Float
SampleNormal
(
Float
u
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
mu
+
Sqrt2
*
sigma
*
ErfInv
(
2
*
u
-
1
);
}
PBRT_CPU_GPU
inline
Float
LogisticPDF
(
Float
x
,
Float
s
)
{
inline
Float
InvertNormalSample
(
Float
x
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
0.5
f
*
(
1
+
std
::
erf
((
x
-
mu
)
/
(
sigma
*
Sqrt2
)));
}
PBRT_CPU_GPU
inline
Point2f
SampleTwoNormal
(
const
Point2f
&
u
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
{
mu
+
sigma
*
std
::
sqrt
(
-
2
*
std
::
log
(
1
-
u
[
0
]))
*
std
::
cos
(
2
*
Pi
*
u
[
1
]),
mu
+
sigma
*
std
::
sqrt
(
-
2
*
std
::
log
(
1
-
u
[
0
]))
*
std
::
sin
(
2
*
Pi
*
u
[
1
])};
}
PBRT_CPU_GPU
inline
Float
LogisticPDF
(
Float
x
,
Float
s
)
{
x
=
std
::
abs
(
x
);
return
std
::
exp
(
-
x
/
s
)
/
(
s
*
Sqr
(
1
+
std
::
exp
(
-
x
/
s
)));
}
PBRT_CPU_GPU
inline
Float
SampleLogistic
(
Float
u
,
Float
s
)
{
PBRT_CPU_GPU
inline
Float
SampleLogistic
(
Float
u
,
Float
s
)
{
return
-
s
*
std
::
log
(
1
/
u
-
1
);
}
PBRT_CPU_GPU
inline
Float
InvertLogisticSample
(
Float
x
,
Float
s
)
{
PBRT_CPU_GPU
inline
Float
InvertLogisticSample
(
Float
x
,
Float
s
)
{
return
1
/
(
1
+
std
::
exp
(
-
x
/
s
));
}
PBRT_CPU_GPU
inline
Float
TrimmedLogisticPDF
(
Float
x
,
Float
s
,
Float
a
,
Float
b
)
{
return
Logistic
(
x
,
s
)
/
(
InvertLogisticSample
(
b
,
s
)
-
InvertLogisticSample
(
a
,
s
));
PBRT_CPU_GPU
inline
Float
TrimmedLogisticPDF
(
Float
x
,
Float
s
,
Float
a
,
Float
b
)
{
if
(
x
<
a
||
x
>
b
)
return
0
;
auto
P
=
[
&
](
Float
x
)
{
return
InvertLogisticSample
(
x
,
s
);
};
return
Logistic
(
x
,
s
)
/
(
P
(
b
)
-
P
(
a
));
}
PBRT_CPU_GPU
inline
Float
SampleTrimmedLogistic
(
Float
u
,
Float
s
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
SampleTrimmedLogistic
(
Float
u
,
Float
s
,
Float
a
,
Float
b
)
{
DCHECK_LT
(
a
,
b
);
u
=
Lerp
(
u
,
InvertLogisticSample
(
a
,
s
),
InvertLogisticSample
(
b
,
s
))
;
Float
x
=
SampleLogistic
(
u
,
s
);
auto
P
=
[
&
](
Float
x
)
{
return
InvertLogisticSample
(
x
,
s
);
}
;
Float
x
=
SampleLogistic
(
Lerp
(
u
,
P
(
a
),
P
(
b
))
,
s
);
DCHECK
(
!
IsNaN
(
x
));
return
Clamp
(
x
,
a
,
b
);
}
PBRT_CPU_GPU
inline
Float
InvertTrimmedLogisticSample
(
Float
x
,
Float
s
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
InvertTrimmedLogisticSample
(
Float
x
,
Float
s
,
Float
a
,
Float
b
)
{
DCHECK
(
a
<=
x
&&
x
<=
b
);
return
(
InvertLogisticSample
(
x
,
s
)
-
InvertLogisticSample
(
a
,
s
))
/
(
InvertLogisticSample
(
b
,
s
)
-
InvertLogisticSample
(
a
,
s
));
auto
P
=
[
&
](
Float
x
)
{
return
InvertLogisticSample
(
x
,
s
);
};
return
(
P
(
x
)
-
P
(
a
))
/
(
P
(
b
)
-
P
(
a
));
}
PBRT_CPU_GPU
inline
Float
SmoothStepPDF
(
Float
x
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
SmoothStepPDF
(
Float
x
,
Float
a
,
Float
b
)
{
if
(
x
<
a
||
x
>
b
)
return
0
;
DCHECK_LT
(
a
,
b
);
return
(
2
/
(
b
-
a
))
*
SmoothStep
(
x
,
a
,
b
);
}
PBRT_CPU_GPU
inline
Float
SampleSmoothStep
(
Float
u
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
SampleSmoothStep
(
Float
u
,
Float
a
,
Float
b
)
{
DCHECK_LT
(
a
,
b
);
auto
cdfMinusU
=
[
=
](
Float
x
)
->
std
::
pair
<
Float
,
Float
>
{
Float
t
=
(
x
-
a
)
/
(
b
-
a
);
...
...
@@ -193,70 +201,42 @@ inline Float SampleSmoothStep(Float u, Float a, Float b) {
return
NewtonBisection
(
a
,
b
,
cdfMinusU
);
}
PBRT_CPU_GPU
inline
Float
InvertSmoothStepSample
(
Float
x
,
Float
a
,
Float
b
)
{
PBRT_CPU_GPU
inline
Float
InvertSmoothStepSample
(
Float
x
,
Float
a
,
Float
b
)
{
Float
t
=
(
x
-
a
)
/
(
b
-
a
);
auto
P
=
[
&
](
Float
x
)
{
return
2
*
Pow
<
3
>
(
t
)
-
Pow
<
4
>
(
t
);
};
return
(
P
(
x
)
-
P
(
a
))
/
(
P
(
b
)
-
P
(
a
));
}
PBRT_CPU_GPU
inline
Float
NormalPDF
(
Float
x
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
Gaussian
(
x
,
mu
,
sigma
);
}
PBRT_CPU_GPU
inline
Float
SampleNormal
(
Float
u
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
mu
+
Sqrt2
*
sigma
*
ErfInv
(
2
*
u
-
1
);
}
PBRT_CPU_GPU
inline
Float
InvertNormalSample
(
Float
x
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
0.5
f
*
(
1
+
std
::
erf
((
x
-
mu
)
/
(
sigma
*
Sqrt2
)));
}
PBRT_CPU_GPU
inline
Point2f
SampleTwoNormal
(
const
Point2f
&
u
,
Float
mu
=
0
,
Float
sigma
=
1
)
{
return
{
mu
+
sigma
*
std
::
sqrt
(
-
2
*
std
::
log
(
1
-
u
[
0
]))
*
std
::
cos
(
2
*
Pi
*
u
[
1
]),
mu
+
sigma
*
std
::
sqrt
(
-
2
*
std
::
log
(
1
-
u
[
0
]))
*
std
::
sin
(
2
*
Pi
*
u
[
1
])};
}
PBRT_CPU_GPU
inline
Vector3f
SampleUniformHemisphere
(
const
Point2f
&
u
)
{
PBRT_CPU_GPU
inline
Vector3f
SampleUniformHemisphere
(
const
Point2f
&
u
)
{
Float
z
=
u
[
0
];
Float
r
=
SafeSqrt
(
1
-
z
*
z
);
Float
r
=
SafeSqrt
(
1
-
Sqr
(
z
)
);
Float
phi
=
2
*
Pi
*
u
[
1
];
return
{
r
*
std
::
cos
(
phi
),
r
*
std
::
sin
(
phi
),
z
};
}
PBRT_CPU_GPU
inline
Float
UniformHemispherePDF
()
{
PBRT_CPU_GPU
inline
Float
UniformHemispherePDF
()
{
return
Inv2Pi
;
}
PBRT_CPU_GPU
inline
Point2f
InvertUniformHemisphereSample
(
const
Vector3f
&
v
)
{
PBRT_CPU_GPU
inline
Point2f
InvertUniformHemisphereSample
(
const
Vector3f
&
v
)
{
Float
phi
=
std
::
atan2
(
v
.
y
,
v
.
x
);
if
(
phi
<
0
)
phi
+=
2
*
Pi
;
return
Point2f
(
v
.
z
,
phi
/
(
2
*
Pi
));
}
PBRT_CPU_GPU
inline
Vector3f
SampleUniformSphere
(
const
Point2f
&
u
)
{
PBRT_CPU_GPU
inline
Vector3f
SampleUniformSphere
(
const
Point2f
&
u
)
{
Float
z
=
1
-
2
*
u
[
0
];
Float
r
=
SafeSqrt
(
1
-
z
*
z
);
Float
phi
=
2
*
Pi
*
u
[
1
];
return
{
r
*
std
::
cos
(
phi
),
r
*
std
::
sin
(
phi
),
z
};
}
PBRT_CPU_GPU
inline
Float
UniformSpherePDF
()
{
PBRT_CPU_GPU
inline
Float
UniformSpherePDF
()
{
return
Inv4Pi
;
}
PBRT_CPU_GPU
inline
Point2f
InvertUniformSphereSample
(
const
Vector3f
&
v
)
{
PBRT_CPU_GPU
inline
Point2f
InvertUniformSphereSample
(
const
Vector3f
&
v
)
{
Float
phi
=
std
::
atan2
(
v
.
y
,
v
.
x
);
if
(
phi
<
0
)
phi
+=
2
*
Pi
;
...
...
@@ -277,10 +257,9 @@ inline Point2f InvertUniformDiskPolarSample(const Point2f &p) {
return
Point2f
(
Sqr
(
p
.
x
)
+
Sqr
(
p
.
y
),
phi
/
(
2
*
Pi
));
}
PBRT_CPU_GPU
inline
Point2f
SampleUniformDiskConcentric
(
const
Point2f
&
u
)
{
PBRT_CPU_GPU
inline
Point2f
SampleUniformDiskConcentric
(
const
Point2f
&
u
)
{
// Map _u_ to $[-1,1]^2$ and handle degeneracy at the origin
Point2f
uOffset
=
2
.
f
*
u
-
Vector2f
(
1
,
1
);
Point2f
uOffset
=
2
*
u
-
Vector2f
(
1
,
1
);
if
(
uOffset
.
x
==
0
&&
uOffset
.
y
==
0
)
return
{
0
,
0
};
...
...
@@ -326,45 +305,39 @@ inline Point2f InvertUniformDiskConcentricSample(const Point2f &p) {
return
{(
uo
.
x
+
1
)
/
2
,
(
uo
.
y
+
1
)
/
2
};
}
PBRT_CPU_GPU
inline
Vector3f
SampleCosineHemisphere
(
const
Point2f
&
u
)
{
PBRT_CPU_GPU
inline
Vector3f
SampleCosineHemisphere
(
const
Point2f
&
u
)
{
Point2f
d
=
SampleUniformDiskConcentric
(
u
);
Float
z
=
SafeSqrt
(
1
-
d
.
x
*
d
.
x
-
d
.
y
*
d
.
y
);
return
Vector3f
(
d
.
x
,
d
.
y
,
z
);
}
PBRT_CPU_GPU
inline
Float
CosineHemispherePDF
(
Float
cosTheta
)
{
PBRT_CPU_GPU
inline
Float
CosineHemispherePDF
(
Float
cosTheta
)
{
return
cosTheta
*
InvPi
;
}
PBRT_CPU_GPU
inline
Point2f
InvertCosineHemisphereSample
(
const
Vector3f
&
v
)
{
PBRT_CPU_GPU
inline
Point2f
InvertCosineHemisphereSample
(
const
Vector3f
&
v
)
{
return
InvertUniformDiskConcentricSample
({
v
.
x
,
v
.
y
});
}
PBRT_CPU_GPU
inline
Float
UniformConePDF
(
Float
cosThetaMax
)
{
PBRT_CPU_GPU
inline
Float
UniformConePDF
(
Float
cosThetaMax
)
{
return
1
/
(
2
*
Pi
*
(
1
-
cosThetaMax
));
}
PBRT_CPU_GPU
inline
Vector3f
SampleUniformCone
(
const
Point2f
&
u
,
Float
cosThetaMax
)
{
PBRT_CPU_GPU
inline
Vector3f
SampleUniformCone
(
const
Point2f
&
u
,
Float
cosThetaMax
)
{
Float
cosTheta
=
(
1
-
u
[
0
])
+
u
[
0
]
*
cosThetaMax
;
Float
sinTheta
=
SafeSqrt
(
1
-
cosTheta
*
cosTheta
);
Float
sinTheta
=
SafeSqrt
(
1
-
Sqr
(
cosTheta
)
);
Float
phi
=
u
[
1
]
*
2
*
Pi
;
return
SphericalDirection
(
sinTheta
,
cosTheta
,
phi
);
}
PBRT_CPU_GPU
inline
Point2f
InvertUniformConeSample
(
const
Vector3f
&
v
,
Float
cosThetaMax
)
{
PBRT_CPU_GPU
inline
Point2f
InvertUniformConeSample
(
const
Vector3f
&
v
,
Float
cosThetaMax
)
{
Float
cosTheta
=
v
.
z
;
Float
phi
=
SphericalPhi
(
v
);
return
{(
cosTheta
-
1
)
/
(
cosThetaMax
-
1
),
phi
/
(
2
*
Pi
)};
}
PBRT_CPU_GPU
inline
Float
BilinearPDF
(
Point2f
p
,
pstd
::
span
<
const
Float
>
w
)
{
PBRT_CPU_GPU
inline
Float
BilinearPDF
(
Point2f
p
,
pstd
::
span
<
const
Float
>
w
)
{
DCHECK_EQ
(
4
,
w
.
size
());
if
(
p
.
x
<
0
||
p
.
x
>
1
||
p
.
y
<
0
||
p
.
y
>
1
)
return
0
;
...
...
@@ -373,8 +346,7 @@ inline Float BilinearPDF(Point2f p, pstd::span<const Float> w) {
return
4
*
Bilerp
({
p
[
0
],
p
[
1
]},
w
)
/
(
w
[
0
]
+
w
[
1
]
+
w
[
2
]
+
w
[
3
]);
}
PBRT_CPU_GPU
inline
Point2f
SampleBilinear
(
Point2f
u
,
pstd
::
span
<
const
Float
>
w
)
{
PBRT_CPU_GPU
inline
Point2f
SampleBilinear
(
Point2f
u
,
pstd
::
span
<
const
Float
>
w
)
{
DCHECK_EQ
(
4
,
w
.
size
());
Point2f
p
;
// Sample $v$ for bilinear marginal distribution
...
...
@@ -387,19 +359,16 @@ inline Point2f SampleBilinear(Point2f u, pstd::span<const Float> w) {
return
p
;
}
PBRT_CPU_GPU
inline
Point2f
InvertBilinearSample
(
Point2f
p
,
pstd
::
span
<
const
Float
>
v
)
{
PBRT_CPU_GPU
inline
Point2f
InvertBilinearSample
(
Point2f
p
,
pstd
::
span
<
const
Float
>
v
)
{
return
{
InvertLinearSample
(
p
[
0
],
Lerp
(
p
[
1
],
v
[
0
],
v
[
2
]),
Lerp
(
p
[
1
],
v
[
1
],
v
[
3
])),
InvertLinearSample
(
p
[
1
],
v
[
0
]
+
v
[
1
],
v
[
2
]
+
v
[
3
])};
}
PBRT_CPU_GPU
inline
Float
BalanceHeuristic
(
int
nf
,
Float
fPdf
,
int
ng
,
Float
gPdf
)
{
PBRT_CPU_GPU
inline
Float
BalanceHeuristic
(
int
nf
,
Float
fPdf
,
int
ng
,
Float
gPdf
)
{
return
(
nf
*
fPdf
)
/
(
nf
*
fPdf
+
ng
*
gPdf
);
}
PBRT_CPU_GPU
inline
Float
PowerHeuristic
(
int
nf
,
Float
fPdf
,
int
ng
,
Float
gPdf
)
{
PBRT_CPU_GPU
inline
Float
PowerHeuristic
(
int
nf
,
Float
fPdf
,
int
ng
,
Float
gPdf
)
{
Float
f
=
nf
*
fPdf
,
g
=
ng
*
gPdf
;
return
(
f
*
f
)
/
(
f
*
f
+
g
*
g
);
}
...
...
@@ -722,30 +691,28 @@ class PiecewiseConstant1D {
PBRT_CPU_GPU
Float
Integral
()
const
{
return
funcInt
;
}
PBRT_CPU_GPU
size_t
size
()
const
{
return
func
.
size
();
}
PBRT_CPU_GPU
Float
Sample
(
Float
u
,
Float
*
pdf
=
nullptr
,
int
*
off
=
nullptr
)
const
{
Float
Sample
(
Float
u
,
Float
*
pdf
=
nullptr
,
int
*
off
set
=
nullptr
)
const
{
// Find surrounding CDF segments and _offset_
int
offset
=
FindInterval
((
int
)
cdf
.
size
(),
[
&
](
int
index
)
{
return
cdf
[
index
]
<=
u
;
});
if
(
off
)
*
off
=
offset
;
int
o
=
FindInterval
((
int
)
cdf
.
size
(),
[
&
](
int
index
)
{
return
cdf
[
index
]
<=
u
;
});
if
(
offset
)
*
offset
=
o
;
// Compute offset along CDF segment
Float
du
=
u
-
cdf
[
o
ffset
];
if
(
cdf
[
o
ffset
+
1
]
-
cdf
[
offset
]
>
0
)
du
/=
cdf
[
o
ffset
+
1
]
-
cdf
[
offset
];
Float
du
=
u
-
cdf
[
o
];
if
(
cdf
[
o
+
1
]
-
cdf
[
o
]
>
0
)
du
/=
cdf
[
o
+
1
]
-
cdf
[
o
];
DCHECK
(
!
IsNaN
(
du
));
// Compute PDF for sampled offset
if
(
pdf
!=
nullptr
)
*
pdf
=
(
funcInt
>
0
)
?
func
[
o
ffset
]
/
funcInt
:
0
;
*
pdf
=
(
funcInt
>
0
)
?
func
[
o
]
/
funcInt
:
0
;
// Return $x$ corresponding to sample
return
Lerp
((
o
ffset
+
du
)
/
size
(),
min
,
max
);
return
Lerp
((
o
+
du
)
/
size
(),
min
,
max
);
}
PBRT_CPU_GPU
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录