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);
};
static Random rnd{-1, 1};
static Random rnd{-1.0, 1.0};
struct RaycasterImageBounds {
int width,height, x,y;
@ -160,6 +160,7 @@ namespace Raytracing {
std::mutex queueSync;
std::queue<RaycasterImageBounds>* unprocessedQuads = nullptr;
Vec4 raycasti(const Ray& ray, int depth);
Vec4 raycast(const Ray& ray);
void runRaycastingAlgorithm(RaycasterImageBounds imageBounds, int loopX, int loopY);
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.
// the returned vec4 is the attenuation color
[[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; }
virtual ~Material() = default;

View File

@ -77,12 +77,22 @@ namespace Raytracing {
std::random_device rd; // obtain a random number from hardware
std::mt19937 gen;
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:
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(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() {
return doubleDistr(gen);
}
long getLong(){
return longDistr(gen);
}
unsigned long getULong(){
return ulongDistr(gen);
}
};
class String {

View File

@ -88,6 +88,13 @@ namespace Raytracing {
[[nodiscard]] virtual ScatterResults scatter(const Ray& ray, const HitData& hitData) const override;
};
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 {
protected:
@ -97,7 +104,7 @@ namespace Raytracing {
explicit TexturedMaterial(const std::string& file);
[[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();
};

View File

@ -52,10 +52,10 @@ namespace Raytracing {
int m_activePlatform;
cl_platform_id* m_platformIDs;
cl_uint m_numOfPlatformIDs;
cl_uint m_numOfPlatformIDs{};
cl_device_id m_deviceID;
cl_uint m_numOfDevices;
cl_device_id m_deviceID{};
cl_uint m_numOfDevices{};
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;
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 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
// requires root. TODO: find way to doing this without root even if asking for user privilege escalation
//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 house = Raytracing::OBJLoader::loadModel(parser.getOptionValue("--resources") + "house.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("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("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("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({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")) {
#ifdef COMPILE_GUI

View File

@ -96,6 +96,10 @@ namespace Raytracing {
Vec4 color;
};
Vec4 Raycaster::raycasti(const Ray& ray, int depth){
return {};
}
Vec4 Raycaster::raycast(const Ray& ray) {
Ray localRay = ray;
Vec4 color {1.0, 1.0, 1.0};
@ -104,22 +108,28 @@ namespace Raytracing {
return color;
while (RTSignal->pauseRaytracing) // sleep for 1/60th of a second, or about 1 frame.
std::this_thread::sleep_for(std::chrono::milliseconds(16));
auto hit = world.checkIfHit(localRay, 0.001, infinity);
if (hit.first.hit) {
auto object = hit.second;
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 (scatterResults.scattered) { // attenuate the recursive raycast by the material's color
color = color * scatterResults.attenuationColor;
localRay = scatterResults.newRay;
} else {
// 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;
}
} else {
// since we didn't hit, we hit the sky.
color = color * Vec4{0.5, 0.7, 1.0};
//color = Vec4{};
// if we don't hit we cannot keep looping.
break;
}

View File

@ -144,9 +144,9 @@ namespace Raytracing {
if (newRay.x() < EPSILON && newRay.y() < EPSILON && newRay.z() < EPSILON && newRay.w() < EPSILON)
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 (!data)
return Vec4{0.2, 1, 0} * Vec4{u, v, 1.0};
@ -180,6 +180,13 @@ namespace Raytracing {
TexturedMaterial::~TexturedMaterial() {
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){
return i >= 0 ? 1 : -1;