Bin packing
parent
d4a9d729a0
commit
74967c11b6
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
protected:
|
||||
int width{}, height{}, channels{};
|
||||
|
@ -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();
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue