Simple Normals Rendering

This commit is contained in:
IlyaShurupov 2023-10-16 13:38:56 +03:00 committed by Ilya Shurupov
parent b2fa4c4266
commit eb133745f9
9 changed files with 2296 additions and 156 deletions

View file

@ -2,19 +2,17 @@
using namespace tp; using namespace tp;
Camera::Camera() { Camera::Camera() { lookAtPoint({0, 0, 0}, {2, 0, 0}, {0, 0, 1}); }
lookAtPoint({ 0, 0, 0 }, { 2, 0, 0 }, { 0, 0, 1 });
}
Vec3F Camera::getTarget() const { return mTarget; } const Vec3F& Camera::getTarget() const { return mTarget; }
void Camera::offset_target(halnf val) { mTarget += (mPos - mTarget).normalize() * val; } void Camera::offset_target(halnf val) { mTarget += (mPos - mTarget).normalize() * val; }
Vec3F Camera::getForward() const { return (mTarget - mPos).normalize(); } Vec3F Camera::getForward() const { return (mTarget - mPos).normalize(); }
Vec3F Camera::getUp() const { return mUp; } const Vec3F& Camera::getUp() const { return mUp; }
Vec3F& Camera::getPos() { return mPos; } const Vec3F& Camera::getPos() const { return mPos; }
halnf Camera::getFar() const { return mFar; } halnf Camera::getFar() const { return mFar; }
@ -26,11 +24,11 @@ void Camera::setRatio(halnf in) { mRatio = in; }
void Camera::setFOV(halnf in) { mFOV = in; } void Camera::setFOV(halnf in) { mFOV = in; }
void Camera::setFar(halnf in) { mFar = in; }
halnf Camera::getFOV() const { return mFOV; } halnf Camera::getFOV() const { return mFOV; }
Mat4F Camera::calculateTransformationMatrix() { Mat4F Camera::calculateTransformationMatrix() { return calculateProjectionMatrix() * calculateViewMatrix(); }
return calculateProjectionMatrix() * calculateViewMatrix();
}
Mat4F Camera::calculateViewMatrix() { Mat4F Camera::calculateViewMatrix() {
const Vec3F& F = (mPos - mTarget).unitV(); const Vec3F& F = (mPos - mTarget).unitV();
@ -85,7 +83,9 @@ Vec2F Camera::project(const tp::Vec3F& world, const tp::Mat4F& viewMat, const tp
} }
void Camera::lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp) { void Camera::lookAtPoint(const Vec3F& aTarget, const Vec3F& aPos, Vec3F aUp) {
if (aTarget == aPos) return; if (aTarget == aPos) {
return;
}
mPos = aPos; mPos = aPos;
mTarget = aTarget; mTarget = aTarget;
Vec3F f = (mPos - mTarget).normalize(); Vec3F f = (mPos - mTarget).normalize();

View file

@ -95,3 +95,6 @@ void Topology::updateTransformed() {
mTrigCaches[idx].updateCache(mPointsTransformed); mTrigCaches[idx].updateCache(mPointsTransformed);
} }
} }
const Buffer<TrigCache>& Topology::getTrigs() const { return mTrigCaches; }

View file

@ -17,11 +17,12 @@ namespace tp {
void setRatio(halnf ratio); void setRatio(halnf ratio);
void setFOV(halnf fov); void setFOV(halnf fov);
void setFar(halnf far);
[[nodiscard]] Vec3F& getPos(); [[nodiscard]] const Vec3F& getPos() const;
[[nodiscard]] Vec3F getTarget() const; [[nodiscard]] const Vec3F& getTarget() const;
[[nodiscard]] Vec3F getForward() const; [[nodiscard]] Vec3F getForward() const;
[[nodiscard]] Vec3F getUp() const; [[nodiscard]] const Vec3F& getUp() const;
[[nodiscard]] halnf getRatio() const; [[nodiscard]] halnf getRatio() const;
[[nodiscard]] halnf getFOV() const; [[nodiscard]] halnf getFOV() const;
[[nodiscard]] halnf getFar() const; [[nodiscard]] halnf getFar() const;
@ -41,6 +42,5 @@ namespace tp {
[[nodiscard]] Vec3F project(Vec2F normalized); [[nodiscard]] Vec3F project(Vec2F normalized);
[[nodiscard]] Vec2F project(const Vec3F& world); [[nodiscard]] Vec2F project(const Vec3F& world);
[[nodiscard]] static Vec2F project(const tp::Vec3F& world, const tp::Mat4F& viewMat, const tp::Mat4F& projMat); [[nodiscard]] static Vec2F project(const tp::Vec3F& world, const tp::Mat4F& viewMat, const tp::Mat4F& projMat);
}; };
} }

View file

@ -44,5 +44,6 @@ namespace tp {
void addTrig(const Vec3F& v1, const Vec3F& v2, const Vec3F& v3); void addTrig(const Vec3F& v1, const Vec3F& v2, const Vec3F& v3);
void transformPoint(Vec3F& vert); void transformPoint(Vec3F& vert);
void updateTransformed(); void updateTransformed();
[[nodiscard]] const Buffer<TrigCache>& getTrigs() const;
}; };
} }

View file

@ -4,6 +4,7 @@
#include "Buffer.hpp" #include "Buffer.hpp"
#include "RayTracer.hpp" #include "RayTracer.hpp"
#include "Strings.hpp" #include "Strings.hpp"
#include "Timing.hpp"
#include "Vec.hpp" #include "Vec.hpp"
#include "OBJ_Loader.h" #include "OBJ_Loader.h"
@ -71,13 +72,24 @@ void renderCommand(const String& scenePath, RayTracer::RenderBuffer::Index2D siz
loadScene(scene, scenePath); loadScene(scene, scenePath);
scene.mCamera.lookAtPoint({0, 0, 0}, {-3, -3, 3}, {1, 1, 1});
scene.mCamera.setFOV(3.14 / 4);
scene.mCamera.setRatio((halnf) size.y / (halnf) size.x);
scene.mCamera.setFar(100);
RayTracer::RenderBuffer output; RayTracer::RenderBuffer output;
output.reserve(size); output.reserve(size);
RayTracer rayt; RayTracer rayt;
auto start = get_time();
rayt.render(scene, output); rayt.render(scene, output);
auto end = get_time();
printf("\n Render finished with average render time per sample - %i (ms)\n", end - start);
writeImage(output); writeImage(output);
} }
@ -86,7 +98,7 @@ int main() {
tp::ModuleManifest module("Rayt", nullptr, nullptr, deps); tp::ModuleManifest module("Rayt", nullptr, nullptr, deps);
if (module.initialize()) { if (module.initialize()) {
renderCommand("scene.obj", {1000, 1000}); renderCommand("scene.obj", {600, 600});
module.deinitialize(); module.deinitialize();
} }

View file

@ -1,12 +1,10 @@
# Blender MTL File: 'None' # Blender MTL File: 'None'
# Material Count: 1 # Material Count: 1
newmtl Material newmtl None
Ns 323.999994 Ns 500
Ka 1.000000 1.000000 1.000000 Ka 0.8 0.8 0.8
Kd 0.800000 0.800000 0.800000 Kd 0.8 0.8 0.8
Ks 0.500000 0.500000 0.500000 Ks 0.8 0.8 0.8
Ke 0.000000 0.000000 0.000000 d 1
Ni 1.450000
d 1.000000
illum 2 illum 2

File diff suppressed because it is too large Load diff

View file

@ -1,9 +1,14 @@
#include "MathCommon.hpp"
#include "NewPlacement.hpp" #include "NewPlacement.hpp"
#include "CommandLine.hpp" #include "CommandLine.hpp"
#include "Module.hpp" #include "Module.hpp"
#include "Ray.hpp"
#include "RayTracer.hpp" #include "RayTracer.hpp"
#include "TypeInfo.hpp"
#include <cstdio>
using namespace tp; using namespace tp;
@ -11,10 +16,79 @@ ModuleManifest* sDependencies[] = {&gModuleMath, &gModuleCommandLine, &gModuleCo
ModuleManifest tp::gModuleRayTracer = ModuleManifest("RayTracer", nullptr, nullptr, sDependencies); ModuleManifest tp::gModuleRayTracer = ModuleManifest("RayTracer", nullptr, nullptr, sDependencies);
void RayTracer::castRay(const Ray& ray, RayCastData& out, alnf far) {
out.hit = false;
far *= far;
for (auto obj : mScene->mObjects) {
for (auto trig : obj->getTrigs()) {
if (trig->castRay(ray)) {
// printf("Hit\n");
auto dist = (trig->getHitPos() - ray.pos).length2();
if (far > dist) {
out.trig = &trig.data();
out.hitPos = trig->getHitPos();
out.obj = &obj.data();
out.hit = true;
far = dist;
}
}
}
}
}
void RayTracer::render(const Scene& scene, RayTracer::RenderBuffer& buff) { void RayTracer::render(const Scene& scene, RayTracer::RenderBuffer& buff) {
mScene = &scene;
mBuff = &buff;
auto pos = mScene->mCamera.getPos();
auto fov = mScene->mCamera.getFOV();
auto height = sqrt(mScene->mCamera.getRatio());
auto width = 1.f / height;
auto forward = mScene->mCamera.getForward();
auto up = mScene->mCamera.getUp();
auto right = forward.cross(up);
auto planeCenter = pos + (forward * halnf(width / (2.f * tan(fov / 2.f))));
auto planeCenterOffset = (up * (halnf) height / 2.f) - (right * (halnf) width / 2.f);
auto planeLeftTop = planeCenter + planeCenterOffset;
RayCastData castData;
Ray ray = {
{0, 0, 0},
pos
};
Vec3F iterPoint = {0, 0, 0};
Vec3F deltaX = right * halnf(width / (alnf) buff.size().x);
Vec3F deltaY = up * halnf(-height / (alnf) buff.size().y);
for (RayTracer::RenderBuffer::Index i = 0; i < buff.size().x; i++) { for (RayTracer::RenderBuffer::Index i = 0; i < buff.size().x; i++) {
for (RayTracer::RenderBuffer::Index j = 0; j < buff.size().y; j++) { for (RayTracer::RenderBuffer::Index j = 0; j < buff.size().y; j++) {
buff.set({i, j}, RGBA(1.f, 1.f, 1.f, 1.f)); iterPoint = planeLeftTop + ((deltaX * (halnf) i) + (deltaY * (halnf) j));
ray.dir = (iterPoint - pos).unitV();
castRay(ray, castData, mScene->mCamera.getFar());
if (castData.hit) {
auto normal = castData.trig->getNormal();
normal.normalize();
RGBA col = {normal.x * 0.5f + 0.5f, normal.y * 0.5f + 0.5f, normal.z * 0.5f + 0.5f, 1.f};
auto depth = 1 - clamp((halnf) (castData.hitPos - ray.pos).length(), 0.f, mScene->mCamera.getFar()) / mScene->mCamera.getFar();
// buff.set({i, j}, {depth, depth, depth, 1.f});
buff.set({i, j}, col);
} else {
buff.set({i, j}, RGBA(0.f, 0.f, 0.f, 0.f));
}
} }
} }
} }

View file

@ -6,17 +6,21 @@
#include "Color.hpp" #include "Color.hpp"
#include "Module.hpp" #include "Module.hpp"
#include "Topology.hpp" #include "Topology.hpp"
#include "Vec.hpp"
namespace tp { namespace tp {
extern ModuleManifest gModuleRayTracer; extern ModuleManifest gModuleRayTracer;
class Scene { class Scene {
public:
typedef Topology Object;
public: public:
Scene() = default; Scene() = default;
public: public:
Buffer<Topology> mObjects; Buffer<Object> mObjects;
Camera mCamera; Camera mCamera;
}; };
@ -24,8 +28,28 @@ namespace tp {
public: public:
typedef Buffer2D<RGBA> RenderBuffer; typedef Buffer2D<RGBA> RenderBuffer;
struct RenderSettings {
alni samplesiPerPixel = 1;
alni rayBounces = 1;
};
public: public:
RayTracer() = default; RayTracer() = default;
void render(const Scene& scene, RenderBuffer& buff); void render(const Scene& scene, RenderBuffer& buff);
private:
struct RayCastData {
const Scene::Object* obj = nullptr;
TrigCache* trig = nullptr;
Vec3F hitPos = {0, 0, 0};
bool hit = false;
};
void castRay(const Ray& ray, RayCastData& out, alnf far);
private:
RenderSettings mSettings;
const Scene* mScene = nullptr;
RenderBuffer* mBuff = nullptr;
}; };
} }