Skip to content

Commit

Permalink
Fix volume+surface scene rendering, fix transform issues for light & …
Browse files Browse the repository at this point in the history
…volume sampling, other fixes (#44)

* fix transform scaling in direct light sampling
* fix nextRayQueue should use current wavefront depth
* render to screen in RGBA8
* fix surface do not have medium inside a medium
* update banner
  • Loading branch information
cuteday authored Nov 9, 2023
1 parent 75762e6 commit 9068f5b
Show file tree
Hide file tree
Showing 28 changed files with 175 additions and 121 deletions.
18 changes: 14 additions & 4 deletions common/configs/example_smoke.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"environment": "$sky.exr",
"model": "common/assets/scenes/smoke/smoke.vdb",
"passes": [
"passes": [
{
"enable": true,
"name": "WavefrontPathTracer",
Expand All @@ -24,7 +22,7 @@
"enable": true,
"name": "ToneMappingPass",
"params": {
"exposure": 0.5,
"exposure": 2,
"operator": "aces"
}
}
Expand All @@ -34,6 +32,18 @@
750
],
"scene": {
"model": [
{
"model": "common/assets/scenes/smoke/smoke.vdb",
"name": "Smoke",
"params": {
"g": 0,
"sigma_a": [1, 0.5, 0.8],
"sigma_s": [0.8, 0.9, 0.8]
}
}
],
"environment": "$sky.exr",
"camera": {
"mData": {
"aspectRatio": 1.093298316001892,
Expand Down
117 changes: 63 additions & 54 deletions common/configs/example_volbox.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
{
"resolution": [
750,
750
],
"passes": [
"passes": [
{
"enable": true,
"name": "WavefrontPathTracer",
"params": {
"nee": true,
"nee": false,
"rr": 0.8,
"max_depth": 10
}
Expand All @@ -29,55 +25,68 @@
"enable": true,
"name": "ToneMappingPass",
"params": {
"exposure": 1,
"exposure": 5,
"operator": "aces"
}
}
],
"scene": {
"model": [
{
"model": "common/assets/scenes/cbox/cbox.obj"
},
{
"model": "common/assets/scenes/smoke/smoke.vdb"
}
],
"camera": {
"mData": {
"aspectRatio": 1.0,
"focalDistance": 10.0,
"focalLength": 21.0,
"lensRadius": 0.0,
"pos": [
-0.010055910795927048,
1.0200917720794678,
2.828592300415039
],
"target": [
-0.011140584014356136,
1.0211291313171387,
-0.2837386131286621
],
"up": [
0.0,
1.0,
0.0
]
}
},
"cameraController": {
"mData": {
"pitch": 0.0003333091735839844,
"radius": 3.1123313903808594,
"target": [
-0.011140584014356136,
1.0211291313171387,
-0.2837386131286621
],
"yaw": 0.000348508358001709
}
}
},
"spp": 0
],
"resolution": [
750,
750
],
"scene": {
"camera": {
"mData": {
"aspectRatio": 1.0,
"focalDistance": 10.0,
"focalLength": 21.0,
"lensRadius": 0.0,
"pos": [
-0.10795403271913528,
40.9928092956543,
111.58308410644531
],
"target": [
-0.14693589508533478,
41.03009033203125,
-0.27035611867904663
],
"up": [
0.0,
1.0,
0.0
]
}
},
"cameraController": {
"mData": {
"pitch": 0.0003333091735839844,
"radius": 111.85345458984375,
"target": [
-0.14693589508533478,
41.03009033203125,
-0.27035611867904663
],
"yaw": 0.000348508358001709
}
},
"model": [
{
"model": "common/assets/scenes/cbox/cbox.obj",
"name": "Cornell Box",
"scale": [40, 40, 40]
},
{
"model": "common/assets/scenes/smoke/smoke.vdb",
"name": "Smoke",
"params": {
"g": 0,
"sigma_a": [1, 0.5, 0.8],
"sigma_s": [0.8, 0.9, 0.8]
},
"scale": [1, 1, 1],
"translate": [0, 5, 0]
}
]
}
}
Binary file removed common/demo/kirara.jpg
Binary file not shown.
Binary file added common/demo/kirara.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/core/math/include/krrmath/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,17 @@ class Array : public Eigen::Array<T, Size, 1> {
ss << "[" << *this << "]";
return std::regex_replace(ss.str(), std::regex("\n"), ", ");
}

#ifdef KRR_MATH_JSON
friend void to_json(json &j, const Array<T, Size> &v) {
for (int i = 0; i < Size; i++) j.push_back(v[i]);
}

friend void from_json(const json &j, Array<T, Size> &v) {
assert(j.size() == Size);
for (int i = 0; i < Size; i++) v[i] = (T) j.at(i);
}
#endif
};

template <typename T>
Expand Down
16 changes: 9 additions & 7 deletions src/core/shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ class Triangle{

KRR_CALLABLE float area()const {
rt::MeshData *mesh = instance->mesh;
const Affine3f &transform = instance->transform;
Vector3i v = mesh->indices[primId];
Vector3f p0 = mesh->positions[v[0]], p1 = mesh->positions[v[1]],
p2 = mesh->positions[v[2]];
/* Remember to transform the vertices, in case that the meshes are scaled */
Vector3f p0 = transform * mesh->positions[v[0]],
p1 = transform * mesh->positions[v[1]],
p2 = transform * mesh->positions[v[2]];
float s = 0.5f * length(cross(p1 - p0, p2 - p0));
DCHECK(s > 0);
return s;
Expand All @@ -44,9 +47,8 @@ class Triangle{
p1 = transform * mesh->positions[v[1]],
p2 = transform * mesh->positions[v[2]];

return utils::sphericalTriangleArea(normalize(p0 - p),
normalize(p1 - p),
normalize(p2 - p));
return utils::sphericalTriangleArea(normalize(p0 - p), normalize(p1 - p),
normalize(p2 - p));
}

KRR_CALLABLE ShapeSample sample(Vector2f u) const {
Expand Down Expand Up @@ -77,13 +79,13 @@ class Triangle{

// transform to world space [TODO: refactor]
p = instance->getTransform() * p;
n = instance->getTransposedInverseTransform() * n;
n = (instance->getTransposedInverseTransform() * n).normalized();
ss.intr = Interaction(p, n, uvSample);
ss.pdf = 1 / area();
return ss;
}

// TODO: Direct sampling on the projeced area to the sphere.
// TODO: Direct sampling on the projected area to the sphere.
KRR_CALLABLE ShapeSample sample(Vector2f u, const ShapeSampleContext &ctx) const {
// sample w.r.t. the reference point,
// also the pdf counted is in solid angle.
Expand Down
2 changes: 1 addition & 1 deletion src/core/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ struct DeviceCreationParameters {
uint32_t backBufferHeight = 720;
uint32_t refreshRate = 0;
uint32_t swapChainBufferCount = 2;
nvrhi::Format swapChainFormat = nvrhi::Format::SRGBA8_UNORM;
nvrhi::Format swapChainFormat = nvrhi::Format::RGBA8_UNORM; // not srgb, since we render in linear HDR.
nvrhi::Format renderFormat = nvrhi::Format::RGBA32_FLOAT;
uint32_t swapChainSampleCount = 1;
uint32_t swapChainSampleQuality = 0;
Expand Down
1 change: 0 additions & 1 deletion src/main/renderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class RenderApp : public DeviceManager{
void loadConfig(const json config);

private:
int mSpp{ 0 }; // Samples needed tobe rendered, 0 means unlimited.
Scene::SharedPtr mScene;
UIRenderer::SharedPtr mpUIRenderer;
ProfilerUI::UniquePtr mProfilerUI;
Expand Down
1 change: 1 addition & 0 deletions src/misc/render/ppg/device.cu
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extern "C" __global__ void KRR_RT_CH(Closest)() {
RayWorkItem r = getRayWorkItem();
int pixelId = launchParams.currentRayQueue->pixelId[getRayId()];
SampledWavelengths lambda = launchParams.pixelState->lambda[pixelId];
intr.medium = r.ray.medium; // if this surface is inside a medium
prepareSurfaceInteraction(intr, hitInfo, lambda);
if (launchParams.mediumSampleQueue && r.ray.medium) {
launchParams.mediumSampleQueue->push(r, intr, optixGetRayTmax());
Expand Down
6 changes: 3 additions & 3 deletions src/misc/render/ppg/integrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ void PPGPathTracer::handleIntersections() {
});
}

void PPGPathTracer::generateScatterRays() {
void PPGPathTracer::generateScatterRays(int depth) {
PROFILE("Generate scatter rays");
ForAllQueued(guidedRayQueue, maxQueueSize,
KRR_DEVICE_LAMBDA(const GuidedRayWorkItem &id) {
Expand Down Expand Up @@ -210,7 +210,7 @@ void PPGPathTracer::generateScatterRays() {
r.depth = w.depth + 1;
r.thp = w.thp * sample.f * fabs(sample.wi[2]) / sample.pdf;
if (any(r.thp)) {
nextRayQueue(w.depth)->push(r);
nextRayQueue(depth)->push(r);
/* guidance... */
if (r.depth <= MAX_TRAIN_DEPTH) {
guidedPathState->incrementDepth(r.pixelId, r.ray, dTree, dTreeVoxelSize,
Expand Down Expand Up @@ -255,7 +255,7 @@ void PPGPathTracer::render(RenderContext *context) {
handleIntersections();
if (enableNEE) traceShadow();
// [STEP#2.4] towards next bounce
generateScatterRays();
generateScatterRays(depth);
}
}
// write results of the current frame...
Expand Down
2 changes: 1 addition & 1 deletion src/misc/render/ppg/integrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class PPGPathTracer : public WavefrontPathTracer{
void handleHit();
void handleMiss();
void handleIntersections();
void generateScatterRays();
void generateScatterRays(int depth);
void traceClosest(int depth);
void traceShadow();

Expand Down
1 change: 1 addition & 0 deletions src/misc/render/zero_guiding/device.cu
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ extern "C" __global__ void KRR_RT_CH(Closest)() {
RayWorkItem r = getRayWorkItem();
int pixelId = launchParams.currentRayQueue->pixelId[getRayId()];
SampledWavelengths lambda = launchParams.pixelState->lambda[pixelId];
intr.medium = r.ray.medium; // if this surface is inside a medium
prepareSurfaceInteraction(intr, hitInfo, lambda);
if (launchParams.mediumSampleQueue && r.ray.medium) {
launchParams.mediumSampleQueue->push(r, intr, optixGetRayTmax());
Expand Down
6 changes: 3 additions & 3 deletions src/misc/render/zero_guiding/integrator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ void ZeroGuidingPT::handleIntersections() {
});
}

void ZeroGuidingPT::generateScatterRays() {
void ZeroGuidingPT::generateScatterRays(int depth) {
PROFILE("Generate scatter rays");
ForAllQueued(guidedRayQueue, maxQueueSize,
KRR_DEVICE_LAMBDA(const GuidedRayWorkItem &id) {
Expand Down Expand Up @@ -209,7 +209,7 @@ void ZeroGuidingPT::generateScatterRays() {
r.depth = w.depth + 1;
r.thp = w.thp * sample.f * fabs(sample.wi[2]) / sample.pdf;
if (any(r.thp)) {
nextRayQueue(w.depth)->push(r);
nextRayQueue(depth)->push(r);
/* guidance... */
if (r.depth <= MAX_TRAIN_DEPTH) {
guidedPathState->incrementDepth(r.pixelId, r.ray, dTree, dTreeVoxelSize,
Expand Down Expand Up @@ -258,7 +258,7 @@ void ZeroGuidingPT::render(RenderContext *context) {
handleIntersections();
if (enableNEE) traceShadow();
// [STEP#2.4] towards next bounce
generateScatterRays();
generateScatterRays(depth);
}
}
// write results of the current frame...
Expand Down
2 changes: 1 addition & 1 deletion src/misc/render/zero_guiding/integrator.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class ZeroGuidingPT : public WavefrontPathTracer{
void handleHit();
void handleMiss();
void handleIntersections();
void generateScatterRays();
void generateScatterRays(int depth);
void sampleMediumInteraction(int depth);
void sampleMediumScattering(int depth);
void traceClosest(int depth);
Expand Down
1 change: 1 addition & 0 deletions src/render/path/device.cu
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ extern "C" __global__ void KRR_RT_CH(Radiance)(){
HitInfo hitInfo = getHitInfo();
PathData *path = getPRD<PathData>();
SurfaceInteraction &intr = path->intr;
intr.medium = path->ray.medium; // if this surface is inside a medium
prepareSurfaceInteraction(intr, hitInfo, path->lambda);
}

Expand Down
22 changes: 11 additions & 11 deletions src/render/path/path.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ struct LaunchParamsPT {
};

struct PathData {
Spectrum L{}; // total contribution to the current pixel
Spectrum throughput; // maintain the throughput of path
float pdf; // BxDF sampling pdf from last scatter
int depth; // number of vertices along the path
BSDFType bsdfType; // the sampled type of the last scatter event
Sampler sampler; // rng
SampledWavelengths lambda; // sampled wavelength
LightSampler lightSampler; // randomly choosing a light source
LightSampleContext ctx; // *last* context used for direct light sampling
SurfaceInteraction intr; // surface interaction of the *current* hit
Ray ray; // The last scattered ray
Spectrum L{}; // total contribution to the current pixel
Spectrum throughput; // maintain the throughput of path
float pdf; // BxDF sampling pdf from last scatter
int depth; // number of vertices along the path
BSDFType bsdfType; // the sampled type of the last scatter event
Sampler sampler; // rng
SampledWavelengths lambda; // sampled wavelength
LightSampler lightSampler; // randomly choosing a light source
LightSampleContext ctx; // *last* context used for direct light sampling
SurfaceInteraction intr; // surface interaction of the *current* hit
Ray ray; // The last scattered ray
};

KRR_NAMESPACE_END
10 changes: 5 additions & 5 deletions src/render/shading.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ KRR_DEVICE_FUNCTION void prepareSurfaceInteraction(SurfaceInteraction &intr, con
// transform local interaction to world space
// [TODO: refactor this, maybe via an integrated SurfaceInteraction struct]
intr.p = hitInfo.instance->getTransform() * intr.p;
intr.n = hitInfo.instance->getTransposedInverseTransform() * intr.n;
intr.tangent = hitInfo.instance->getTransposedInverseTransform() * intr.tangent;
intr.bitangent = hitInfo.instance->getTransposedInverseTransform() * intr.bitangent;
intr.n = (hitInfo.instance->getTransposedInverseTransform() * intr.n).normalized();
intr.tangent = (hitInfo.instance->getTransposedInverseTransform() * intr.tangent).normalized();
intr.bitangent = (hitInfo.instance->getTransposedInverseTransform() * intr.bitangent).normalized();

/* Safely return here since below are all material-related operations. */
if (intr.material == nullptr) return;
Expand Down Expand Up @@ -174,8 +174,8 @@ KRR_DEVICE_FUNCTION void prepareSurfaceInteraction(SurfaceInteraction &intr, con
} else if (material.mShadingModel == Material::ShadingModel::SpecularGlossiness) {
// [SPECULAR] RGB - Specular RGB; A - Glossiness
diffuse = baseColor;
specular = (RGB) spec; // specular reflectance
intr.sd.roughness = 1.f - spec[3]; //
specular = (RGB) spec;
intr.sd.roughness = 1.f - spec[3];
intr.sd.metallic = getMetallic(diffuse, specular);
} else assert(false);
intr.sd.diffuse = Spectrum::fromRGB(diffuse, SpectrumType::RGBBounded, lambda, colorSpace);
Expand Down
Loading

0 comments on commit 9068f5b

Please sign in to comment.