Skip to content

Commit

Permalink
Fixed environment sampling issue
Browse files Browse the repository at this point in the history
  • Loading branch information
PearCoding committed Sep 8, 2020
1 parent e9c479a commit e1a371f
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 33 deletions.
25 changes: 25 additions & 0 deletions .vscode/launch.json
Expand Up @@ -125,6 +125,31 @@
}
]
},
{
"name": "SpectralTest",
"type": "cppdbg",
"request": "launch",
"program": "${command:cmake.buildDirectory}/bin/pearray",
"args": [
"-i",
"${workspaceFolder}/examples/spectral_test.prc",
"-v",
"-p"
],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/build",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"targetArchitecture": "x64",
"setupCommands": [
{
"description": "Automatische Strukturierung und Einrückung für \"gdb\" aktivieren",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
},
{
"name": "CornellBox-Water",
"type": "cppdbg",
Expand Down
4 changes: 2 additions & 2 deletions examples/spectral_test.prc
Expand Up @@ -8,9 +8,9 @@
; Settings
(integrator
:type 'DIRECT'
:max_ray_depth 2
:max_ray_depth 1
:light_sampe_count 1
:msi true
:msi false
)
(sampler
:slot 'aa'
Expand Down
9 changes: 8 additions & 1 deletion src/base/math/Tangent.h
Expand Up @@ -56,7 +56,7 @@ inline void frame_duff(const Vector3f& N, Vector3f& Nx, Vector3f& Ny)
Ny = Vector3f(b, sign + N(1) * N(1) * a, -N(1));
}

inline void frame(const Vector3f& N, Vector3f& Nx, Vector3f& Ny)
inline void unnormalized_frame(const Vector3f& N, Vector3f& Nx, Vector3f& Ny)
{
#ifdef PR_USE_ORTHOGONAL_FRAME_FRISVAD
return frame_frisvad(N, Nx, Ny);
Expand All @@ -65,6 +65,13 @@ inline void frame(const Vector3f& N, Vector3f& Nx, Vector3f& Ny)
#endif
}

inline void frame(const Vector3f& N, Vector3f& Nx, Vector3f& Ny)
{
unnormalized_frame(N, Nx, Ny);
Nx.normalize();
Ny.normalize();
}

inline void invert_frame(Vector3f& N, Vector3f& Nx, Vector3f& Ny)
{
N = -N;
Expand Down
1 change: 1 addition & 0 deletions src/base/math/Transform.h
Expand Up @@ -21,6 +21,7 @@ inline Vector3f safePosition(const Vector3f& pos,
offset = -offset;
Vector3f posOff = pos + offset;

PR_OPT_LOOP
for (int i = 0; i < 3; ++i) {
if (offset[i] > 0)
posOff[i] = nextFloatUp(posOff[i]);
Expand Down
5 changes: 1 addition & 4 deletions src/plugins/main/entities/cone.cpp
Expand Up @@ -181,11 +181,8 @@ class ConeEntity : public IEntity {
}
}

Tangent::frame(pt.N, pt.Nx, pt.Ny);

pt.N.normalize();
pt.Nx.normalize();
pt.Ny.normalize();
Tangent::frame(pt.N, pt.Nx, pt.Ny);

pt.EntityID = id();
pt.PrimitiveID = query.PrimitiveID;
Expand Down
7 changes: 1 addition & 6 deletions src/plugins/main/entities/disk.cpp
Expand Up @@ -97,14 +97,9 @@ class DiskEntity : public IEntity {
{
PR_PROFILE_THIS;

pt.N = normalMatrix() * mDisk.normal();

pt.N = (normalMatrix() * mDisk.normal()).normalized();
Tangent::frame(pt.N, pt.Nx, pt.Ny);

pt.N.normalize();
pt.Nx.normalize();
pt.Ny.normalize();

pt.UV = query.UV;
pt.EntityID = id();
pt.PrimitiveID = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/main/entities/mesh.cpp
Expand Up @@ -175,7 +175,7 @@ class MeshEntity : public IEntity {
Face face = mMesh->base()->getFace(query.PrimitiveID);
pt.N = face.interpolateNormals(query.UV);

Tangent::frame(pt.N, pt.Nx, pt.Ny);
Tangent::unnormalized_frame(pt.N, pt.Nx, pt.Ny);
pt.UV = query.UV;

pt.MaterialID = face.MaterialSlot < mMaterials.size() ? mMaterials.at(face.MaterialSlot) : PR_INVALID_ID;
Expand Down
3 changes: 0 additions & 3 deletions src/plugins/main/entities/quadric.cpp
Expand Up @@ -143,9 +143,6 @@ class QuadricEntity : public IEntity {

Tangent::frame(pt.N, pt.Nx, pt.Ny);

pt.Nx.normalize();
pt.Ny.normalize();

pt.UVW = parameter.cwiseAbs();
if (pt.UVW(2) < PR_EPSILON) {
pt.UVW(0) /= pt.UVW(2);
Expand Down
1 change: 1 addition & 0 deletions src/plugins/main/entities/sphere.cpp
Expand Up @@ -142,6 +142,7 @@ class SphereEntity : public IEntity {
pt.N.normalize();

Tangent::frame(pt.N, pt.Nx, pt.Ny);

const Vector2f uv = Spherical::uv_from_normal(pt.N);
pt.UV = uv;
pt.EntityID = id();
Expand Down
19 changes: 9 additions & 10 deletions src/plugins/main/infinitelights/environment.cpp
Expand Up @@ -38,9 +38,7 @@ class EnvironmentLight : public IInfiniteLight {
const RenderTileSession&) const override
{
ShadingContext ctx;
Vector3f dir = mInvTransform * in.Ray.Direction;

ctx.UV = Spherical::uv_from_normal(dir);
ctx.UV = Spherical::uv_from_normal(mInvTransform * in.Ray.Direction);
ctx.WavelengthNM = in.Ray.WavelengthNM;

if constexpr (UseSplit) {
Expand All @@ -58,7 +56,7 @@ class EnvironmentLight : public IInfiniteLight {
const float denom = 2 * PR_PI * PR_PI * sinTheta;
out.PDF_S *= (denom <= PR_EPSILON) ? 0.0f : 1.0f / denom;
} else {
out.PDF_S = in.Point ? Sampling::cos_hemi_pdf(std::abs(in.Point->Surface.N.dot(dir))) : 1.0f;
out.PDF_S = in.Point ? Sampling::cos_hemi_pdf(std::abs(in.Point->Surface.N.dot(in.Ray.Direction))) : 1.0f;
}
}

Expand All @@ -68,16 +66,18 @@ class EnvironmentLight : public IInfiniteLight {
Vector2f uv;
if constexpr (UseDistribution) {
uv = mDistribution->sampleContinuous(in.RND, out.PDF_S);
out.Outgoing = Spherical::cartesian_from_uv(uv(0), uv(1));
out.Outgoing = mTransform * Spherical::cartesian_from_uv(uv(0), uv(1));

const float sinTheta = std::sin(uv(1) * PR_PI);
const float denom = 2 * PR_PI * PR_PI * sinTheta;
out.PDF_S *= (denom <= PR_EPSILON) ? 0.0f : 1 / denom;
} else {
uv = in.RND;
out.Outgoing = Sampling::cos_hemi(in.RND[0], in.RND[1], out.PDF_S);
out.Outgoing = Sampling::cos_hemi(in.RND[0], in.RND[1]);
out.PDF_S = Sampling::cos_hemi_pdf(out.Outgoing(2));
}
out.Outgoing = mTransform * Tangent::fromTangentSpace(in.Point.Surface.N, in.Point.Surface.Nx, in.Point.Surface.Ny, out.Outgoing);

out.Outgoing = Tangent::fromTangentSpace(in.Point.Surface.N, in.Point.Surface.Nx, in.Point.Surface.Ny, out.Outgoing);

ShadingContext coord;
coord.UV = uv;
Expand All @@ -93,11 +93,10 @@ class EnvironmentLight : public IInfiniteLight {
<< " <EnvironmentLight>:" << std::endl
<< " Radiance: " << (mRadiance ? mRadiance->dumpInformation() : "NONE") << std::endl
<< " Background: " << (mBackground ? mBackground->dumpInformation() : "NONE") << std::endl;
if (mDistribution) {
if (mDistribution)
stream << " Distribution: " << mDistribution->width() << "x" << mDistribution->height() << std::endl;
} else {
else
stream << " Distribution: NONE" << std::endl;
};

return stream.str();
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/main/materials/lambert.cpp
Expand Up @@ -40,8 +40,8 @@ class LambertMaterial : public IMaterial {
out.L = Sampling::cos_hemi(in.RND[0], in.RND[1]);

out.Weight = mAlbedo->eval(in.ShadingContext) * out.L(2) * PR_INV_PI;
out.Type = MST_DiffuseReflection;
out.PDF_S = Sampling::cos_hemi_pdf(out.L(2));
out.Type = MST_DiffuseReflection;
}

std::string dumpInformation() const override
Expand Down
10 changes: 5 additions & 5 deletions src/tests/tangent.cpp
Expand Up @@ -9,7 +9,7 @@ PR_TEST("Frame 1")
auto N = Vector3f(0, 0, 1);

Vector3f Nx, Ny;
Tangent::frame(N, Nx, Ny);
Tangent::unnormalized_frame(N, Nx, Ny);

PR_CHECK_NEARLY_EQ(Nx, Vector3f(1, 0, 0));
PR_CHECK_NEARLY_EQ(Ny, Vector3f(0, 1, 0));
Expand All @@ -19,7 +19,7 @@ PR_TEST("Frame 2")
auto N = Vector3f(0, 1, 0);

Vector3f Nx, Ny;
Tangent::frame(N, Nx, Ny);
Tangent::unnormalized_frame(N, Nx, Ny);

PR_CHECK_NEARLY_EQ(Nx, Vector3f(1, 0, 0));
PR_CHECK_NEARLY_EQ(Ny, Vector3f(0, 0, -1));
Expand All @@ -29,7 +29,7 @@ PR_TEST("Frame Perpendicular")
auto N = Vector3f(0, 1, 0);

Vector3f Nx, Ny;
Tangent::frame(N, Nx, Ny);
Tangent::unnormalized_frame(N, Nx, Ny);

PR_CHECK_NEARLY_EQ(Nx.dot(N), 0);
PR_CHECK_NEARLY_EQ(Ny.dot(N), 0);
Expand Down Expand Up @@ -168,7 +168,7 @@ PR_TEST("Space Reversibility 2")
{
auto N = Vector3f(1, 1, 0).normalized();
Vector3f Nx, Ny;
Tangent::frame(N, Nx, Ny);
Tangent::unnormalized_frame(N, Nx, Ny);

auto V = Vector3f(0, 1, 0);

Expand All @@ -195,7 +195,7 @@ PR_TEST("Space Reversibility 4")
{
auto N = Vector3f(1, 1, 0).normalized();
Vector3f Nx, Ny;
Tangent::frame(N, Nx, Ny);
Tangent::unnormalized_frame(N, Nx, Ny);

auto V = Vector3f(0, 1, 0);

Expand Down

0 comments on commit e1a371f

Please sign in to comment.