Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
imjiangjun
pbrt-v4
提交
6dd33255
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,发现更多精彩内容 >>
提交
6dd33255
编写于
5月 21, 2021
作者:
M
Matt Pharr
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Update from book source. No functional changes.
上级
282a5cb4
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
161 addition
and
152 deletion
+161
-152
src/pbrt/gpu/optix.cu
src/pbrt/gpu/optix.cu
+1
-2
src/pbrt/textures.h
src/pbrt/textures.h
+22
-20
src/pbrt/wavefront/aggregate.cpp
src/pbrt/wavefront/aggregate.cpp
+6
-12
src/pbrt/wavefront/film.cpp
src/pbrt/wavefront/film.cpp
+2
-0
src/pbrt/wavefront/integrator.cpp
src/pbrt/wavefront/integrator.cpp
+4
-3
src/pbrt/wavefront/integrator.h
src/pbrt/wavefront/integrator.h
+3
-13
src/pbrt/wavefront/intersect.h
src/pbrt/wavefront/intersect.h
+27
-25
src/pbrt/wavefront/media.cpp
src/pbrt/wavefront/media.cpp
+35
-17
src/pbrt/wavefront/subsurface.cpp
src/pbrt/wavefront/subsurface.cpp
+11
-8
src/pbrt/wavefront/surfscatter.cpp
src/pbrt/wavefront/surfscatter.cpp
+36
-29
src/pbrt/wavefront/workitems.h
src/pbrt/wavefront/workitems.h
+10
-19
src/pbrt/wavefront/workitems.soa
src/pbrt/wavefront/workitems.soa
+4
-4
未找到文件。
src/pbrt/gpu/optix.cu
浏览文件 @
6dd33255
...
...
@@ -145,8 +145,7 @@ static __forceinline__ __device__ void ProcessClosestIntersection(
EnqueueWorkAfterIntersection
(
r
,
rayMedium
,
optixGetRayTmax
(),
intr
,
params
.
mediumSampleQueue
,
params
.
nextRayQueue
,
params
.
hitAreaLightQueue
,
params
.
basicEvalMaterialQueue
,
params
.
universalEvalMaterialQueue
,
getPayload
<
ClosestHitContext
>
()
->
mediumInterface
);
params
.
universalEvalMaterialQueue
);
}
static
__forceinline__
__device__
Transform
getWorldFromInstance
()
{
...
...
src/pbrt/textures.h
浏览文件 @
6dd33255
...
...
@@ -1108,27 +1108,31 @@ class BasicTextureEvaluator {
PBRT_CPU_GPU
bool
CanEvaluate
(
std
::
initializer_list
<
FloatTexture
>
ftex
,
std
::
initializer_list
<
SpectrumTexture
>
stex
)
const
{
for
(
auto
f
:
ftex
)
// Return _false_ if any _FloatTexture_s cannot be evaluated
for
(
FloatTexture
f
:
ftex
)
if
(
f
&&
!
f
.
Is
<
FloatConstantTexture
>
()
&&
!
f
.
Is
<
FloatImageTexture
>
()
&&
!
f
.
Is
<
GPUFloatPtexTexture
>
()
&&
!
f
.
Is
<
GPUFloatImageTexture
>
())
return
false
;
for
(
auto
s
:
stex
)
// Return _false_ if any _SpectrumTexture_s cannot be evaluated
for
(
SpectrumTexture
s
:
stex
)
if
(
s
&&
!
s
.
Is
<
SpectrumConstantTexture
>
()
&&
!
s
.
Is
<
SpectrumImageTexture
>
()
&&
!
s
.
Is
<
GPUSpectrumPtexTexture
>
()
&&
!
s
.
Is
<
GPUSpectrumImageTexture
>
())
return
false
;
return
true
;
}
PBRT_CPU_GPU
Float
operator
()(
FloatTexture
tex
,
TextureEvalContext
ctx
)
{
if
(
FloatConstantTexture
*
fcTex
=
tex
.
CastOrNullptr
<
FloatConstantTexture
>
())
return
fcTex
->
Evaluate
(
ctx
);
else
if
(
FloatImageTexture
*
fiTex
=
tex
.
CastOrNullptr
<
FloatImageTexture
>
())
return
fiTex
->
Evaluate
(
ctx
);
else
if
(
GPUFloatImageTexture
*
gfiTex
=
tex
.
CastOrNullptr
<
GPUFloatImageTexture
>
())
return
gfiTex
->
Evaluate
(
ctx
);
else
if
(
GPUFloatPtexTexture
*
fPtex
=
tex
.
CastOrNullptr
<
GPUFloatPtexTexture
>
())
return
fPtex
->
Evaluate
(
ctx
);
if
(
tex
.
Is
<
FloatConstantTexture
>
())
return
tex
.
Cast
<
FloatConstantTexture
>
()
->
Evaluate
(
ctx
);
else
if
(
tex
.
Is
<
FloatImageTexture
>
())
return
tex
.
Cast
<
FloatImageTexture
>
()
->
Evaluate
(
ctx
);
else
if
(
tex
.
Is
<
GPUFloatImageTexture
>
())
return
tex
.
Cast
<
GPUFloatImageTexture
>
()
->
Evaluate
(
ctx
);
else
if
(
tex
.
Is
<
GPUFloatPtexTexture
>
())
return
tex
.
Cast
<
GPUFloatPtexTexture
>
()
->
Evaluate
(
ctx
);
else
{
if
(
tex
)
LOG_FATAL
(
"BasicTextureEvaluator::operator() called with %s"
,
tex
);
...
...
@@ -1139,16 +1143,14 @@ class BasicTextureEvaluator {
PBRT_CPU_GPU
SampledSpectrum
operator
()(
SpectrumTexture
tex
,
TextureEvalContext
ctx
,
SampledWavelengths
lambda
)
{
if
(
SpectrumConstantTexture
*
sc
=
tex
.
CastOrNullptr
<
SpectrumConstantTexture
>
())
return
sc
->
Evaluate
(
ctx
,
lambda
);
else
if
(
SpectrumImageTexture
*
siTex
=
tex
.
CastOrNullptr
<
SpectrumImageTexture
>
())
return
siTex
->
Evaluate
(
ctx
,
lambda
);
else
if
(
GPUSpectrumImageTexture
*
gsiTex
=
tex
.
CastOrNullptr
<
GPUSpectrumImageTexture
>
())
return
gsiTex
->
Evaluate
(
ctx
,
lambda
);
else
if
(
GPUSpectrumPtexTexture
*
sPtex
=
tex
.
CastOrNullptr
<
GPUSpectrumPtexTexture
>
())
return
sPtex
->
Evaluate
(
ctx
,
lambda
);
if
(
tex
.
Is
<
SpectrumConstantTexture
>
())
return
tex
.
Cast
<
SpectrumConstantTexture
>
()
->
Evaluate
(
ctx
,
lambda
);
else
if
(
tex
.
Is
<
SpectrumImageTexture
>
())
return
tex
.
Cast
<
SpectrumImageTexture
>
()
->
Evaluate
(
ctx
,
lambda
);
else
if
(
tex
.
Is
<
GPUSpectrumImageTexture
>
())
return
tex
.
Cast
<
GPUSpectrumImageTexture
>
()
->
Evaluate
(
ctx
,
lambda
);
else
if
(
tex
.
Is
<
GPUSpectrumPtexTexture
>
())
return
tex
.
Cast
<
GPUSpectrumPtexTexture
>
()
->
Evaluate
(
ctx
,
lambda
);
else
{
if
(
tex
)
LOG_FATAL
(
"BasicTextureEvaluator::operator() called with %s"
,
tex
);
...
...
src/pbrt/wavefront/aggregate.cpp
浏览文件 @
6dd33255
...
...
@@ -42,26 +42,20 @@ void CPUAggregate::IntersectClosest(int maxRays, const RayQueue *rayQueue,
ParallelFor
(
0
,
rayQueue
->
Size
(),
[
=
](
int
index
)
{
const
RayWorkItem
r
=
(
*
rayQueue
)[
index
];
// Intersect _r_'s ray with the scene and enqueue resulting work
pstd
::
optional
<
ShapeIntersection
>
si
=
aggregate
.
Intersect
(
r
.
ray
,
Infinity
);
pstd
::
optional
<
ShapeIntersection
>
si
=
aggregate
.
Intersect
(
r
.
ray
);
if
(
!
si
)
EnqueueWorkAfterMiss
(
r
,
mediumSampleQueue
,
escapedRayQueue
);
else
{
// Process queued ray intersected a surface
const
SurfaceInteraction
&
intr
=
si
->
intr
;
Float
tHit
=
Distance
(
r
.
ray
.
o
,
intr
.
p
())
/
Length
(
r
.
ray
.
d
);
MediumInterface
mi
=
intr
.
mediumInterface
?
*
intr
.
mediumInterface
:
MediumInterface
(
r
.
ray
.
medium
);
else
// FIXME? Second arg r.ray.medium doesn't match OptiX path
EnqueueWorkAfterIntersection
(
r
,
r
.
ray
.
medium
,
tHit
,
si
->
intr
,
mediumSampleQueue
,
nextRayQueue
,
hitAreaLightQueue
,
basicEvalMaterialQueue
,
universalEvalMaterialQueue
,
mi
);
}
EnqueueWorkAfterIntersection
(
r
,
r
.
ray
.
medium
,
si
->
tHit
,
si
->
intr
,
mediumSampleQueue
,
nextRayQueue
,
hitAreaLightQueue
,
basicEvalMaterialQueue
,
universalEvalMaterialQueue
);
});
}
void
CPUAggregate
::
IntersectShadow
(
int
maxRays
,
ShadowRayQueue
*
shadowRayQueue
,
SOA
<
PixelSampleState
>
*
pixelSampleState
)
const
{
// Intersect shadow rays from _shadowRayQueue_ in parallel
ParallelFor
(
0
,
shadowRayQueue
->
Size
(),
[
=
](
int
index
)
{
const
ShadowRayWorkItem
w
=
(
*
shadowRayQueue
)[
index
];
bool
hit
=
aggregate
.
IntersectP
(
w
.
ray
,
w
.
tMax
);
...
...
src/pbrt/wavefront/film.cpp
浏览文件 @
6dd33255
...
...
@@ -28,9 +28,11 @@ void WavefrontPathIntegrator::UpdateFilm() {
SampledWavelengths
lambda
=
pixelSampleState
.
lambda
[
pixelIndex
];
Float
filterWeight
=
pixelSampleState
.
filterWeight
[
pixelIndex
];
if
(
initializeVisibleSurface
)
{
// Call _Film::AddSample()_ with _VisibleSurface_ for pixel sample
VisibleSurface
visibleSurface
=
pixelSampleState
.
visibleSurface
[
pixelIndex
];
film
.
AddSample
(
pPixel
,
Lw
,
lambda
,
&
visibleSurface
,
filterWeight
);
}
else
film
.
AddSample
(
pPixel
,
Lw
,
lambda
,
nullptr
,
filterWeight
);
});
...
...
src/pbrt/wavefront/integrator.cpp
浏览文件 @
6dd33255
...
...
@@ -491,7 +491,7 @@ Float WavefrontPathIntegrator::Render() {
for
(
int
sampleIndex
=
firstSampleIndex
;
sampleIndex
<
lastSampleIndex
;
++
sampleIndex
)
{
CheckCallbackScope
_
([
&
]()
{
return
StringPrintf
(
"Wavefrontrendering failed at sample %d. Debug with "
return
StringPrintf
(
"Wavefront
rendering failed at sample %d. Debug with "
"
\"
--debugstart %d
\"\n
"
,
sampleIndex
,
sampleIndex
);
});
...
...
@@ -622,11 +622,10 @@ Float WavefrontPathIntegrator::Render() {
void
WavefrontPathIntegrator
::
HandleEscapedRays
()
{
if
(
!
escapedRayQueue
)
return
;
ForAllQueued
(
"Handle escaped rays"
,
escapedRayQueue
,
maxQueueSize
,
PBRT_CPU_GPU_LAMBDA
(
const
EscapedRayWorkItem
w
)
{
//
Update pixel
radiance for escaped ray
//
Compute weighted
radiance for escaped ray
SampledSpectrum
L
(
0.
f
);
for
(
const
auto
&
light
:
*
infiniteLights
)
{
if
(
SampledSpectrum
Le
=
light
.
Le
(
Ray
(
w
.
rayo
,
w
.
rayd
),
w
.
lambda
);
Le
)
{
...
...
@@ -652,6 +651,8 @@ void WavefrontPathIntegrator::HandleEscapedRays() {
}
}
}
// Update pixel radiance if ray's radiance is non-zero
if
(
L
)
{
PBRT_DBG
(
"Added L %f %f %f %f for escaped ray pixel index %d
\n
"
,
L
[
0
],
L
[
1
],
L
[
2
],
L
[
3
],
w
.
pixelIndex
);
...
...
src/pbrt/wavefront/integrator.h
浏览文件 @
6dd33255
...
...
@@ -45,7 +45,6 @@ class WavefrontAggregate {
virtual
void
IntersectShadow
(
int
maxRays
,
ShadowRayQueue
*
shadowRayQueue
,
SOA
<
PixelSampleState
>
*
pixelSampleState
)
const
=
0
;
virtual
void
IntersectShadowTr
(
int
maxRays
,
ShadowRayQueue
*
shadowRayQueue
,
SOA
<
PixelSampleState
>
*
pixelSampleState
)
const
=
0
;
...
...
@@ -77,19 +76,10 @@ class WavefrontPathIntegrator {
void
HandleEmissiveIntersection
();
void
EvaluateMaterialsAndBSDFs
(
int
wavefrontDepth
);
template
<
typename
Mt
l
>
template
<
typename
ConcreteMateria
l
>
void
EvaluateMaterialAndBSDF
(
int
wavefrontDepth
);
template
<
typename
Mtl
,
typename
TextureEvaluator
>
void
EvaluateMaterialAndBSDF
(
TextureEvaluator
texEval
,
MaterialEvalQueue
*
evalQueue
,
int
wavefrontDepth
);
void
SampleDirect
(
int
wavefrontDepth
);
template
<
typename
BxDF
>
void
SampleDirect
(
int
wavefrontDepth
);
void
SampleIndirect
(
int
wavefrontDepth
);
template
<
typename
BxDF
>
void
SampleIndirect
(
int
wavefrontDepth
);
template
<
typename
ConcreteMaterial
,
typename
TextureEvaluator
>
void
EvaluateMaterialAndBSDF
(
MaterialEvalQueue
*
evalQueue
,
int
wavefrontDepth
);
void
UpdateFilm
();
...
...
src/pbrt/wavefront/intersect.h
浏览文件 @
6dd33255
...
...
@@ -28,11 +28,32 @@ inline PBRT_CPU_GPU void EnqueueWorkAfterMiss(RayWorkItem r,
}
}
inline
PBRT_CPU_GPU
void
RecordShadowRayIntersection
(
const
ShadowRayWorkItem
w
,
SOA
<
PixelSampleState
>
*
pixelSampleState
,
bool
foundIntersection
)
{
if
(
foundIntersection
)
{
PBRT_DBG
(
"Shadow ray was occluded
\n
"
);
return
;
}
SampledSpectrum
Ld
=
w
.
Ld
/
(
w
.
uniPathPDF
+
w
.
lightPathPDF
).
Average
();
PBRT_DBG
(
"Unoccluded shadow ray. Final Ld %f %f %f %f "
"(sr.Ld %f %f %f %f uniPathPDF %f %f %f %f lightPathPDF %f %f %f %f)
\n
"
,
Ld
[
0
],
Ld
[
1
],
Ld
[
2
],
Ld
[
3
],
w
.
Ld
[
0
],
w
.
Ld
[
1
],
w
.
Ld
[
2
],
w
.
Ld
[
3
],
w
.
uniPathPDF
[
0
],
w
.
uniPathPDF
[
1
],
w
.
uniPathPDF
[
2
],
w
.
uniPathPDF
[
3
],
w
.
lightPathPDF
[
0
],
w
.
lightPathPDF
[
1
],
w
.
lightPathPDF
[
2
],
w
.
lightPathPDF
[
3
]);
SampledSpectrum
Lpixel
=
pixelSampleState
->
L
[
w
.
pixelIndex
];
pixelSampleState
->
L
[
w
.
pixelIndex
]
=
Lpixel
+
Ld
;
}
inline
PBRT_CPU_GPU
void
EnqueueWorkAfterIntersection
(
RayWorkItem
r
,
Medium
rayMedium
,
float
tMax
,
SurfaceInteraction
intr
,
MediumSampleQueue
*
mediumSampleQueue
,
RayQueue
*
nextRayQueue
,
HitAreaLightQueue
*
hitAreaLightQueue
,
MaterialEvalQueue
*
basicEvalMaterialQueue
,
MaterialEvalQueue
*
universalEvalMaterialQueue
,
MediumInterface
mediumInterface
)
{
MaterialEvalQueue
*
universalEvalMaterialQueue
)
{
MediumInterface
mediumInterface
=
intr
.
mediumInterface
?
*
intr
.
mediumInterface
:
MediumInterface
(
rayMedium
);
if
(
rayMedium
)
{
assert
(
mediumSampleQueue
);
PBRT_DBG
(
"Enqueuing into medium sample queue
\n
"
);
...
...
@@ -94,7 +115,7 @@ inline PBRT_CPU_GPU void EnqueueWorkAfterIntersection(
// TODO: intr.wo == -ray.d?
hitAreaLightQueue
->
Push
(
HitAreaLightWorkItem
{
intr
.
areaLight
,
intr
.
p
(),
intr
.
n
,
intr
.
uv
,
intr
.
wo
,
r
.
depth
,
r
.
lambda
,
r
.
T_hat
,
r
.
uniPathPDF
,
r
.
lightPathPDF
,
r
.
lambda
,
r
.
depth
,
r
.
T_hat
,
r
.
uniPathPDF
,
r
.
lightPathPDF
,
r
.
prevIntrCtx
,
(
int
)
r
.
isSpecularBounce
,
r
.
pixelIndex
});
}
...
...
@@ -115,48 +136,29 @@ inline PBRT_CPU_GPU void EnqueueWorkAfterIntersection(
intr
.
n
,
intr
.
dpdu
,
intr
.
dpdv
,
intr
.
time
,
r
.
depth
,
intr
.
shading
.
n
,
intr
.
shading
.
dpdu
,
intr
.
shading
.
dpdv
,
intr
.
shading
.
dndu
,
intr
.
shading
.
dndv
,
intr
.
uv
,
r
.
depth
,
intr
.
faceIndex
,
r
.
lambda
,
r
.
pixelIndex
,
r
.
anyNonSpecularBounces
,
intr
.
wo
,
r
.
pixelIndex
,
r
.
T_hat
,
r
.
uniPathPDF
,
r
.
etaScale
,
mediumInterface
,
intr
.
time
});
mediumInterface
});
};
material
.
Dispatch
(
enqueue
);
PBRT_DBG
(
"Closest hit found intersection at t %f
\n
"
,
tMax
);
}
inline
PBRT_CPU_GPU
void
RecordShadowRayIntersection
(
const
ShadowRayWorkItem
w
,
SOA
<
PixelSampleState
>
*
pixelSampleState
,
bool
foundIntersection
)
{
if
(
foundIntersection
)
{
PBRT_DBG
(
"Shadow ray was occluded
\n
"
);
return
;
}
SampledSpectrum
Ld
=
w
.
Ld
/
(
w
.
uniPathPDF
+
w
.
lightPathPDF
).
Average
();
PBRT_DBG
(
"Unoccluded shadow ray. Final Ld %f %f %f %f "
"(sr.Ld %f %f %f %f uniPathPDF %f %f %f %f lightPathPDF %f %f %f %f)
\n
"
,
Ld
[
0
],
Ld
[
1
],
Ld
[
2
],
Ld
[
3
],
w
.
Ld
[
0
],
w
.
Ld
[
1
],
w
.
Ld
[
2
],
w
.
Ld
[
3
],
w
.
uniPathPDF
[
0
],
w
.
uniPathPDF
[
1
],
w
.
uniPathPDF
[
2
],
w
.
uniPathPDF
[
3
],
w
.
lightPathPDF
[
0
],
w
.
lightPathPDF
[
1
],
w
.
lightPathPDF
[
2
],
w
.
lightPathPDF
[
3
]);
SampledSpectrum
Lpixel
=
pixelSampleState
->
L
[
w
.
pixelIndex
];
pixelSampleState
->
L
[
w
.
pixelIndex
]
=
Lpixel
+
Ld
;
}
struct
TransmittanceTraceResult
{
bool
hit
;
Point3f
pHit
;
...
...
src/pbrt/wavefront/media.cpp
浏览文件 @
6dd33255
...
...
@@ -189,7 +189,7 @@ void WavefrontPathIntegrator::SampleMediumInteraction(int wavefrontDepth) {
w
.
pixelIndex
,
w
.
depth
);
escapedRayQueue
->
Push
(
EscapedRayWorkItem
{
ray
.
o
,
ray
.
d
,
w
.
depth
,
lambda
,
w
.
pixelIndex
,
(
int
)
w
.
isSpecularBounce
,
T_hat
,
uniPathPDF
,
T_hat
,
(
int
)
w
.
isSpecularBounce
,
uniPathPDF
,
lightPathPDF
,
w
.
prevIntrCtx
});
}
return
;
...
...
@@ -224,7 +224,7 @@ void WavefrontPathIntegrator::SampleMediumInteraction(int wavefrontDepth) {
"depth %d
\n
"
,
w
.
pixelIndex
,
w
.
depth
);
hitAreaLightQueue
->
Push
(
HitAreaLightWorkItem
{
w
.
areaLight
,
Point3f
(
w
.
pi
),
w
.
n
,
w
.
uv
,
-
ray
.
d
,
w
.
depth
,
lambda
,
T_hat
,
w
.
areaLight
,
Point3f
(
w
.
pi
),
w
.
n
,
w
.
uv
,
-
ray
.
d
,
lambda
,
w
.
depth
,
T_hat
,
uniPathPDF
,
lightPathPDF
,
w
.
prevIntrCtx
,
w
.
isSpecularBounce
,
w
.
pixelIndex
});
}
...
...
@@ -242,15 +242,29 @@ void WavefrontPathIntegrator::SampleMediumInteraction(int wavefrontDepth) {
auto
enqueue
=
[
=
](
auto
ptr
)
{
using
Material
=
typename
std
::
remove_reference_t
<
decltype
(
*
ptr
)
>
;
q
->
Push
<
MaterialEvalWorkItem
<
Material
>>
(
MaterialEvalWorkItem
<
Material
>
{
ptr
,
w
.
pi
,
w
.
n
,
w
.
dpdu
,
w
.
dpdv
,
w
.
ns
,
w
.
dpdus
,
w
.
dpdvs
,
w
.
dndus
,
w
.
dndvs
,
w
.
uv
,
w
.
depth
,
w
.
faceIndex
,
lambda
,
w
.
anyNonSpecularBounces
,
-
ray
.
d
,
w
.
pixelIndex
,
T_hat
,
uniPathPDF
,
w
.
etaScale
,
w
.
mediumInterface
,
ray
.
time
});
q
->
Push
<
MaterialEvalWorkItem
<
Material
>>
(
MaterialEvalWorkItem
<
Material
>
{
ptr
,
w
.
pi
,
w
.
n
,
w
.
dpdu
,
w
.
dpdv
,
ray
.
time
,
w
.
depth
,
w
.
ns
,
w
.
dpdus
,
w
.
dpdvs
,
w
.
dndus
,
w
.
dndvs
,
w
.
uv
,
w
.
faceIndex
,
lambda
,
w
.
pixelIndex
,
w
.
anyNonSpecularBounces
,
-
ray
.
d
,
T_hat
,
uniPathPDF
,
w
.
etaScale
,
w
.
mediumInterface
});
};
material
.
Dispatch
(
enqueue
);
});
...
...
@@ -262,15 +276,18 @@ void WavefrontPathIntegrator::SampleMediumInteraction(int wavefrontDepth) {
PhaseFunction
::
Types
());
}
template
<
typename
Phase
>
template
<
typename
ConcretePhaseFunction
>
void
WavefrontPathIntegrator
::
SampleMediumScattering
(
int
wavefrontDepth
)
{
RayQueue
*
currentRayQueue
=
CurrentRayQueue
(
wavefrontDepth
);
RayQueue
*
nextRayQueue
=
NextRayQueue
(
wavefrontDepth
);
std
::
string
desc
=
std
::
string
(
"Sample direct/indirect - "
)
+
Phase
::
Name
();
std
::
string
desc
=
std
::
string
(
"Sample direct/indirect - "
)
+
ConcretePhaseFunction
::
Name
();
ForAllQueued
(
desc
.
c_str
(),
mediumScatterQueue
->
Get
<
MediumScatterWorkItem
<
Phase
>>
(),
maxQueueSize
,
PBRT_CPU_GPU_LAMBDA
(
const
MediumScatterWorkItem
<
Phase
>
w
)
{
desc
.
c_str
(),
mediumScatterQueue
->
Get
<
MediumScatterWorkItem
<
ConcretePhaseFunction
>>
(),
maxQueueSize
,
PBRT_CPU_GPU_LAMBDA
(
const
MediumScatterWorkItem
<
ConcretePhaseFunction
>
w
)
{
RaySamples
raySamples
=
pixelSampleState
.
samples
[
w
.
pixelIndex
];
Vector3f
wo
=
w
.
wo
;
...
...
@@ -303,8 +320,9 @@ void WavefrontPathIntegrator::SampleMediumScattering(int wavefrontDepth) {
Ray
ray
(
w
.
p
,
ls
->
pLight
.
p
()
-
w
.
p
,
w
.
time
,
w
.
medium
);
// Enqueue shadow ray
shadowRayQueue
->
Push
(
ray
,
1
-
ShadowEpsilon
,
w
.
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
);
shadowRayQueue
->
Push
(
ShadowRayWorkItem
{
ray
,
1
-
ShadowEpsilon
,
w
.
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
});
PBRT_DBG
(
"Enqueued medium shadow ray depth %d "
"Ld %f %f %f %f uniPathPDF %f %f %f %f "
...
...
src/pbrt/wavefront/subsurface.cpp
浏览文件 @
6dd33255
...
...
@@ -53,8 +53,8 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
using
BSSRDF
=
TabulatedBSSRDF
;
BSSRDF
bssrdf
=
w
.
bssrdf
;
using
BxDF
=
typename
BSSRDF
::
BxDF
;
BxDF
bxdf
;
using
Concrete
BxDF
=
typename
BSSRDF
::
BxDF
;
Concrete
BxDF
bxdf
;
SubsurfaceInteraction
&
intr
=
w
.
ssi
;
BSSRDFSample
bssrdfSample
=
bssrdf
.
ProbeIntersectionToSample
(
intr
,
&
bxdf
);
...
...
@@ -78,7 +78,8 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
Point2f
u
=
raySamples
.
indirect
.
u
;
Float
uc
=
raySamples
.
indirect
.
uc
;
pstd
::
optional
<
BSDFSample
>
bsdfSample
=
bsdf
.
Sample_f
<
BxDF
>
(
wo
,
uc
,
u
);
pstd
::
optional
<
BSDFSample
>
bsdfSample
=
bsdf
.
Sample_f
<
ConcreteBxDF
>
(
wo
,
uc
,
u
);
if
(
bsdfSample
)
{
Vector3f
wi
=
bsdfSample
->
wi
;
SampledSpectrum
T_hat
=
T_hatp
*
bsdfSample
->
f
*
AbsDot
(
wi
,
intr
.
ns
);
...
...
@@ -86,7 +87,7 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
lightPathPDF
=
uniPathPDF
;
PBRT_DBG
(
"%s f*cos[0] %f bsdfSample->pdf %f f*cos/pdf %f
\n
"
,
BxDF
::
Name
(),
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
intr
.
ns
),
Concrete
BxDF
::
Name
(),
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
intr
.
ns
),
bsdfSample
->
pdf
,
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
intr
.
ns
)
/
bsdfSample
->
pdf
);
...
...
@@ -165,7 +166,7 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
return
;
Vector3f
wi
=
ls
->
wi
;
SampledSpectrum
f
=
bsdf
.
f
<
BxDF
>
(
wo
,
wi
);
SampledSpectrum
f
=
bsdf
.
f
<
Concrete
BxDF
>
(
wo
,
wi
);
if
(
!
f
)
return
;
...
...
@@ -180,7 +181,8 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
Float
lightPDF
=
ls
->
pdf
*
sampledLight
->
pdf
;
// This causes uniPathPDF to be zero for the shadow ray, so that
// part of MIS just becomes a no-op.
Float
bsdfPDF
=
IsDeltaLight
(
light
.
Type
())
?
0.
f
:
bsdf
.
PDF
<
BxDF
>
(
wo
,
wi
);
Float
bsdfPDF
=
IsDeltaLight
(
light
.
Type
())
?
0.
f
:
bsdf
.
PDF
<
ConcreteBxDF
>
(
wo
,
wi
);
SampledSpectrum
lightPathPDF
=
uniPathPDF
*
lightPDF
;
uniPathPDF
*=
bsdfPDF
;
...
...
@@ -202,8 +204,9 @@ void WavefrontPathIntegrator::SampleSubsurface(int wavefrontDepth) {
ray
.
medium
=
Dot
(
ray
.
d
,
intr
.
n
)
>
0
?
w
.
mediumInterface
.
outside
:
w
.
mediumInterface
.
inside
;
shadowRayQueue
->
Push
(
ray
,
1
-
ShadowEpsilon
,
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
);
shadowRayQueue
->
Push
(
ShadowRayWorkItem
{
ray
,
1
-
ShadowEpsilon
,
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
});
}
});
...
...
src/pbrt/wavefront/surfscatter.cpp
浏览文件 @
6dd33255
...
...
@@ -44,10 +44,10 @@ struct EvaluateMaterialCallback {
int
wavefrontDepth
;
WavefrontPathIntegrator
*
integrator
;
// EvaluateMaterialCallback Public Methods
template
<
typename
Mt
l
>
template
<
typename
ConcreteMateria
l
>
void
operator
()()
{
if
constexpr
(
!
std
::
is_same_v
<
Mt
l
,
MixMaterial
>
)
integrator
->
EvaluateMaterialAndBSDF
<
Mt
l
>
(
wavefrontDepth
);
if
constexpr
(
!
std
::
is_same_v
<
ConcreteMateria
l
,
MixMaterial
>
)
integrator
->
EvaluateMaterialAndBSDF
<
ConcreteMateria
l
>
(
wavefrontDepth
);
}
};
...
...
@@ -56,30 +56,33 @@ void WavefrontPathIntegrator::EvaluateMaterialsAndBSDFs(int wavefrontDepth) {
ForEachType
(
EvaluateMaterialCallback
{
wavefrontDepth
,
this
},
Material
::
Types
());
}
template
<
typename
Mt
l
>
template
<
typename
ConcreteMateria
l
>
void
WavefrontPathIntegrator
::
EvaluateMaterialAndBSDF
(
int
wavefrontDepth
)
{
if
(
haveBasicEvalMaterial
[
Material
::
TypeIndex
<
Mtl
>
()])
EvaluateMaterialAndBSDF
<
Mtl
>
(
BasicTextureEvaluator
(),
basicEvalMaterialQueue
,
wavefrontDepth
);
if
(
haveUniversalEvalMaterial
[
Material
::
TypeIndex
<
Mtl
>
()])
EvaluateMaterialAndBSDF
<
Mtl
>
(
UniversalTextureEvaluator
(),
universalEvalMaterialQueue
,
wavefrontDepth
);
int
index
=
Material
::
TypeIndex
<
ConcreteMaterial
>
();
if
(
haveBasicEvalMaterial
[
index
])
EvaluateMaterialAndBSDF
<
ConcreteMaterial
,
BasicTextureEvaluator
>
(
basicEvalMaterialQueue
,
wavefrontDepth
);
if
(
haveUniversalEvalMaterial
[
index
])
EvaluateMaterialAndBSDF
<
ConcreteMaterial
,
UniversalTextureEvaluator
>
(
universalEvalMaterialQueue
,
wavefrontDepth
);
}
template
<
typename
Mtl
,
typename
TextureEvaluator
>
void
WavefrontPathIntegrator
::
EvaluateMaterialAndBSDF
(
TextureEvaluator
texEval
,
MaterialEvalQueue
*
evalQueue
,
template
<
typename
ConcreteMaterial
,
typename
TextureEvaluator
>
void
WavefrontPathIntegrator
::
EvaluateMaterialAndBSDF
(
MaterialEvalQueue
*
evalQueue
,
int
wavefrontDepth
)
{
// Get BSDF for items in _evalQueue_ and sample illumination
// Construct _name_ for material/texture evaluator kernel
std
::
string
name
=
StringPrintf
(
"%s + BxDF Eval (%s tex)"
,
Mt
l
::
Name
(),
"%s + BxDF Eval (%s tex)"
,
ConcreteMateria
l
::
Name
(),
std
::
is_same_v
<
TextureEvaluator
,
BasicTextureEvaluator
>
?
"Basic"
:
"Universal"
);
RayQueue
*
nextRayQueue
=
NextRayQueue
(
wavefrontDepth
);
auto
queue
=
evalQueue
->
Get
<
MaterialEvalWorkItem
<
ConcreteMaterial
>>
();
ForAllQueued
(
name
.
c_str
(),
evalQueue
->
Get
<
MaterialEvalWorkItem
<
Mtl
>>
()
,
maxQueueSize
,
PBRT_CPU_GPU_LAMBDA
(
const
MaterialEvalWorkItem
<
Mt
l
>
w
)
{
name
.
c_str
(),
queue
,
maxQueueSize
,
PBRT_CPU_GPU_LAMBDA
(
const
MaterialEvalWorkItem
<
ConcreteMateria
l
>
w
)
{
// Evaluate material and BSDF for ray intersection
TextureEvaluator
texEval
;
// Compute differentials for position and $(u,v)$ at intersection point
Vector3f
dpdx
,
dpdy
;
Float
dudx
=
0
,
dudy
=
0
,
dvdx
=
0
,
dvdy
=
0
;
...
...
@@ -107,7 +110,7 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
dudy
=
IsFinite
(
dudy
)
?
Clamp
(
dudy
,
-
1e8
f
,
1e8
f
)
:
0.
f
;
dvdy
=
IsFinite
(
dvdy
)
?
Clamp
(
dvdy
,
-
1e8
f
,
1e8
f
)
:
0.
f
;
//
Apply bump mapping if material has a displacement texture
//
Compute shading normal if bump or normal mapping is being used
Normal3f
ns
=
w
.
ns
;
Vector3f
dpdus
=
w
.
dpdus
;
FloatTexture
displacement
=
w
.
material
->
GetDisplacement
();
...
...
@@ -126,9 +129,10 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
SampledWavelengths
lambda
=
w
.
lambda
;
MaterialEvalContext
ctx
=
w
.
GetMaterialEvalContext
(
dudx
,
dudy
,
dvdx
,
dvdy
,
ns
,
dpdus
);
using
BxDF
=
typename
Mt
l
::
BxDF
;
BxDF
bxdf
;
using
ConcreteBxDF
=
typename
ConcreteMateria
l
::
BxDF
;
Concrete
BxDF
bxdf
;
BSDF
bsdf
=
w
.
material
->
GetBSDF
(
texEval
,
ctx
,
lambda
,
&
bxdf
);
// Handle terminated secondary wavelengths after BSDF creation
if
(
lambda
.
SecondaryTerminated
())
pixelSampleState
.
lambda
[
w
.
pixelIndex
]
=
lambda
;
...
...
@@ -173,21 +177,22 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
// Sample BSDF and enqueue indirect ray at intersection point
Vector3f
wo
=
w
.
wo
;
RaySamples
raySamples
=
pixelSampleState
.
samples
[
w
.
pixelIndex
];
pstd
::
optional
<
BSDFSample
>
bsdfSample
=
bsdf
.
Sample_f
<
BxDF
>
(
wo
,
raySamples
.
indirect
.
uc
,
raySamples
.
indirect
.
u
);
pstd
::
optional
<
BSDFSample
>
bsdfSample
=
bsdf
.
Sample_f
<
ConcreteBxDF
>
(
wo
,
raySamples
.
indirect
.
uc
,
raySamples
.
indirect
.
u
);
if
(
bsdfSample
)
{
// Compute updated path throughput and PDFs and enqueue indirect ray
Vector3f
wi
=
bsdfSample
->
wi
;
SampledSpectrum
T_hat
=
w
.
T_hat
*
bsdfSample
->
f
*
AbsDot
(
wi
,
ns
);
SampledSpectrum
uniPathPDF
=
w
.
uniPathPDF
,
lightPathPDF
=
w
.
uniPathPDF
;
PBRT_DBG
(
"%s f*cos[0] %f bsdfSample->pdf %f f*cos/pdf %f
\n
"
,
BxDF
::
Name
(),
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
ns
),
bsdfSample
->
pdf
,
PBRT_DBG
(
"%s f*cos[0] %f bsdfSample->pdf %f f*cos/pdf %f
\n
"
,
ConcreteBxDF
::
Name
(),
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
ns
),
bsdfSample
->
pdf
,
bsdfSample
->
f
[
0
]
*
AbsDot
(
wi
,
ns
)
/
bsdfSample
->
pdf
);
// Update _uniPathPDF_ based on BSDF sample PDF
if
(
bsdfSample
->
pdfIsProportional
)
{
Float
pdf
=
bsdf
.
PDF
<
BxDF
>
(
wo
,
wi
);
Float
pdf
=
bsdf
.
PDF
<
Concrete
BxDF
>
(
wo
,
wi
);
T_hat
*=
pdf
/
bsdfSample
->
pdf
;
uniPathPDF
*=
pdf
;
}
else
...
...
@@ -215,7 +220,7 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
}
if
(
T_hat
)
{
// Enqueue ray in
BSSRDF or indirect ray
queue, as appropriate
// Enqueue ray in
indirect ray queue or BSSRDF
queue, as appropriate
if
(
bsdfSample
->
IsTransmission
()
&&
w
.
material
->
HasSubsurfaceScattering
())
{
bssrdfEvalQueue
->
Push
(
w
.
material
,
lambda
,
T_hat
,
uniPathPDF
,
...
...
@@ -275,7 +280,7 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
if
(
!
ls
||
!
ls
->
L
||
ls
->
pdf
==
0
)
return
;
Vector3f
wi
=
ls
->
wi
;
SampledSpectrum
f
=
bsdf
.
f
<
BxDF
>
(
wo
,
wi
);
SampledSpectrum
f
=
bsdf
.
f
<
Concrete
BxDF
>
(
wo
,
wi
);
if
(
!
f
)
return
;
...
...
@@ -294,7 +299,8 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
Float
lightPDF
=
ls
->
pdf
*
sampledLight
->
pdf
;
// This causes uniPathPDF to be zero for the shadow ray, so that
// part of MIS just becomes a no-op.
Float
bsdfPDF
=
IsDeltaLight
(
light
.
Type
())
?
0.
f
:
bsdf
.
PDF
<
BxDF
>
(
wo
,
wi
);
Float
bsdfPDF
=
IsDeltaLight
(
light
.
Type
())
?
0.
f
:
bsdf
.
PDF
<
ConcreteBxDF
>
(
wo
,
wi
);
SampledSpectrum
uniPathPDF
=
w
.
uniPathPDF
*
bsdfPDF
;
SampledSpectrum
lightPathPDF
=
w
.
uniPathPDF
*
lightPDF
;
...
...
@@ -306,8 +312,9 @@ void WavefrontPathIntegrator::EvaluateMaterialAndBSDF(TextureEvaluator texEval,
ray
.
medium
=
Dot
(
ray
.
d
,
w
.
n
)
>
0
?
w
.
mediumInterface
.
outside
:
w
.
mediumInterface
.
inside
;
shadowRayQueue
->
Push
(
ray
,
1
-
ShadowEpsilon
,
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
);
shadowRayQueue
->
Push
(
ShadowRayWorkItem
{
ray
,
1
-
ShadowEpsilon
,
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
w
.
pixelIndex
});
PBRT_DBG
(
"w.index %d spawned shadow ray depth %d Ld %f %f %f %f "
...
...
src/pbrt/wavefront/workitems.h
浏览文件 @
6dd33255
...
...
@@ -151,8 +151,9 @@ struct EscapedRayWorkItem {
int
depth
;
SampledWavelengths
lambda
;
int
pixelIndex
;
SampledSpectrum
T_hat
;
int
specularBounce
;
SampledSpectrum
T_hat
,
uniPathPDF
,
lightPathPDF
;
SampledSpectrum
uniPathPDF
,
lightPathPDF
;
LightSampleContext
prevIntrCtx
;
};
...
...
@@ -164,8 +165,8 @@ struct HitAreaLightWorkItem {
Normal3f
n
;
Point2f
uv
;
Vector3f
wo
;
int
depth
;
SampledWavelengths
lambda
;
int
depth
;
SampledSpectrum
T_hat
,
uniPathPDF
,
lightPathPDF
;
LightSampleContext
prevIntrCtx
;
int
isSpecularBounce
;
...
...
@@ -275,7 +276,7 @@ struct MediumScatterWorkItem {
};
// MaterialEvalWorkItem Definition
template
<
typename
Material
>
template
<
typename
Concrete
Material
>
struct
MaterialEvalWorkItem
{
// MaterialEvalWorkItem Public Methods
PBRT_CPU_GPU
...
...
@@ -317,24 +318,24 @@ struct MaterialEvalWorkItem {
}
// MaterialEvalWorkItem Public Members
const
Material
*
material
;
const
Concrete
Material
*
material
;
Point3fi
pi
;
Normal3f
n
;
Vector3f
dpdu
,
dpdv
;
Float
time
;
int
depth
;
Normal3f
ns
;
Vector3f
dpdus
,
dpdvs
;
Normal3f
dndus
,
dndvs
;
Point2f
uv
;
int
depth
;
int
faceIndex
;
SampledWavelengths
lambda
;
int
pixelIndex
;
int
anyNonSpecularBounces
;
Vector3f
wo
;
int
pixelIndex
;
SampledSpectrum
T_hat
,
uniPathPDF
;
Float
etaScale
;
MediumInterface
mediumInterface
;
Float
time
;
};
#include "wavefront_workitems_soa.h"
...
...
@@ -397,17 +398,7 @@ inline int RayQueue::PushIndirectRay(
}
// ShadowRayQueue Definition
class
ShadowRayQueue
:
public
WorkQueue
<
ShadowRayWorkItem
>
{
public:
using
WorkQueue
::
WorkQueue
;
// ShadowRayQueue Public Methods
PBRT_CPU_GPU
void
Push
(
const
Ray
&
ray
,
Float
tMax
,
SampledWavelengths
lambda
,
SampledSpectrum
Ld
,
SampledSpectrum
uniPathPDF
,
SampledSpectrum
lightPathPDF
,
int
pixelIndex
)
{
WorkQueue
<
ShadowRayWorkItem
>::
Push
(
ShadowRayWorkItem
{
ray
,
tMax
,
lambda
,
Ld
,
uniPathPDF
,
lightPathPDF
,
pixelIndex
});
}
};
using
ShadowRayQueue
=
WorkQueue
<
ShadowRayWorkItem
>
;
// EscapedRayQueue Definition
class
EscapedRayQueue
:
public
WorkQueue
<
EscapedRayWorkItem
>
{
...
...
@@ -423,7 +414,7 @@ class EscapedRayQueue : public WorkQueue<EscapedRayWorkItem> {
inline
int
EscapedRayQueue
::
Push
(
RayWorkItem
r
)
{
return
Push
(
EscapedRayWorkItem
{
r
.
ray
.
o
,
r
.
ray
.
d
,
r
.
depth
,
r
.
lambda
,
r
.
pixelIndex
,
(
int
)
r
.
isSpecularBounce
,
r
.
T_hat
,
r
.
uniPathPDF
,
r
.
T_hat
,
(
int
)
r
.
isSpecularBounce
,
r
.
uniPathPDF
,
r
.
lightPathPDF
,
r
.
prevIntrCtx
});
}
...
...
src/pbrt/wavefront/workitems.soa
浏览文件 @
6dd33255
...
...
@@ -142,12 +142,12 @@ soa MediumSampleWorkItem {
MediumInterface
mediumInterface
;
};
soa
MediumScatterWorkItem
<
PhaseFunction
>
{
soa
MediumScatterWorkItem
<
Concrete
PhaseFunction
>
{
Point3f
p
;
int
depth
;
SampledWavelengths
lambda
;
SampledSpectrum
T_hat
,
uniPathPDF
;
const
PhaseFunction
*
phase
;
const
Concrete
PhaseFunction
*
phase
;
Vector3f
wo
;
Float
time
;
Float
etaScale
;
...
...
@@ -155,8 +155,8 @@ soa MediumScatterWorkItem<PhaseFunction> {
int
pixelIndex
;
};
soa
MaterialEvalWorkItem
<
Material
>
{
const
Material
*
material
;
soa
MaterialEvalWorkItem
<
Concrete
Material
>
{
const
Concrete
Material
*
material
;
SampledWavelengths
lambda
;
SampledSpectrum
T_hat
,
uniPathPDF
;
Point3fi
pi
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录