diff options
| Commit | b80b72b103fbc51adcc36e91b4d51bd6089d2aaa (patch) | |
|---|---|---|
| Author | 2024-04-16 18:33:09 +0300 | |
| Committer | 2024-04-16 18:33:09 +0300 | |
| Files | 7ee67040b85432ec982341fce367b5176721784f | |
| uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.tar uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.tar.gz uni-projects-b80b72b103fbc51adcc36e91b4d51bd6089d2aaa.zip | ||
| Parent | 02ce081204865012a0f01cf2a9dd7c80c5f9fa88 (diff) | |
[Ray/h5] Added solution
1 files changed, 230 insertions, 0 deletions
| -rw-r--r-- | Year 3/Raytracing/0002-h5-Added-OrenNayar-shader.patch | 230 |
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 + |
