Summary Files Commits Branches @commit @diff @stats
diff options
context:
space:
mode:
Commitb80b72b103fbc51adcc36e91b4d51bd6089d2aaa (patch)
Author
 Syndamia <kamen@syndamia.com>
2024-04-16 18:33:09 +0300
Committer
 Syndamia <kamen@syndamia.com>
2024-04-16 18:33:09 +0300
Files7ee67040b85432ec982341fce367b5176721784f
uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.tar
uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.tar.gz
uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.zip
Parent02ce081204865012a0f01cf2a9dd7c80c5f9fa88 (diff)
[Ray/h5] Added solution
1 files changed, 230 insertions, 0 deletions
-rw-r--r--Year 3/Raytracing/0002-h5-Added-OrenNayar-shader.patch230
diff --git a/Year 3/Raytracing/0002-h5-Added-OrenNayar-shader.patch b/Year 3/Raytracing/0002-h5-Added-OrenNayar-shader.patch
new file mode 100644
index 0000000..fb7ae5f
--- /dev/null
+++ b/Year 3/Raytracing/0002-h5-Added-OrenNayar-shader.patch
@@ -0,0 +1,230 @@
+From 1f1cd2457d7e6bc7e3000fd1303a4d2a857c4b60 Mon Sep 17 00:00:00 2001
+From: Syndamia <kamen@syndamia.com>
+Date: Tue, 16 Apr 2024 18:27:57 +0300
+Subject: [PATCH] [h5] Added OrenNayar shader
+
+---
+ src/main.cpp | 85 ++++++++++++++++++++++++++-----------------------
+ src/shading.cpp | 26 +++++++++++++++
+ src/shading.h | 20 ++++++++++++
+ src/vector.h | 5 +++
+ 4 files changed, 97 insertions(+), 39 deletions(-)
+
+diff --git a/src/main.cpp b/src/main.cpp
+index ffb9478..8656207 100644
+--- a/src/main.cpp
++++ b/src/main.cpp
+@@ -37,7 +37,6 @@
+ #include "shading.h"
+
+ Color vfb[VFB_MAX_SIZE][VFB_MAX_SIZE];
+-Camera camera;
+ Color backgroundColor(0, 0, 0);
+
+ struct Node {
+@@ -81,38 +80,46 @@ Geometry* createRoundedEdgesCube(Vector center, double side, double cornerRadius
+ Vector csgCenter(-50, 20, 15);
+ Cube cube(csgCenter, 40);
+ Sphere sphere(csgCenter, 26);
+-void setupScene()
++void setupScene(void)
+ {
+- camera.pos.set(0, 60, -120);
+- camera.pitch = -10;
++ camera.yaw = 0;
++ camera.pitch = -30;
++ camera.roll = 0;
++ camera.fov = 90;
++ camera.aspectRatio = 4. / 3.0;
++ camera.pos = Vector(0, 165, 0);
++
+ camera.beginFrame();
+- sphere.uvscaling = 50;
+- // Create the floor:
+- Texture* floor = new BitmapTexture("data/floor.bmp");
+- nodes.push_back(Node{ new Plane(0), new Lambert(Color(0, 0, 0.8), floor)});
+- // Create a globe with the world map:
+- Phong* globeMat = new Phong;
+- globeMat->specularExponent = 120.0f;
+- globeMat->diffuseTex = new BitmapTexture("data/world.bmp", 1);
+- nodes.push_back(Node{ new Sphere(Vector(50, 30, 15), 30), globeMat});
+- // Create a CSG object: a cube with a cut out sphere in the middle
+- Texture* checker = new CheckerTexture(Color(0x8d3d3d), Color(0x9c9c9c), 5);
+- Phong* phong = new Phong(Color(0.6, 0.4, 0.1), Color(1, 1, 1), 120.0f, checker);
+- nodes.push_back(Node{ new CSGDiff(&cube, &sphere), phong});
+- // Create a complex CSG object: cube with rounded edges:
+- nodes.push_back(Node{ createRoundedEdgesCube(Vector(0, 20, 15), 40, 10),
+- new Phong(Color(0.9, 0.4, 0.1), Color(1, 1, 1), 125.0f)});
+- /*
+- nodes.push_back(Node{ createRoundedEdgesCube(Vector(0, 10, -15), 20, 8),
+- new Phong(Color(0.1, 0.4, 0.9), Color(1, 1, 1), 125.0f)});
+- nodes.push_back(Node{ createRoundedEdgesCube(Vector(0, 40, 100), 80, 10),
+- new Phong(Color(0.4, 0.9, 0.1), Color(1, 1, 1), 125.0f)});
+- */
+- lightPos.set(+30, +100, -70);
+- lightColor.setColor(1, 1, 1);
+- lightIntensity = 10000.0;
+-}
+
++ lightPos = Vector(-90, 700, 350);
++ lightColor = Color(1, 1, 1);
++ lightIntensity = 800000;
++
++ Plane* plane = new Plane(-0.01);
++ std::vector<Geometry*> geometries;
++ geometries.push_back(plane);
++
++ Texture* texture = new BitmapTexture("data/floor.bmp", 200);
++ Lambert* lambert = new Lambert(Color(1, 1, 1), texture);
++ Node floor{plane, lambert};
++ nodes.push_back(floor);
++
++ Shader* shaders[7];
++ Color diffuseR(0.6, 0.4, 0.4);
++ Color diffuseG(0.4, 0.6, 0.4);
++ shaders[0] = new Lambert(diffuseR);
++ shaders[1] = new Phong(diffuseR, Color(1, 1, 1), 80);
++ for (int i = 2; i < 7; i++) {
++ shaders[i] = new OrenNayar(diffuseG, (i - 2) / 5.0);
++ }
++
++ for (int i = 0; i < 2; i++) {
++ nodes.push_back(Node{new Sphere(Vector(-30 + 60*i, 15, 200), 22), shaders[i]});
++ }
++ for (int i = 2; i < 7; i++) {
++ nodes.push_back(Node{new Sphere(Vector(-120 + 60*(i-2), 15, 140), 22), shaders[i]});
++ }
++}
+ Color raytrace(Ray ray)
+ {
+ IntersectionInfo closestIntersection;
+@@ -180,18 +187,18 @@ int main(int argc, char** argv)
+ setupScene();
+ Uint32 start = SDL_GetTicks();
+ bool shouldExit = false;
+- for (double angle = 0; angle < 360 && !shouldExit; angle += 30) {
+- double a_rad = toRadians(angle);
+- camera.pos = Vector(sin(a_rad) * 120, 60, -cos(a_rad) * 120);
+- camera.yaw = angle;
++ // for (double angle = 0; angle < 360 && !shouldExit; angle += 30) {
++ // double a_rad = toRadians(angle);
++ // camera.pos = Vector(sin(a_rad) * 120, 60, -cos(a_rad) * 120);
++ // camera.yaw = angle;
+ camera.beginFrame();
+ render();
+ displayVFB(vfb);
+- if (checkForUserExit()) {
+- printf("Exited early.\n");
+- shouldExit = true;
+- }
+- }
++ // if (checkForUserExit()) {
++ // printf("Exited early.\n");
++ // shouldExit = true;
++ // }
++ // }
+ if (!shouldExit) {
+ Uint32 end = SDL_GetTicks();
+ printf("Elapsed time: %.2f seconds.\n", (end - start) / 1000.0);
+diff --git a/src/shading.cpp b/src/shading.cpp
+index 72dbdf2..123642c 100644
+--- a/src/shading.cpp
++++ b/src/shading.cpp
+@@ -29,6 +29,7 @@
+ Vector lightPos;
+ Color lightColor;
+ float lightIntensity;
++Camera camera;
+ const Color AMBIENT_LIGHT(0.15, 0.15, 0.15);
+
+ Color ConstantShader::computeColor(Ray ray, const IntersectionInfo& info)
+@@ -69,6 +70,31 @@ Color Lambert::computeColor(Ray ray, const IntersectionInfo& info)
+ return direct + ambient;
+ }
+
++Vector project(const Vector& a, const Vector& norm) {
++ return a - dot(a, norm) * norm;
++}
++
++Color OrenNayar::computeColor(Ray ray, const IntersectionInfo& info) {
++ Color ambient = diffuse * AMBIENT_LIGHT;
++ if (!visible(lightPos, info.ip)) {
++ return ambient;
++ }
++
++ Vector Vi = lightPos - info.ip;
++ Vector Vr = camera.pos - info.ip;
++ Color Li = lightColor * lightIntensity / Vi.lengthSqr();
++ const double albedo = 1.0;
++
++ double thetai = angle(info.norm, Vi);
++ double thetar = angle(info.norm, Vr);
++ double alpha = std::max(thetai, thetar), beta = std::min(thetai, thetar);
++
++ double surfProj = dot(normalize(project(Vi, info.norm)), normalize(project(Vr, info.norm))); // cos(phii - phir)
++
++ Color Lr = albedo * Li * cos(thetai) * (A + (B * std::max(0.0, surfProj) * sin(alpha) * tan(beta)));
++ return diffuse * Lr + ambient;
++}
++
+ Phong::Phong(Color color, Color spec, float specularExponent, Texture* diffuseTex):
+ diffuse(color), specular(spec), specularExponent(specularExponent), diffuseTex(diffuseTex) {}
+
+diff --git a/src/shading.h b/src/shading.h
+index 2bd1ef2..3ca71bd 100644
+--- a/src/shading.h
++++ b/src/shading.h
+@@ -28,10 +28,12 @@
+ #include "vector.h"
+ #include "geometry.h"
+ #include "bitmap.h"
++#include "camera.h"
+
+ extern Vector lightPos;
+ extern Color lightColor;
+ extern float lightIntensity;
++extern Camera camera;
+
+
+ class Shader {
+@@ -79,6 +81,24 @@ public:
+ virtual Color computeColor(Ray ray, const IntersectionInfo& info) override;
+ };
+
++class OrenNayar : public Shader {
++ float A;
++ float B;
++
++public:
++ Color diffuse;
++ float sigma;
++ OrenNayar(
++ Color color = Color(0.5, 0.5, 0.5),
++ float sigma = 0.0
++ ): diffuse(color), sigma(sigma) {
++ float sigma2 = sigma * sigma;
++ A = 1.0 - 0.5 * (sigma2 / (sigma2 + 0.33));
++ B = 0.45 * (sigma2 / (sigma2 + 0.09));
++ }
++ virtual Color computeColor(Ray ray, const IntersectionInfo& info) override;
++};
++
+ class Phong: public Shader {
+ public:
+ Color diffuse, specular;
+diff --git a/src/vector.h b/src/vector.h
+index c80a8c9..ef9baaa 100644
+--- a/src/vector.h
++++ b/src/vector.h
+@@ -159,3 +159,8 @@ inline Vector reflect(const Vector& i, const Vector& n)
+ {
+ return 2 * dot(-i, n) * n + i;
+ }
++
++/// angle between two vectors, in radians
++inline double angle(const Vector& a, const Vector& b) {
++ return acos(dot(normalize(a), normalize(b)));
++}
+--
+2.42.0
+