-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HW5 Solution #8
base: master
Are you sure you want to change the base?
HW5 Solution #8
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,3 +21,7 @@ doc/html | |
./vscode | ||
|
||
.DS_Store | ||
|
||
|
||
.idea | ||
cmake-build-debug |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,8 +13,11 @@ class CSamplerRegular : public CSampler | |
virtual ~CSamplerRegular(void) = default; | ||
|
||
virtual Vec2f getSample(size_t s) const | ||
{ | ||
// --- PUT YOUR CODE HERE --- | ||
return Vec2f::all(0.5f); | ||
{ | ||
size_t n = sqrt(this->getNumSamples()); | ||
// get i, j from row major format | ||
float i = (s % getNumSamples()) + 0.5; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In such case I will be equal to 0 all the time, you need to use n here |
||
float j = (s / n + 0.5); | ||
return Vec2f(j / n, i / n); | ||
} | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,8 +21,11 @@ class CSamplerStratified : public CSampler { | |
|
||
virtual Vec2f getSample(size_t s) const | ||
{ | ||
// --- PUT YOUR CODE HERE --- | ||
return Vec2f::all(0.5f); | ||
auto rd = Random::U<float>(); | ||
size_t n = sqrt(this->getNumSamples()); | ||
float i = s % getNumSamples(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The same error is here |
||
float j = (float)s / n; | ||
return Vec2f((j + rd) / n, (i + rd) / n); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rd should be different |
||
} | ||
|
||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,23 +25,57 @@ class CShaderGlossy : public CShaderPhong { | |
virtual ~CShaderGlossy(void) = default; | ||
|
||
virtual Vec3f shade(const Ray& ray) const override { | ||
Vec3f res = CShaderPhong::shade(ray); | ||
|
||
Vec3f normal = ray.hit->getNormal(ray); // shading normal | ||
|
||
// --- PUT YOUR CODE HERE --- | ||
|
||
Ray reflected; | ||
reflected.org = ray.org + ray.dir * ray.t; | ||
reflected.dir = normalize(ray.dir - 2 * normal.dot(ray.dir) * normal); | ||
|
||
Vec3f reflection = m_scene.RayTrace(reflected); | ||
|
||
res = 0.5 * res + 0.5 * reflection; | ||
|
||
return res; | ||
// shading normal | ||
int nSamples = m_pSampler->getNumSamples(); | ||
Vec3f agg = Vec3f::all(0); | ||
Vec3f res = CShaderPhong::shade(ray); | ||
Vec3f normal = ray.hit->getNormal(ray); | ||
int k = 0; | ||
for(int i = 0; i < nSamples; i++) { | ||
// deep copy of normal. | ||
auto normalCpy = Vec3f(normal); | ||
Vec2f sample = m_pSampler -> getSample(i); | ||
auto res2 = cwsReflection(sample, normalCpy, ray, nSamples); | ||
if (res2.has_value()) | ||
{ | ||
k++; | ||
agg += res2.value() * m_glossiness; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is a mis-use go the glossiness effect. This implementation just makes glossiness to vanish, but the m_glossiness parameter should modulate how much the normal is deviated - thus, for m_glossiness close to 1, the samples should be concentrated on top of the hemisphere, whereas for small m_glossiness close to 0, the samples should be equally distributed over the hemisphere |
||
} | ||
} | ||
res = res*0.5 + agg / k * 0.5; | ||
return res; | ||
} | ||
|
||
protected: | ||
[[nodiscard]] std::optional<Vec3f> cwsReflection(const Vec2f& sample, const Vec3f& normal, const Ray& ray, int n) const | ||
{ | ||
Vec2f disc; | ||
Vec2f s = 2 * sample - Vec2f::all(1); | ||
if (s[0] == 0 && s[1] == 0) | ||
disc = Vec2f::all(0); | ||
float theta, r; | ||
if (fabs(s[0]) > fabs(s[1])) { | ||
r = s[0]; | ||
theta = 0.25f * Pif * s[1] / r; | ||
} else { | ||
r = s[1]; | ||
theta = 0.5f * Pif - 0.25f * Pif * s[0] / r; | ||
} | ||
auto rA = normalize((Vec3f(0, 0, 1) + normal) / 2); | ||
float x = r * cosf(theta); | ||
float y = r * sinf(theta); | ||
s = Vec2f(x, y); | ||
float z = sqrtf(max(0.0f, 1.0f - s[0] * s[0] - s[1] * s[1])); | ||
auto nS = Vec3f(s[0], s[1], z); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You derive nS, but never use it. It should be used instead of the normal. m_glossiness should also participate in the derivation of the nS. For example, for glossiness close to 1, you can divide x and y parameters by a large number, etc. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So, the code above is not in use |
||
Ray reflected; | ||
reflected.org = ray.org + ray.dir * ray.t; | ||
reflected.dir = normalize(ray.dir - 2 * normal.dot(ray.dir) * normal); | ||
if (reflected.dir.dot(normal) < Epsilon) | ||
return std::nullopt; | ||
return m_scene.RayTrace(reflected); | ||
}; | ||
|
||
private: | ||
float m_glossiness; ///< 1 - perfect mirror, 0.01 - fully diffuse | ||
ptr_sampler_t m_pSampler; ///< Pointer to the sampler ref @ref CSampler | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here both components will be initialized with the same random number. U() method will be called only once.