Skip to content
This repository has been archived by the owner on Mar 19, 2020. It is now read-only.

Commit

Permalink
ggx microfacet reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
椎名深雪 committed Nov 24, 2019
1 parent 8d6c005 commit e8f4d52
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 5 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ include_directories(external/cxxopts/include)
include_directories(external/gl3w/include)
include_directories(external/glfw/include)
include_directories(external/imgui/)
include_directories(external/glm)

file(GLOB MiyukiAPI src/api/*.h src/api/*.hpp src/api/detail/*.hpp src/api/detail/*.h)
file(GLOB libcoreSource src/core/*.cpp
Expand Down
4 changes: 0 additions & 4 deletions src/api/bsdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,5 @@ namespace miyuki::core {
BSDF::Type sampledType = BSDF::ENone;
};


inline Vec3f Reflect(const Vec3f &v, const Normal3f &n) {
return v - 2.0f * v.dot(n) * n;
}
}
#endif //MIYUKIRENDERER_BSDF_H
11 changes: 11 additions & 0 deletions src/api/fresnel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <api/math.hpp>
#include <api/object.hpp>

namespace miyuki::core {
class Frensel : public Object {
public:
virtual Float evaluate(const Float cosTheta) const = 0;
};
} // namespace miyuki::core
2 changes: 2 additions & 0 deletions src/api/object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ namespace miyuki {

virtual std::string toString() const;

virtual ~Object() = default;

// get a ObjectProperty from name
//virtual std::shared_ptr<Object> getProperty(const char *name);

Expand Down
74 changes: 74 additions & 0 deletions src/core/bsdfs/microfacet.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#include "microfacet.h"
#include <api/shader.h>
#include <api/trignometry.hpp>

namespace miyuki::core {
static float SchlickWeight(float cosTheta) {
float m = std::clamp(1.0 - cosTheta, 0.0, 1.0);
return (m * m) * (m * m) * m;
}
static float Schlick(float R0, float cosTheta) { return mix<float>(R0, 1.0, SchlickWeight(cosTheta)); }
static float GGX_D(float alpha, const Vec3f &m) {
if (m.y <= 0.0f)
return 0.0f;
float a2 = alpha * alpha;
float c2 = Cos2Theta(m);
float t2 = Tan2Theta(m);
float at = (a2 + t2);
return a2 / (Pi * c2 * c2 * at * at);
}
static float GGX_G1(float alpha, const Vec3f &v, const Vec3f &m) {
if (v.dot(m) * v.y <= 0.0f) {
return 0.0f;
}
return 2.0 / (1.0 + sqrt(1.0 + alpha * alpha * Tan2Theta(m)));
}
static float GGX_G(float alpha, const Vec3f &i, const Vec3f &o, const Vec3f &m) {
return GGX_G1(alpha, i, m) * GGX_G1(alpha, o, m);
}
static Vec3f GGX_SampleWh(float alpha, const Vec3f &wo, const Point2f &u) {
float phi = 2.0 * Pi * u.y;
float t2 = alpha * alpha * u.x / (1.0 - u.x);
float cosTheta = 1.0f / sqrt(1.0 + t2);
float sinTheta = sqrt(std::fmax(0.0f, 1.0 - cosTheta * cosTheta));
return Vec3f(cos(phi) * sinTheta, cosTheta, sin(phi) * sinTheta);
}
Spectrum MicrofacetBSDF::evaluate(const ShadingPoint &point, const Vec3f &wo, const Vec3f &wi) const {
if (!SameHemisphere(wo, wi)) {
return Spectrum(0);
}
float cosThetaO = AbsCosTheta(wo);
float cosThetaI = AbsCosTheta(wi);
Vec3f wh = (wo + wi);
if (cosThetaI == 0 || cosThetaO == 0)
return Spectrum(0);
if (wh.x == 0 && wh.y == 0 && wh.z == 0)
return Spectrum(0);
wh.normalize();
float F = 1.0; // Schlick(0.4f, abs(dot(wi, wh)));
auto R = color->evaluate(point);
auto alpha = roughness->evaluate(point).x;
alpha *= alpha;
return max(Spectrum(0), R * F * GGX_D(alpha, wh) * GGX_G(alpha, wo, wi, wh) / (4.0f * cosThetaI * cosThetaO));
}

void MicrofacetBSDF::sample(Point2f u, const ShadingPoint &sp, BSDFSample &sample) const {
auto alpha = roughness->evaluate(sp).x;
alpha *= alpha;
Normal3f wh = GGX_SampleWh(alpha, sample.wo, u);
sample.wi = Reflect(sample.wo, wh);
sample.f = evaluate(sp, sample.wo, sample.wi);
sample.pdf = evaluatePdf(sp, sample.wo, sample.wi);
}

Float MicrofacetBSDF::evaluatePdf(const ShadingPoint &point, const Vec3f &wo, const Vec3f &wi) const {
if (!SameHemisphere(wo, wi)) {
return 0.0f;
}
auto wh = (wo + wi).normalized();
auto alpha = roughness->evaluate(point).x;
alpha *= alpha;
return GGX_D(alpha, wh) * AbsCosTheta(wh);
}

} // namespace miyuki::core
32 changes: 32 additions & 0 deletions src/core/bsdfs/microfacet.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#pragma once

#include <api/bsdf.h>
#include <api/serialize.hpp>


namespace miyuki::core {
class Fresnel;
class Shader;

/*GGX microfacet reflection*/
class MicrofacetBSDF final : public BSDF {
std::shared_ptr<Shader> color, roughness;

public:
MYK_DECL_CLASS(MicrofacetBSDF, "MicrofacetBSDF", interface = "BSDF")

MYK_AUTO_SER(color, roughness)

MYK_AUTO_INIT(color, roughness)

MicrofacetBSDF() = default;

[[nodiscard]] Spectrum evaluate(const ShadingPoint &point, const Vec3f &wo, const Vec3f &wi) const override;

void sample(Point2f u, const ShadingPoint &sp, BSDFSample &sample) const override;

[[nodiscard]] Float evaluatePdf(const ShadingPoint &point, const Vec3f &wo, const Vec3f &wi) const override;

[[nodiscard]] Type getBSDFType() const override { return Type(EGlossy | EReflection); }
};
} // namespace miyuki::core
3 changes: 3 additions & 0 deletions src/core/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "accelerators/embree-backend.h"
#include "accelerators/sahbvh.h"
#include "core/bsdfs/diffusebsdf.h"
#include "bsdfs/microfacet.h"
#include "bsdfs/mixbsdf.h"
#include "core/cameras/perspective-camera.h"
#include "core/integrators/rtao.h"
Expand All @@ -48,12 +49,14 @@ namespace miyuki::core {
Register<RGBShader>();
Register<PerspectiveCamera>();
Register<DiffuseBSDF>();
Register<MicrofacetBSDF>();
Register<MixBSDF>();
Register<RTAO>();
Register<RandomSampler>();
Register<SobolSampler>();
Register<EmbreeAccelerator>();
Register<WavefrontImporter>();

}

void Finalize() {}
Expand Down
2 changes: 1 addition & 1 deletion src/core/mesh-importers/wavefront-importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace miyuki::core {
index_offset += fv;

// per-face material
shapes[s].mesh.material_ids[f];
// shapes[s].mesh.material_ids[f];

primitive.mesh = mesh.get();
mesh->triangles.push_back(primitive);
Expand Down

0 comments on commit e8f4d52

Please sign in to comment.