From 9a07c4d9659e81b7c3e7ca64fa2e88c2024fa909 Mon Sep 17 00:00:00 2001 From: sabyrrakhim06 <48181713+sabyrrakhim06@users.noreply.github.com> Date: Wed, 25 Nov 2020 15:23:50 +0100 Subject: [PATCH 1/2] updated README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9207f5a..c8a0dda 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ **Dealine**: 26.11.2020 Please put your name here: -**Name:** ....... +**Name:** Abumansur Sabyrrakhim ## Problem 1 ### Supersampling (Points 10 + 10 + 10) In this assignment we will concentrate on stochastic ray-tracin and start with developing samplers, which generate random samples covering a unit square area. From 109419367fa81df88ad059c98eb55bc47cb7a0f1 Mon Sep 17 00:00:00 2001 From: sabyrrakhim06 <48181713+sabyrrakhim06@users.noreply.github.com> Date: Thu, 26 Nov 2020 23:42:08 +0100 Subject: [PATCH 2/2] Assignment 6 --- src/LightArea.h | 26 ++++++- src/SamplerRandom.h | 6 +- src/SamplerRegular.h | 7 +- src/SamplerStratified.h | 16 +++- src/ShaderGlossy.h | 50 +++++++++++-- src/ShaderPhong.h | 37 ++++++---- src/main.cpp | 158 ++++++++++++++++++++-------------------- 7 files changed, 193 insertions(+), 107 deletions(-) diff --git a/src/LightArea.h b/src/LightArea.h index 9ee1ff0..d71a022 100644 --- a/src/LightArea.h +++ b/src/LightArea.h @@ -39,7 +39,31 @@ class CLightArea : public CLightOmni virtual std::optional illuminate(Ray& ray) override { // --- PUT YOUR CODE HERE --- - return std::nullopt; + Vec2f sample(0, 0); + size_t k = 0; + if(k < getNumSamples() - 1) { + sample = m_pSampler -> getSample(k); + k++; + } + + else { + sample = m_pSampler -> getSample(k); + k = 0; + } + + Vec3f org = m_org + sample.val[0] * m_edge1 + sample.val[1] * m_edge2; + + setOrigin(org); + auto res = CLightOmni::illuminate(ray); + + double cos_n = -ray.dir.dot(m_normal) / ray.t; + if(cos_n > 0) { + return m_area * cos_n * res.value(); + } + + else { + return std::nullopt; + } } virtual size_t getNumSamples(void) const override { return m_pSampler->getNumSamples(); } diff --git a/src/SamplerRandom.h b/src/SamplerRandom.h index 5a17b7d..c301939 100644 --- a/src/SamplerRandom.h +++ b/src/SamplerRandom.h @@ -22,6 +22,10 @@ class CSamplerRandom : public CSampler { virtual Vec2f getSample(size_t) const override { // --- PUT YOUR CODE HERE --- - return Vec2f::all(0.5f); + // random numbers between 0 and 1 + float i = Random::U(); + float j = Random::U(); + // return Vec2f::all(0.5f); + return Vec2f(j, i); } }; diff --git a/src/SamplerRegular.h b/src/SamplerRegular.h index 38d1cc7..6870b6e 100644 --- a/src/SamplerRegular.h +++ b/src/SamplerRegular.h @@ -15,6 +15,11 @@ class CSamplerRegular : public CSampler virtual Vec2f getSample(size_t s) const { // --- PUT YOUR CODE HERE --- - return Vec2f::all(0.5f); + // n - number of samples + int n = getNumSamples(); + float i = ((s % n) + 0.5) / float(sqrt(n)); + float j = ((s / sqrt(n)) + 0.5) / float(sqrt(n)); + // return Vec2f::all(0.5f); + return Vec2f(j, i); } }; diff --git a/src/SamplerStratified.h b/src/SamplerStratified.h index 6ae4d94..b24bbef 100644 --- a/src/SamplerStratified.h +++ b/src/SamplerStratified.h @@ -19,10 +19,20 @@ class CSamplerStratified : public CSampler { CSamplerStratified(size_t nSamples) : CSampler(nSamples) {} virtual ~CSamplerStratified(void) = default; - virtual Vec2f getSample(size_t s) const - { + virtual Vec2f getSample(size_t s) const { // --- PUT YOUR CODE HERE --- - return Vec2f::all(0.5f); + // n - number of samples + int n = getNumSamples(); + + // generating random numbers + // from 0 to 1 + float ei = Random::U(); + float ej = Random::U(); + + float i = ((s % n) + ei) / float(sqrt(n)); + float j = ((s / sqrt(n)) + ej) / float(sqrt(n)); + return Vec2f(j, i); + // return Vec2f::all(0.5f); } }; \ No newline at end of file diff --git a/src/ShaderGlossy.h b/src/ShaderGlossy.h index f05eb50..a275680 100644 --- a/src/ShaderGlossy.h +++ b/src/ShaderGlossy.h @@ -27,17 +27,55 @@ class CShaderGlossy : public CShaderPhong { virtual Vec3f shade(const Ray& ray) const override { Vec3f res = CShaderPhong::shade(ray); - Vec3f normal = ray.hit->getNormal(ray); // shading normal + Vec3f normal = ray.hit->getNormal(ray); // shading normal // --- PUT YOUR CODE HERE --- + int N = m_pSampler -> getNumSamples(); + Vec2f disc; + Vec3f deviatedNormal(0, 0, 0); + for(int i = 0; i < N; i++) { + Vec2f sample = m_pSampler -> getSample(i); - Ray reflected; - reflected.org = ray.org + ray.dir * ray.t; - reflected.dir = normalize(ray.dir - 2 * normal.dot(ray.dir) * normal); + Vec2f s1 = 2 * sample - Vec2f :: all(0); - Vec3f reflection = m_scene.RayTrace(reflected); +// // handling the origin degeneracy +// if(s1[0] == 0 && s1[1] == 0) { +// disc = Vec2f :: all(0); +// } - res = 0.5 * res + 0.5 * reflection; + // applying concentric mapping to point + float theta, r; + if(fabs(s1[0]) > fabs(s1[1])) { + r = s1[0]; + theta = 0.25f * Pif * s1[1] / r; + } + else { + r = s1[1]; + theta = 0.5f * Pif - 0.25 * Pif * s1[0] / r; + } + + float x = r * cosf(theta); + float y = r * sinf(theta); + + x += ((-1) * x * m_glossiness); + y += ((-1) * y * m_glossiness); + + disc = Vec2f(x, y); + Vec2f s2 = disc; + + float z = sqrtf(max(0.0f, 1.0f - s2[0] * s2[0] - s2[1] * s2[1])); + + deviatedNormal = Vec3f(normal.val[0] + s2[0], z, normal.val[2] + s2[1]); + + Ray reflected; + reflected.org = ray.org + ray.dir * ray.t; + reflected.dir = normalize(ray.dir - 2 * deviatedNormal.dot(ray.dir) * deviatedNormal); + + Vec3f reflection = m_scene.RayTrace(reflected); + + res += 0.5 * res + 0.5 * reflection; + } + res /= N; return res; } diff --git a/src/ShaderPhong.h b/src/ShaderPhong.h index 6544281..ea0937a 100644 --- a/src/ShaderPhong.h +++ b/src/ShaderPhong.h @@ -51,25 +51,30 @@ class CShaderPhong : public CShaderFlat for (auto pLight : m_scene.getLights()) { // get direction to light, and intensity // --- PUT YOUR CODE HERE --- - std::optional lightIntensity = pLight->illuminate(shadow); - if (lightIntensity) { - // diffuse term - float cosLightNormal = shadow.dir.dot(normal); - if (cosLightNormal > 0) { - if (m_scene.occluded(shadow)) - continue; + // N - number of samples + int N = pLight -> getNumSamples(); + for(int i = 0; i < N; i++) { + std::optional lightIntensity = pLight->illuminate(shadow); + if (lightIntensity) { + // diffuse term + float cosLightNormal = shadow.dir.dot(normal); + if (cosLightNormal > 0) { + if (m_scene.occluded(shadow)) + continue; - Vec3f diffuseColor = m_kd * color; - res += (diffuseColor * cosLightNormal).mul(lightIntensity.value()); - } + Vec3f diffuseColor = m_kd * color; + res += (diffuseColor * cosLightNormal).mul(lightIntensity.value()); + } - // specular term - float cosLightReflect = shadow.dir.dot(reflect); - if (cosLightReflect > 0) { - Vec3f specularColor = m_ks * RGB(1, 1, 1); // white highlight; - res += (specularColor * powf(cosLightReflect, m_ke)).mul(lightIntensity.value()); - } + // specular term + float cosLightReflect = shadow.dir.dot(reflect); + if (cosLightReflect > 0) { + Vec3f specularColor = m_ks * RGB(1, 1, 1); // white highlight; + res += (specularColor * powf(cosLightReflect, m_ke)).mul(lightIntensity.value()); + } + } } + res /= N; } for (int i = 0; i < 3; i++) diff --git a/src/main.cpp b/src/main.cpp index 9c03364..2be1bce 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -27,94 +27,94 @@ Mat RenderFrame(void) { - // Camera resolution - const Size resolution(800, 600); - - // Background color - const Vec3f bgColor = RGB(0, 0, 0); + // Camera resolution + const Size resolution(800, 600); - // Define a scene - CScene scene(bgColor); + // Background color + const Vec3f bgColor = RGB(0, 0, 0); - // Camera - scene.add(std::make_shared(resolution, Vec3f(0, 2, -30.0f), normalize(Vec3f(0.8f, -0.5f, 1)), Vec3f(0, 1, 0), 45.0f)); + // Define a scene + CScene scene(bgColor); + + // Camera + scene.add(std::make_shared(resolution, Vec3f(0, 2, -30.0f), normalize(Vec3f(0.8f, -0.5f, 1)), Vec3f(0, 1, 0), 45.0f)); #ifdef WIN32 - const std::string dataPath = "../data/"; + const std::string dataPath = "/Users/sabyr./Desktop/CG/eyden-tracer-05/data"; #else - const std::string dataPath = "../../../data/"; + const std::string dataPath = "/Users/sabyr./Desktop/CG/eyden-tracer-05/data"; #endif - // Textures - Mat cb = imread(dataPath + "cb.bmp"); - if (cb.empty()) printf("ERROR: Texture file is not found!\n"); - auto pTextureChessBoard = std::make_shared(cb); - - // Shaders - auto pShaderFloor = std::make_shared(pTextureChessBoard); - - // Geometry - const float s = 100; // size of the chess board - const float t = 100; // texture size of the chess board - - // --- Problem 2 --- - //scene.add(std::make_shared(resolution, Vec3f(0, 30.0f, 30.0f), normalize(Vec3f(0, -0.9f, -1)), Vec3f(0, 1, 0), 30.0f)); - // - //auto pAreaLightSampler = std::make_shared(3); - //auto pAreaLight = std::make_shared(Vec3f::all(400), Vec3f(15, 32, 1), Vec3f(-15, 32, 1), Vec3f(-15, 32, -1), Vec3f(15, 32, -1), pAreaLightSampler); - //scene.add(pAreaLight); - - //pShaderFloor = std::make_shared(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f); - //auto pShaderDragon = std::make_shared(scene, RGB(0.153f, 0.682f, 0.376f), 0.2f, 0.8f, 0.5f, 40.0f); - //CSolid dragon(pShaderDragon, dataPath + "Stanford Dragon.obj"); - //scene.add(dragon); - // --- ------- - --- - - // --- Problem 3 --- - //auto pGlossinessSampler = std::make_shared(3); - //pShaderFloor = std::make_shared(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f, 0.5f, pGlossinessSampler); - // --- ------- - --- - - CSolidQuad floor(pShaderFloor, Vec3f(-s, 0, -s), Vec3f(-s, 0, s), Vec3f(s, 0, s), Vec3f(s, 0, -s), Vec2f(0, 0), Vec2f(t, 0), Vec2f(t, t), Vec2f(0, t)); - - // Add everything to the scene - scene.add(floor); - - // Build BSPTree - scene.buildAccelStructure(30, 3); - - // Sampler - auto pPixelSampler = std::make_shared(2); - - Mat img(resolution, CV_32FC3); // image array - size_t nSamples = pPixelSampler->getNumSamples(); - - img.setTo(0); - parallel_for_(Range(0, img.rows), [&](const Range& range) { - Ray ray; // primary ray - for (int y = range.start; y < range.end; y++) { - Vec3f* pImg = img.ptr(y); // fast processing via pointers - for (int x = 0; x < img.cols; x++) { - for (size_t s = 0; s < nSamples; s++) { - Vec2f sample = pPixelSampler->getSample(s); - scene.getActiveCamera()->InitRay(ray, x, y, sample); // initialize ray - pImg[x] += scene.RayTrace(ray); - } // s - pImg[x] = (1.0f / nSamples) * pImg[x]; - } // x - } // y - }); - img.convertTo(img, CV_8UC3, 255); - return img; + // Textures + Mat cb = imread(dataPath + "cb.bmp"); + if (cb.empty()) printf("ERROR: Texture file is not found!\n"); + auto pTextureChessBoard = std::make_shared(cb); + + // Shaders + auto pShaderFloor = std::make_shared(pTextureChessBoard); + + // Geometry + const float s = 100; // size of the chess board + const float t = 100; // texture size of the chess board + + // --- Problem 2 --- + scene.add(std::make_shared(resolution, Vec3f(0, 30.0f, 30.0f), normalize(Vec3f(0, -0.9f, -1)), Vec3f(0, 1, 0), 30.0f)); + + auto pAreaLightSampler = std::make_shared(2); + auto pAreaLight = std::make_shared(Vec3f::all(400), Vec3f(15, 32, 1), Vec3f(-15, 32, 1), Vec3f(-15, 32, -1), Vec3f(15, 32, -1), pAreaLightSampler); + scene.add(pAreaLight); + + pShaderFloor = std::make_shared(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f); + auto pShaderDragon = std::make_shared(scene, RGB(0.153f, 0.682f, 0.376f), 0.2f, 0.8f, 0.5f, 40.0f); + CSolid dragon(pShaderDragon, "/Users/sabyr./Desktop/CG/eyden-tracer-05/data/Stanford Dragon.obj"); + scene.add(dragon); + // --- ------- - --- + + // --- Problem 3 --- + auto pGlossinessSampler = std::make_shared(2); + pShaderFloor = std::make_shared(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f, 1.0f, pGlossinessSampler); + // --- ------- - --- + + CSolidQuad floor(pShaderFloor, Vec3f(-s, 0, -s), Vec3f(-s, 0, s), Vec3f(s, 0, s), Vec3f(s, 0, -s), Vec2f(0, 0), Vec2f(t, 0), Vec2f(t, t), Vec2f(0, t)); + + // Add everything to the scene + scene.add(floor); + + // Build BSPTree + scene.buildAccelStructure(30, 3); + + // Sampler + auto pPixelSampler = std::make_shared(2); + + Mat img(resolution, CV_32FC3); // image array + size_t nSamples = pPixelSampler->getNumSamples(); + + img.setTo(0); + parallel_for_(Range(0, img.rows), [&](const Range& range) { + Ray ray; // primary ray + for (int y = range.start; y < range.end; y++) { + Vec3f* pImg = img.ptr(y); // fast processing via pointers + for (int x = 0; x < img.cols; x++) { + for (size_t s = 0; s < nSamples; s++) { + Vec2f sample = pPixelSampler->getSample(s); + scene.getActiveCamera()->InitRay(ray, x, y, sample); // initialize ray + pImg[x] += scene.RayTrace(ray); + } // s + pImg[x] = (1.0f / nSamples) * pImg[x]; + } // x + } // y + }); + img.convertTo(img, CV_8UC3, 255); + return img; } int main(int argc, char* argv[]) { - DirectGraphicalModels::Timer::start("Rendering..."); - Mat img = RenderFrame(); - DirectGraphicalModels::Timer::stop(); - imshow("Image", img); - waitKey(); - imwrite("image.jpg", img); - return 0; + DirectGraphicalModels::Timer::start("Rendering..."); + Mat img = RenderFrame(); + DirectGraphicalModels::Timer::stop(); + imshow("Image", img); + waitKey(); + imwrite("image.jpg", img); + return 0; }