Simple Normals Rendering
This commit is contained in:
parent
97525efacb
commit
0e41a6e4fd
9 changed files with 2296 additions and 156 deletions
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -95,3 +95,6 @@ void Topology::updateTransformed() {
|
||||||
mTrigCaches[idx].updateCache(mPointsTransformed);
|
mTrigCaches[idx].updateCache(mPointsTransformed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Buffer<TrigCache>& Topology::getTrigs() const { return mTrigCaches; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue