Add Library
This commit is contained in:
parent
e365b9dbd9
commit
3c47103b39
318 changed files with 56465 additions and 0 deletions
151
libraries/bitluni_ESP32Lib/examples/Raytracer/Raytracer.h
Normal file
151
libraries/bitluni_ESP32Lib/examples/Raytracer/Raytracer.h
Normal file
|
@ -0,0 +1,151 @@
|
|||
//cc by-sa 4.0 license
|
||||
//bitluni
|
||||
#pragma once
|
||||
|
||||
class Ray
|
||||
{
|
||||
public:
|
||||
Ray(Vector pos, Vector dir)
|
||||
:p(pos), d(dir)
|
||||
{
|
||||
}
|
||||
Vector p;
|
||||
Vector d;
|
||||
};
|
||||
|
||||
class Raytracable
|
||||
{
|
||||
public:
|
||||
float reflection;
|
||||
Vector c;
|
||||
Raytracable()
|
||||
{
|
||||
reflection = 0;
|
||||
}
|
||||
virtual bool intersection(Ray &ray, Vector &i, float &t) const = 0;
|
||||
virtual Vector normal(Vector &i) const = 0;
|
||||
virtual Vector color(Vector &p) const = 0;
|
||||
};
|
||||
|
||||
class Sphere : public Raytracable
|
||||
{
|
||||
public:
|
||||
float r;
|
||||
float r2;
|
||||
Vector p;
|
||||
Sphere(Vector pos, float radius)
|
||||
:p(pos),
|
||||
r(radius),
|
||||
r2(radius * radius)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool intersection(Ray &ray, Vector &i, float &t) const
|
||||
{
|
||||
Vector L = p - ray.p;
|
||||
float tca = L.dot(ray.d);
|
||||
if(tca < 0) return false;
|
||||
float d2 = L.dot(L) - tca * tca;
|
||||
if (d2 >= r2) return false;
|
||||
float thc = Vector::sqrt(r2 - d2);
|
||||
float ct = tca - thc;
|
||||
if(t <= ct) return false;
|
||||
t = ct;
|
||||
i = ray.p + ray.d * ct;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Vector normal(Vector &i) const
|
||||
{
|
||||
return (i - p) * (1.f / r);
|
||||
}
|
||||
|
||||
virtual Vector color(Vector &p) const
|
||||
{
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
class Checker : public Raytracable
|
||||
{
|
||||
public:
|
||||
Checker()
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool intersection(Ray &ray, Vector &i, float &t) const
|
||||
{
|
||||
if(ray.d[1] >= 0 || ray.p[1] <= 0) return false;
|
||||
float ct = ray.p[1] / -ray.d[1];
|
||||
if(ct >= t) return false;
|
||||
i = Vector(ray.p[0] + ray.d[0] * ct, 0, ray.p[2] + ray.d[2] * ct);
|
||||
t = ct;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual Vector normal(Vector &i) const
|
||||
{
|
||||
return Vector(0, 1, 0);
|
||||
}
|
||||
|
||||
virtual Vector color(Vector &p) const
|
||||
{
|
||||
float c = ((int)p[0] + (int)p[2] + (p[0] >= 0 ? 1 : 0)) & 1;
|
||||
return Vector(0.8 + 0.2 * c, c, c);
|
||||
}
|
||||
};
|
||||
|
||||
const float FAR = 10000;
|
||||
Vector raytrace(Raytracable **objects, int count, Ray &r, Vector &light, int depth, Raytracable *self = 0)
|
||||
{
|
||||
if(depth == 0)
|
||||
return Vector(0, 0, 0);
|
||||
Vector i;
|
||||
float t = FAR;
|
||||
Raytracable *best = 0;
|
||||
for(int n = 0; n < count; n++)
|
||||
{
|
||||
Raytracable *o = objects[n];
|
||||
if(o != self && o->intersection(r, i, t))
|
||||
best = o;
|
||||
}
|
||||
float fog = t * 0.02f;
|
||||
float fc = 0.5f - (r.d[1] < 0 ? 0 : r.d[1]) * 0.5;
|
||||
Vector fogc = Vector(fc, fc, 1.0f);
|
||||
if(fog >= 1) return fogc;
|
||||
if(!best)
|
||||
{
|
||||
return fogc;
|
||||
}
|
||||
Vector n = best->normal(i);
|
||||
float l = light.dot(n) * 0.9;
|
||||
if(l < 0)
|
||||
l = 0;
|
||||
else
|
||||
{
|
||||
Ray r2(i, light);
|
||||
Vector i2;
|
||||
float t2 = FAR;
|
||||
for(int n = 0; n < count; n++)
|
||||
{
|
||||
Raytracable *o = objects[n];
|
||||
if(o == best) continue;
|
||||
if(o->intersection(r2, i2, t2))
|
||||
{
|
||||
l = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Vector c = (best->color(i) * (0.1f + l)) * (1 - fog) + fogc * fog;
|
||||
if(best->reflection == 0)
|
||||
return c;
|
||||
float dn = r.d.dot(n);
|
||||
float fr = (0.2f + (1+dn) * 0.8f) * best->reflection;
|
||||
if(fr < 0) fr = 0;
|
||||
Vector refl = r.d - n * (dn * 2);
|
||||
Ray nr = Ray(i, refl);
|
||||
//return Vector(fr, fr, fr);
|
||||
c = raytrace(objects, count, nr, light, depth - 1, best) * fr + c * (1 - fr);
|
||||
return c;
|
||||
}
|
90
libraries/bitluni_ESP32Lib/examples/Raytracer/Raytracer.ino
Normal file
90
libraries/bitluni_ESP32Lib/examples/Raytracer/Raytracer.ino
Normal file
|
@ -0,0 +1,90 @@
|
|||
//A realtime raytraycer utilizing both cores of the ESP32. Please change the pin configuration in the setup if you are not using VGA v0.1 or the Black Edition shields.
|
||||
//cc by-sa 4.0 license
|
||||
//bitluni
|
||||
|
||||
#include <ESP32Lib.h>
|
||||
#include <Ressources/Font6x8.h>
|
||||
#include <math.h>
|
||||
#include <Math/Matrix.h>
|
||||
#include "Raytracer.h"
|
||||
|
||||
//VGA Device
|
||||
VGA14Bit vga;
|
||||
|
||||
int taskData[2][3] =
|
||||
{
|
||||
{0, 0, 160},
|
||||
{0, 160, 320}
|
||||
};
|
||||
|
||||
static Sphere sphere(Vector(0, 0.5f, 0), 1);
|
||||
static Sphere sphere2(Vector(1, 1.5f, 0.5), 0.5f);
|
||||
static Checker checker;
|
||||
static Raytracable *objects[] = {&sphere, &sphere2, &checker};
|
||||
static Vector light = Vector(5, 4, -5);
|
||||
|
||||
void raytraceTask(void *param)
|
||||
{
|
||||
static Vector p(0, 1, -10);
|
||||
int *data = (int*)param;
|
||||
while(true)
|
||||
{
|
||||
while(!data[0]) delay(1);
|
||||
for(int y = 0; y < 200; y++)
|
||||
for(int x = data[1]; x < data[2]; x++)
|
||||
{
|
||||
Vector v(float(x - 160) * (1.f / 320), float(100 - y) * (1.f / 320), 1.f);
|
||||
v.normalize();
|
||||
Ray r(p, v);
|
||||
Vector c = raytrace(objects, 3, r, light, 3);
|
||||
vga.dotFast(x, y, vga.RGB(c[0] * 255, c[1] * 255, c[2] * 255));
|
||||
}
|
||||
data[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//initial setup
|
||||
void setup()
|
||||
{
|
||||
//we need double buffering for smooth animations
|
||||
vga.setFrameBufferCount(2);
|
||||
//initializing i2s vga
|
||||
//Pin presets are avaialable for: VGAv01, VGABlackEdition, VGAWhiteEdition, PicoVGA
|
||||
//But you can also use custom pins. Check the other examples
|
||||
vga.init(vga.MODE320x200, vga.VGABlackEdition);
|
||||
//setting the font
|
||||
vga.setFont(Font6x8);
|
||||
light.normalize();
|
||||
sphere.reflection = 0.4f;
|
||||
sphere2.reflection = 0.5f;
|
||||
checker.reflection = 0.2f;
|
||||
sphere.c = Vector(0, 1, 0);
|
||||
sphere2.c = Vector(1, 0, 1);
|
||||
static uint8_t ucParameterToPass;
|
||||
TaskHandle_t xHandle = NULL;
|
||||
xTaskCreatePinnedToCore(raytraceTask, "Raytracer1", 2000, taskData[0], ( 2 | portPRIVILEGE_BIT ), &xHandle, 0);
|
||||
xTaskCreatePinnedToCore(raytraceTask, "Raytracer2", 2000, taskData[1], ( 2 | portPRIVILEGE_BIT ), &xHandle, 1);
|
||||
}
|
||||
|
||||
//the loop is done every frame
|
||||
void loop()
|
||||
{
|
||||
taskData[0][0] = 1;
|
||||
taskData[1][0] = 1;
|
||||
//waiting for task to finish
|
||||
while(taskData[0][0] || taskData[1][0]) delay(1);
|
||||
sphere2.p.v[0] = sin(millis() * 0.0005f) * 2;
|
||||
sphere2.p.v[2] = cos(millis() * 0.0005f) * 2;
|
||||
sphere.p.v[1] = sphere2.p[0] * 0.3 + 1;
|
||||
//setting the text cursor to the lower left corner of the screen
|
||||
vga.setCursor(0, 0);
|
||||
//setting the text color to white with opaque black background
|
||||
vga.setTextColor(vga.RGB(0xffffff), vga.RGBA(0, 0, 0, 0));
|
||||
//printing the fps
|
||||
vga.print("ms/frame: ");
|
||||
static long t = 0;
|
||||
long ct = millis();
|
||||
vga.print(ct - t);
|
||||
t = ct;
|
||||
vga.show();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue