Bin packing

main
Brett 2022-11-22 00:26:23 -05:00
parent d4a9d729a0
commit 74967c11b6
10 changed files with 236 additions and 10 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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 {

View File

@ -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();
}; };

View File

@ -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;

View File

@ -0,0 +1,2 @@
# Blender 3.3.1 MTL File: 'None'
# www.blender.org

View File

@ -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

View File

@ -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

View File

@ -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;
} }

View File

@ -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;