Bin packing
parent
d4a9d729a0
commit
74967c11b6
|
@ -135,7 +135,7 @@ namespace Raytracing {
|
||||||
void lookAt(const Vec4& lookAtPos);
|
void lookAt(const Vec4& lookAtPos);
|
||||||
};
|
};
|
||||||
|
|
||||||
static Random rnd{-1, 1};
|
static Random rnd{-1.0, 1.0};
|
||||||
|
|
||||||
struct RaycasterImageBounds {
|
struct RaycasterImageBounds {
|
||||||
int width,height, x,y;
|
int width,height, x,y;
|
||||||
|
@ -160,6 +160,7 @@ namespace Raytracing {
|
||||||
std::mutex queueSync;
|
std::mutex queueSync;
|
||||||
std::queue<RaycasterImageBounds>* unprocessedQuads = nullptr;
|
std::queue<RaycasterImageBounds>* unprocessedQuads = nullptr;
|
||||||
|
|
||||||
|
Vec4 raycasti(const Ray& ray, int depth);
|
||||||
Vec4 raycast(const Ray& ray);
|
Vec4 raycast(const Ray& ray);
|
||||||
void runRaycastingAlgorithm(RaycasterImageBounds imageBounds, int loopX, int loopY);
|
void runRaycastingAlgorithm(RaycasterImageBounds imageBounds, int loopX, int loopY);
|
||||||
void runSTDThread(int threads);
|
void runSTDThread(int threads);
|
||||||
|
|
|
@ -55,6 +55,11 @@ namespace Raytracing {
|
||||||
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
|
// returns true if the ray was scattered along with the scattered ray, otherwise will return false with empty ray.
|
||||||
// the returned vec4 is the attenuation color
|
// the returned vec4 is the attenuation color
|
||||||
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
|
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const = 0;
|
||||||
|
// emission value for this material
|
||||||
|
// this allows for a material to glow slightly or emit full on light
|
||||||
|
// the light can of course be of any color
|
||||||
|
// and the UV coords along with the actual hit point are provided for your convince
|
||||||
|
[[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const { return {}; }
|
||||||
|
|
||||||
[[nodiscard]] Vec4 getBaseColor() const { return baseColor; }
|
[[nodiscard]] Vec4 getBaseColor() const { return baseColor; }
|
||||||
virtual ~Material() = default;
|
virtual ~Material() = default;
|
||||||
|
|
|
@ -77,12 +77,22 @@ namespace Raytracing {
|
||||||
std::random_device rd; // obtain a random number from hardware
|
std::random_device rd; // obtain a random number from hardware
|
||||||
std::mt19937 gen;
|
std::mt19937 gen;
|
||||||
std::uniform_real_distribution<double> doubleDistr{0, 1};
|
std::uniform_real_distribution<double> doubleDistr{0, 1};
|
||||||
|
std::uniform_int_distribution<long> longDistr{0, 1};
|
||||||
|
std::uniform_int_distribution<unsigned long> ulongDistr{0, 1};
|
||||||
public:
|
public:
|
||||||
Random(): gen(std::mt19937(long(rd.entropy() * 691 * 691))) {}
|
Random(): gen(std::mt19937(long(rd.entropy() * 691 * 691))) {}
|
||||||
Random(double min, double max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), doubleDistr{min, max} {}
|
Random(double min, double max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), doubleDistr{min, max} {}
|
||||||
|
Random(long min, long max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), longDistr{min, max} {}
|
||||||
|
Random(unsigned long min, unsigned long max): gen(std::mt19937(long(rd.entropy() * 691 * 691))), ulongDistr{min, max} {}
|
||||||
double getDouble() {
|
double getDouble() {
|
||||||
return doubleDistr(gen);
|
return doubleDistr(gen);
|
||||||
}
|
}
|
||||||
|
long getLong(){
|
||||||
|
return longDistr(gen);
|
||||||
|
}
|
||||||
|
unsigned long getULong(){
|
||||||
|
return ulongDistr(gen);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class String {
|
class String {
|
||||||
|
|
|
@ -89,6 +89,13 @@ namespace Raytracing {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class LightMaterial : public Material {
|
||||||
|
public:
|
||||||
|
explicit LightMaterial(const Vec4& lightColor): Material(lightColor) {}
|
||||||
|
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
|
||||||
|
[[nodiscard]] virtual Vec4 emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const override;
|
||||||
|
};
|
||||||
|
|
||||||
class TexturedMaterial : public Material {
|
class TexturedMaterial : public Material {
|
||||||
protected:
|
protected:
|
||||||
int width{}, height{}, channels{};
|
int width{}, height{}, channels{};
|
||||||
|
@ -97,7 +104,7 @@ namespace Raytracing {
|
||||||
explicit TexturedMaterial(const std::string& file);
|
explicit TexturedMaterial(const std::string& file);
|
||||||
|
|
||||||
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
|
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
|
||||||
[[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& point) const;
|
[[nodiscard]] Vec4 getColor(PRECISION_TYPE u, PRECISION_TYPE v) const;
|
||||||
|
|
||||||
~TexturedMaterial();
|
~TexturedMaterial();
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,10 +52,10 @@ namespace Raytracing {
|
||||||
int m_activePlatform;
|
int m_activePlatform;
|
||||||
|
|
||||||
cl_platform_id* m_platformIDs;
|
cl_platform_id* m_platformIDs;
|
||||||
cl_uint m_numOfPlatformIDs;
|
cl_uint m_numOfPlatformIDs{};
|
||||||
|
|
||||||
cl_device_id m_deviceID;
|
cl_device_id m_deviceID{};
|
||||||
cl_uint m_numOfDevices;
|
cl_uint m_numOfDevices{};
|
||||||
|
|
||||||
cl_context m_context;
|
cl_context m_context;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# Blender 3.3.1 MTL File: 'None'
|
||||||
|
# www.blender.org
|
|
@ -0,0 +1,47 @@
|
||||||
|
# Blender 3.3.1
|
||||||
|
# www.blender.org
|
||||||
|
mtllib skybox.mtl
|
||||||
|
o Cube
|
||||||
|
v -256.000000 -256.000000 256.000000
|
||||||
|
v -256.000000 256.000000 256.000000
|
||||||
|
v -256.000000 -256.000000 -256.000000
|
||||||
|
v -256.000000 256.000000 -256.000000
|
||||||
|
v 256.000000 -256.000000 256.000000
|
||||||
|
v 256.000000 256.000000 256.000000
|
||||||
|
v 256.000000 -256.000000 -256.000000
|
||||||
|
v 256.000000 256.000000 -256.000000
|
||||||
|
vn -1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 -1.0000
|
||||||
|
vn 1.0000 -0.0000 -0.0000
|
||||||
|
vn -0.0000 -0.0000 1.0000
|
||||||
|
vn -0.0000 -1.0000 -0.0000
|
||||||
|
vn -0.0000 1.0000 -0.0000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 0.000000 0.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 0.000000 1.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 1.000000 0.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
vt 1.000000 1.000000
|
||||||
|
s 0
|
||||||
|
f 2/2/1 3/6/1 1/1/1
|
||||||
|
f 4/8/2 7/14/2 3/4/2
|
||||||
|
f 8/16/3 5/9/3 7/14/3
|
||||||
|
f 6/12/4 1/1/4 5/10/4
|
||||||
|
f 7/15/5 1/1/5 3/5/5
|
||||||
|
f 4/8/6 6/13/6 8/16/6
|
||||||
|
f 2/2/1 4/7/1 3/6/1
|
||||||
|
f 4/8/2 8/16/2 7/14/2
|
||||||
|
f 8/16/3 6/11/3 5/9/3
|
||||||
|
f 6/12/4 2/2/4 1/1/4
|
||||||
|
f 7/15/5 5/10/5 1/1/5
|
||||||
|
f 4/8/6 2/3/6 6/13/6
|
|
@ -36,7 +36,143 @@ namespace Raytracing{
|
||||||
|
|
||||||
using namespace Raytracing;
|
using namespace Raytracing;
|
||||||
|
|
||||||
|
typedef unsigned long binsType;
|
||||||
|
|
||||||
|
std::queue<binsType> sort(std::queue<binsType>& q, bool dir = false){
|
||||||
|
std::queue<binsType> ret;
|
||||||
|
auto size = q.size();
|
||||||
|
binsType vals[size];
|
||||||
|
for (int i = 0; i < size; i++){
|
||||||
|
vals[i] = q.front();
|
||||||
|
q.pop();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++){
|
||||||
|
for (int j = i; j < size; j++){
|
||||||
|
if (dir) {
|
||||||
|
if (vals[j] < vals[i]) {
|
||||||
|
auto temp = vals[j];
|
||||||
|
vals[j] = vals[i];
|
||||||
|
vals[i] = temp;
|
||||||
|
}
|
||||||
|
} else{
|
||||||
|
if (vals[j] > vals[i]) {
|
||||||
|
auto temp = vals[j];
|
||||||
|
vals[j] = vals[i];
|
||||||
|
vals[i] = temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < size; i++){
|
||||||
|
ret.push(vals[i]);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
int main(int argc, char** args) {
|
int main(int argc, char** args) {
|
||||||
|
/*int numOfObjects = 50000;
|
||||||
|
binsType binCapacity = 100.0;
|
||||||
|
|
||||||
|
Random rnd1{0, binCapacity};
|
||||||
|
|
||||||
|
binsType objects[numOfObjects];
|
||||||
|
std::vector<binsType> bins;
|
||||||
|
|
||||||
|
for (int i = 0; i < numOfObjects; i++)
|
||||||
|
objects[i] = (rnd1.getULong());
|
||||||
|
|
||||||
|
std::queue<binsType> less;
|
||||||
|
std::queue<binsType> more;
|
||||||
|
|
||||||
|
for (int i = 0; i < numOfObjects; i++){
|
||||||
|
if (objects[i] >= binCapacity){
|
||||||
|
bins.push_back(objects[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (objects[i] < binCapacity/2)
|
||||||
|
less.push(objects[i]);
|
||||||
|
else
|
||||||
|
more.push(objects[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
//less = sort(less, true);
|
||||||
|
//more = sort(more, false);
|
||||||
|
|
||||||
|
binsType currentBin = 0;
|
||||||
|
|
||||||
|
|
||||||
|
while (true){
|
||||||
|
if (!more.empty()) {
|
||||||
|
auto moreVal = more.front();
|
||||||
|
while (!more.empty() && moreVal + currentBin <= binCapacity){
|
||||||
|
currentBin += moreVal;
|
||||||
|
more.pop();
|
||||||
|
moreVal = more.front();
|
||||||
|
}
|
||||||
|
ilog << currentBin << "\n";
|
||||||
|
auto lessVal = less.front();
|
||||||
|
while (!less.empty() && lessVal + currentBin <= binCapacity){
|
||||||
|
currentBin += lessVal;
|
||||||
|
less.pop();
|
||||||
|
lessVal = less.front();
|
||||||
|
}
|
||||||
|
dlog << currentBin << " " << lessVal << "\n";
|
||||||
|
} else {
|
||||||
|
if (less.empty())
|
||||||
|
break;
|
||||||
|
auto lessVal = less.front();
|
||||||
|
while (!less.empty() && lessVal + currentBin <= binCapacity){
|
||||||
|
currentBin += lessVal;
|
||||||
|
less.pop();
|
||||||
|
lessVal = less.front();
|
||||||
|
}
|
||||||
|
wlog << currentBin << " " << lessVal << "\n";
|
||||||
|
}
|
||||||
|
if (currentBin <= 0)
|
||||||
|
break;
|
||||||
|
bins.push_back(currentBin);
|
||||||
|
currentBin = 0;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*while (!more.empty()) {
|
||||||
|
currentBin = more.front();
|
||||||
|
more.pop();
|
||||||
|
double lessVal = less.front();
|
||||||
|
while (!less.empty() && currentBin + lessVal < binCapacity){
|
||||||
|
currentBin += lessVal;
|
||||||
|
less.pop();
|
||||||
|
lessVal = less.front();
|
||||||
|
}
|
||||||
|
if (currentBin > 0)
|
||||||
|
bins.push_back(currentBin);
|
||||||
|
currentBin = 0;
|
||||||
|
if (less.empty()) {
|
||||||
|
double moreVal = more.front();
|
||||||
|
while (!more.empty()){
|
||||||
|
while (!more.empty() && currentBin + moreVal < binCapacity) {
|
||||||
|
currentBin += moreVal;
|
||||||
|
more.pop();
|
||||||
|
moreVal = more.front();
|
||||||
|
}
|
||||||
|
if (currentBin > 0)
|
||||||
|
bins.push_back(currentBin);
|
||||||
|
currentBin = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
/*int goodCount = 0;
|
||||||
|
int greatCount = 0;
|
||||||
|
for (binsType bin : bins) {
|
||||||
|
tlog << bin << "\n";
|
||||||
|
if (bin >= (binsType)((double)binCapacity * 0.95))
|
||||||
|
goodCount++;
|
||||||
|
if (bin >= (binsType)((double)binCapacity * 0.99))
|
||||||
|
greatCount++;
|
||||||
|
}
|
||||||
|
tlog << "We made " << bins.size() << " bins!\n";
|
||||||
|
tlog << "With " << goodCount << " good bins and " << greatCount << " great bins!\n";
|
||||||
|
|
||||||
|
return 0;*/
|
||||||
// since this is linux only we can easily set our process priority to be high with a syscall
|
// since this is linux only we can easily set our process priority to be high with a syscall
|
||||||
// requires root. TODO: find way to doing this without root even if asking for user privilege escalation
|
// requires root. TODO: find way to doing this without root even if asking for user privilege escalation
|
||||||
//setpriority(PRIO_PROCESS, 0, -20);
|
//setpriority(PRIO_PROCESS, 0, -20);
|
||||||
|
@ -126,11 +262,12 @@ int main(int argc, char** args) {
|
||||||
Raytracing::ModelData spider = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "spider.obj");
|
Raytracing::ModelData spider = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "spider.obj");
|
||||||
Raytracing::ModelData house = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "house.obj");
|
Raytracing::ModelData house = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "house.obj");
|
||||||
Raytracing::ModelData plane = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "plane.obj");
|
Raytracing::ModelData plane = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "plane.obj");
|
||||||
Raytracing::ModelData debugCube = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "debug.obj");
|
Raytracing::ModelData debugCube = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "skybox.obj");
|
||||||
|
|
||||||
world.add("greenDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{0, 1.0, 0, 1}});
|
world.add("greenDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{0, 1.0, 0, 1}});
|
||||||
world.add("redDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{1.0, 0, 0, 1}});
|
world.add("redDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{1.0, 0, 0, 1}});
|
||||||
world.add("blueDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{0, 0, 1.0, 1}});
|
world.add("blueDiffuse", new Raytracing::DiffuseMaterial{Raytracing::Vec4{0, 0, 1.0, 1}});
|
||||||
|
world.add("light", new Raytracing::LightMaterial{Raytracing::Vec4{10.0, 10.0, 10.0}});
|
||||||
|
|
||||||
world.add("greenMetal", new Raytracing::MetalMaterial{Raytracing::Vec4{0.4, 1.0, 0.4, 1}});
|
world.add("greenMetal", new Raytracing::MetalMaterial{Raytracing::Vec4{0.4, 1.0, 0.4, 1}});
|
||||||
world.add("redMetal", new Raytracing::BrushedMetalMaterial{Raytracing::Vec4{1.0, 0.4, 0.4, 1}, 0.6f});
|
world.add("redMetal", new Raytracing::BrushedMetalMaterial{Raytracing::Vec4{1.0, 0.4, 0.4, 1}, 0.6f});
|
||||||
|
@ -147,7 +284,7 @@ int main(int argc, char** args) {
|
||||||
world.add(new Raytracing::ModelObject({5, 1, 0}, house, world.getMaterial("redDiffuse")));
|
world.add(new Raytracing::ModelObject({5, 1, 0}, house, world.getMaterial("redDiffuse")));
|
||||||
world.add(new Raytracing::ModelObject({0, 0, -5}, house, world.getMaterial("blueDiffuse")));
|
world.add(new Raytracing::ModelObject({0, 0, -5}, house, world.getMaterial("blueDiffuse")));
|
||||||
world.add(new Raytracing::ModelObject({0, 0, 5}, house, world.getMaterial("blueDiffuse")));
|
world.add(new Raytracing::ModelObject({0, 0, 5}, house, world.getMaterial("blueDiffuse")));
|
||||||
world.add(new Raytracing::ModelObject({0, 5, 0}, debugCube, world.getMaterial("magic")));
|
//world.add(new Raytracing::ModelObject({0, 0, 0}, debugCube, world.getMaterial("cat")));
|
||||||
|
|
||||||
if (parser.hasOption("--gui") || parser.hasOption("-g")) {
|
if (parser.hasOption("--gui") || parser.hasOption("-g")) {
|
||||||
#ifdef COMPILE_GUI
|
#ifdef COMPILE_GUI
|
||||||
|
|
|
@ -96,6 +96,10 @@ namespace Raytracing {
|
||||||
Vec4 color;
|
Vec4 color;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Vec4 Raycaster::raycasti(const Ray& ray, int depth){
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
Vec4 Raycaster::raycast(const Ray& ray) {
|
Vec4 Raycaster::raycast(const Ray& ray) {
|
||||||
Ray localRay = ray;
|
Ray localRay = ray;
|
||||||
Vec4 color {1.0, 1.0, 1.0};
|
Vec4 color {1.0, 1.0, 1.0};
|
||||||
|
@ -104,22 +108,28 @@ namespace Raytracing {
|
||||||
return color;
|
return color;
|
||||||
while (RTSignal->pauseRaytracing) // sleep for 1/60th of a second, or about 1 frame.
|
while (RTSignal->pauseRaytracing) // sleep for 1/60th of a second, or about 1 frame.
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||||
|
|
||||||
auto hit = world.checkIfHit(localRay, 0.001, infinity);
|
auto hit = world.checkIfHit(localRay, 0.001, infinity);
|
||||||
if (hit.first.hit) {
|
if (hit.first.hit) {
|
||||||
auto object = hit.second;
|
auto object = hit.second;
|
||||||
auto scatterResults = object->getMaterial()->scatter(localRay, hit.first);
|
auto scatterResults = object->getMaterial()->scatter(localRay, hit.first);
|
||||||
|
//auto emission = object->getMaterial()->emission(hit.first.u, hit.first.v, hit.first.hitPoint);
|
||||||
// if the material scatters the ray, ie casts a new one,
|
// if the material scatters the ray, ie casts a new one,
|
||||||
if (scatterResults.scattered) { // attenuate the recursive raycast by the material's color
|
if (scatterResults.scattered) { // attenuate the recursive raycast by the material's color
|
||||||
color = color * scatterResults.attenuationColor;
|
color = color * scatterResults.attenuationColor;
|
||||||
localRay = scatterResults.newRay;
|
localRay = scatterResults.newRay;
|
||||||
} else {
|
} else {
|
||||||
// if we don't scatter, we don't need to keep looping
|
// if we don't scatter, we don't need to keep looping
|
||||||
color = {0.0, 0.0, 0.0};
|
// but we should return whatever the material's emission is
|
||||||
|
// which for all that aren't lights (currently) is the old black color.
|
||||||
|
//color = color + emission;
|
||||||
|
color = {};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// since we didn't hit, we hit the sky.
|
// since we didn't hit, we hit the sky.
|
||||||
color = color * Vec4{0.5, 0.7, 1.0};
|
color = color * Vec4{0.5, 0.7, 1.0};
|
||||||
|
//color = Vec4{};
|
||||||
// if we don't hit we cannot keep looping.
|
// if we don't hit we cannot keep looping.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -144,9 +144,9 @@ namespace Raytracing {
|
||||||
if (newRay.x() < EPSILON && newRay.y() < EPSILON && newRay.z() < EPSILON && newRay.w() < EPSILON)
|
if (newRay.x() < EPSILON && newRay.y() < EPSILON && newRay.z() < EPSILON && newRay.w() < EPSILON)
|
||||||
newRay = hitData.normal;
|
newRay = hitData.normal;
|
||||||
|
|
||||||
return {true, Ray{hitData.hitPoint, newRay}, getColor(hitData.u, hitData.v, hitData.hitPoint)};
|
return {true, Ray{hitData.hitPoint, newRay}, getColor(hitData.u, hitData.v)};
|
||||||
}
|
}
|
||||||
Vec4 TexturedMaterial::getColor(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& point) const {
|
Vec4 TexturedMaterial::getColor(PRECISION_TYPE u, PRECISION_TYPE v) const {
|
||||||
// if we are unable to load the image return the debug color.
|
// if we are unable to load the image return the debug color.
|
||||||
if (!data)
|
if (!data)
|
||||||
return Vec4{0.2, 1, 0} * Vec4{u, v, 1.0};
|
return Vec4{0.2, 1, 0} * Vec4{u, v, 1.0};
|
||||||
|
@ -180,6 +180,13 @@ namespace Raytracing {
|
||||||
TexturedMaterial::~TexturedMaterial() {
|
TexturedMaterial::~TexturedMaterial() {
|
||||||
stbi_image_free(data);
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
|
ScatterResults LightMaterial::scatter(const Ray& ray, const HitData& hitData) const {
|
||||||
|
// do not scatter. The light emits.
|
||||||
|
return {false, ray, baseColor};
|
||||||
|
}
|
||||||
|
Vec4 LightMaterial::emission(PRECISION_TYPE u, PRECISION_TYPE v, const Vec4& hitPoint) const {
|
||||||
|
return baseColor;
|
||||||
|
}
|
||||||
|
|
||||||
PRECISION_TYPE sign(PRECISION_TYPE i){
|
PRECISION_TYPE sign(PRECISION_TYPE i){
|
||||||
return i >= 0 ? 1 : -1;
|
return i >= 0 ? 1 : -1;
|
||||||
|
|
Loading…
Reference in New Issue