Skip to content
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

eyden-tracer-05 #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
26 changes: 25 additions & 1 deletion src/LightArea.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,31 @@ class CLightArea : public CLightOmni
virtual std::optional<Vec3f> illuminate(Ray& ray) override
{
// --- PUT YOUR CODE HERE ---
return std::nullopt;
Vec2f sample(0, 0);
size_t k = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it will be all the time 0
You need to make it static or member variable to save the state over the different calls of the function

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(); }

Expand Down
6 changes: 5 additions & 1 deletion src/SamplerRandom.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
float j = Random::U<float>();
// return Vec2f::all(0.5f);
return Vec2f(j, i);
}
};
7 changes: 6 additions & 1 deletion src/SamplerRegular.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you need to use sort(n) instead of n

float j = ((s / sqrt(n)) + 0.5) / float(sqrt(n));
// return Vec2f::all(0.5f);
return Vec2f(j, i);
}
};
16 changes: 13 additions & 3 deletions src/SamplerStratified.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
float ej = Random::U<float>();

float i = ((s % n) + ei) / float(sqrt(n));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you need to use sqrt(n) instead of n

float j = ((s / sqrt(n)) + ej) / float(sqrt(n));
return Vec2f(j, i);
// return Vec2f::all(0.5f);
}

};
50 changes: 44 additions & 6 deletions src/ShaderGlossy.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,55 @@ class CShaderGlossy : public CShaderPhong {
virtual Vec3f shade(const Ray& ray) const override {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suspection on plagiarism

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;
}
Expand Down
37 changes: 21 additions & 16 deletions src/ShaderPhong.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec3f> 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<Vec3f> 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++)
Expand Down
158 changes: 79 additions & 79 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<CCameraPerspective>(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<CCameraPerspective>(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<CTexture>(cb);

// Shaders
auto pShaderFloor = std::make_shared<CShaderFlat>(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<CCameraPerspective>(resolution, Vec3f(0, 30.0f, 30.0f), normalize(Vec3f(0, -0.9f, -1)), Vec3f(0, 1, 0), 30.0f));
//
//auto pAreaLightSampler = std::make_shared<CSamplerRandom>(3);
//auto pAreaLight = std::make_shared<CLightArea>(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<CShaderPhong>(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f);
//auto pShaderDragon = std::make_shared<CShaderPhong>(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<CSamplerRandom>(3);
//pShaderFloor = std::make_shared<CShaderGlossy>(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<CSampler>(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<Vec3f>(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<CTexture>(cb);

// Shaders
auto pShaderFloor = std::make_shared<CShaderFlat>(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<CCameraPerspective>(resolution, Vec3f(0, 30.0f, 30.0f), normalize(Vec3f(0, -0.9f, -1)), Vec3f(0, 1, 0), 30.0f));

auto pAreaLightSampler = std::make_shared<CSamplerRandom>(2);
auto pAreaLight = std::make_shared<CLightArea>(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<CShaderPhong>(scene, Vec3f::all(1), 0.1f, 0.9f, 0.0f, 40.0f);
auto pShaderDragon = std::make_shared<CShaderPhong>(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<CSamplerRandom>(2);
pShaderFloor = std::make_shared<CShaderGlossy>(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<CSamplerRandom>(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<Vec3f>(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;
}