Fixed the way lights were linked to opencl, did some tweaking of the phong lighting.

master
MitchellHansen 8 years ago
parent 7d7ed5367c
commit 129e475b15

@ -1,6 +1,6 @@
#pragma once
#include <SFML/System/Vector3.hpp>
#include <SFML/System/Vector2.hpp>
#include <SFML/System/Vector2.hpp>
#include "util.hpp"
#include "Pub_Sub.h"
@ -10,7 +10,7 @@ public:
enum DIRECTION { FORWARD, REARWARD, LEFT, RIGHT, UP, DOWN };
Camera();
Camera(sf::Vector3f position, sf::Vector2f direction);
Camera(sf::Vector3f position, sf::Vector2f direction, sf::RenderWindow *window);
~Camera();
int set_position(sf::Vector3f position);
@ -50,5 +50,12 @@ private:
// These are spherical coords
sf::Vector2f direction;
bool mouse_enabled = true;
sf::Vector2i deltas;
sf::Vector2i fixed;
sf::Vector2i prev_pos;
sf::RenderWindow *window;
};

@ -50,7 +50,7 @@ public:
// Both will create the view matrix, view res buffer
void create_viewport(int width, int height, float v_fov, float h_fov) override;
void assign_lights(std::vector<Light> lights) override;
void assign_lights(std::vector<Light> *lights) override;
void assign_map(Old_Map *map) override;
void assign_camera(Camera *camera) override;
void validate() override;
@ -60,6 +60,8 @@ public:
void compute() override;
void draw(sf::RenderWindow* window) override;
void test_edit_viewport(int width, int height, float v_fov, float h_fov);
private:

@ -24,7 +24,7 @@ public:
virtual void assign_map(Old_Map *map) = 0;
virtual void assign_camera(Camera *camera) = 0;
virtual void create_viewport(int width, int height, float v_fov, float h_fov) = 0;
virtual void assign_lights(std::vector<Light> lights) = 0;
virtual void assign_lights(std::vector<Light> *lights) = 0;
virtual void validate() = 0;
// draw will abstract the gl sharing and software rendering
@ -39,7 +39,7 @@ protected:
Old_Map * map = nullptr;
Camera *camera = nullptr;
std::vector<Light> lights;
std::vector<Light> *lights;
int light_count = 0;
sf::Uint8 *viewport_image = nullptr;
sf::Vector4f *viewport_matrix = nullptr;

@ -15,7 +15,7 @@ public:
// Both will create the view matrix, view res buffer
void create_viewport(int width, int height, float v_fov, float h_fov) override;
void assign_lights(std::vector<Light> lights) override;
void assign_lights(std::vector<Light> *lights) override;
void assign_map(Old_Map *map) override;
void assign_camera(Camera *camera) override;
void validate() override;

@ -5,7 +5,7 @@ float4 white_light(float4 input, float3 light, int3 mask) {
input.w = input.w + acos(
dot(
normalize(light),
normalize(fabs(convert_float3(mask)))
normalize(convert_float3(mask * (-mask)))
)
) / 2;
@ -13,6 +13,31 @@ float4 white_light(float4 input, float3 light, int3 mask) {
}
float4 view_light(float4 in_color, float3 light, float3 view, int3 mask) {
float diffuse = max(dot(normalize(convert_float3(mask)), normalize(light)), 0.0f);
if (dot(light, normalize(convert_float3(mask))) > 0.0)
{
float3 halfwayVector = normalize(normalize(light) + normalize(view));
float specTmp = max(dot(normalize(convert_float3(mask)), halfwayVector), 0.0f);
return in_color + pow(specTmp, 1.0f) * 0.01 +diffuse * 0.5;
}
//float3 halfwayDir = normalize(normalize(view) + normalize(light));
//float spec = pow(max(dot(normalize(convert_float3(mask)), halfwayDir), 0.0f), 32.0f);
in_color.w += 0.2;
return in_color;
}
void cast_ray(float3 ray_origin, float3 ray_direction) {
}
// 0 1 2 3 4 5 6 7 8 9
// {r, g, b, i, x, y, z, x', y', z'}
@ -99,21 +124,21 @@ __kernel void raycaster(
global int* seed_memory
){
// Get and set the random seed from seed memory
int global_id = get_global_id(0);
// Get and set the random seed from seed memory
int seed = seed_memory[global_id];
int random_number = rand(&seed);
seed_memory[global_id] = seed;
size_t id = get_global_id(0);
int2 pixel = {id % (*resolution).x, id / (*resolution).x};
// Get the pixel on the viewport, and find the view matrix ray that matches it
int2 pixel = { global_id % (*resolution).x, global_id / (*resolution).x};
float3 ray_dir = projection_matrix[pixel.x + (*resolution).x * pixel.y];
if (pixel.x == 960 && pixel.y == 540) {
write_imagef(image, pixel, (float4)(0.00, 1.00, 0.00, 1.00));
return;
}
//if (pixel.x == 960 && pixel.y == 540) {
// write_imagef(image, pixel, (float4)(0.00, 1.00, 0.00, 1.00));
// return;
//}
// Pitch
ray_dir = (float3)(
@ -160,67 +185,53 @@ __kernel void raycaster(
intersection_t.z += delta_t.z;
}
// use a ghetto ass rng to give rays a "fog" appearance
int2 randoms = { random_number, 14 };
uint tseed = randoms.x + id;
uint t = tseed ^ (tseed << 11);
uint result = randoms.y ^ (randoms.y >> 19) ^ (t ^ (t >> 8));
int max_dist = 800 + result % 100;
// Hard cut-off for how far the ray can travel
int max_dist = 800;
int dist = 0;
int3 mask = { 0, 0, 0 };
float4 color = { 0.73, 0.81, 0.89, 0.6 };
float4 c = (float4)(0.60, 0.00, 0.40, 0.1);
c.x += (result % 100) / 10;
int3 face_mask = { 0, 0, 0 };
float4 fog_color = { 0.73, 0.81, 0.89, 0.8 };
float4 voxel_color = (float4)(0.25, 0.52, 0.30, 0.1);
float4 overshoot_color = { 0.25, 0.48, 0.52, 0.8 };
// Andrew Woo's raycasting algo
do {
mask = intersection_t.xyz <= min(intersection_t.yzx, intersection_t.zxy);
intersection_t += delta_t * fabs(convert_float3(mask.xyz));
voxel.xyz += voxel_step.xyz * mask.xyz;
// Fancy no branch version of the logic step
face_mask = intersection_t.xyz <= min(intersection_t.yzx, intersection_t.zxy);
intersection_t += delta_t * fabs(convert_float3(face_mask.xyz));
voxel.xyz += voxel_step.xyz * face_mask.xyz;
// If the ray went out of bounds
int3 overshoot = voxel <= *map_dim;
int3 undershoot = voxel > 0;
if (overshoot.x == 0 || overshoot.y == 0 || overshoot.z == 0 || undershoot.x == 0 || undershoot.y == 0){
write_imagef(image, pixel, white_light(mix(color, (float4)(0.40, 0.00, 0.40, 0.2), 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), mask));
write_imagef(image, pixel, white_light(mix(fog_color, overshoot_color, 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), face_mask));
return;
}
if (undershoot.z == 0) {
write_imagef(image, pixel, white_light(mix(color, (float4)(0.40, 0.00, 0.40, 0.2), 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), mask));
write_imagef(image, pixel, white_light(mix(fog_color, overshoot_color, 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), face_mask));
return;
}
// If we hit a voxel
//int index = voxel.x * (*map_dim).y * (*map_dim).z + voxel.z * (*map_dim).z + voxel.y;
int index = voxel.x + (*map_dim).x * (voxel.y + (*map_dim).z * (voxel.z));
int voxel_data = map[index];
if (voxel_data != 0) {
switch (voxel_data) {
case 1:
write_imagef(image, pixel, (float4)(.50, .00, .00, 1));
return;
case 2:
write_imagef(image, pixel, (float4)(.00, .50, .40, 1.00));
return;
case 3:
write_imagef(image, pixel, (float4)(.00, .00, .50, 1.00));
return;
case 4:
write_imagef(image, pixel, (float4)(.25, .00, .25, 1.00));
return;
case 5:
//write_imagef(image, pixel, (float4)(0.40, 0.00, 0.40, 0.2));
write_imagef(image, pixel, white_light(mix(color, c, 1.0 - max((dist/700.0f) - 0.3f, (float)0)), (float3)(lights[7], lights[8], lights[9]), mask));
write_imagef(image, pixel, view_light(voxel_color, (convert_float3(voxel) + offset) - (float3)(lights[4], lights[5], lights[6]), (convert_float3(voxel) + offset) - (*cam_pos), face_mask));
//write_imagef(image, pixel, white_light(mix(fog_color, voxel_color, 1.0 - max((dist/700.0f) - 0.3f, (float)0)), (float3)(lights[7], lights[8], lights[9]), face_mask));
return;
float3 vox = convert_float3(voxel);
float3 norm = normalize(convert_float3(mask) * convert_float3(voxel_step));
float3 norm = normalize(convert_float3(face_mask) * convert_float3(voxel_step));
float4 color = (float4)(0.95, 0.00, 0.25, 1.00);
@ -235,12 +246,16 @@ __kernel void raycaster(
));
return;
case 6:
write_imagef(image, pixel, (float4)(.30, .80, .10, 1.00));
write_imagef(image, pixel, view_light((float4)(0.0, 0.239, 0.419, 0.3), (convert_float3(voxel) + offset) - (float3)(lights[4], lights[5], lights[6]), (convert_float3(voxel) + offset) - (*cam_pos), face_mask));
//write_imagef(image, pixel, white_light(mix((float4)(0.73, 0.81, 0.89, 0.6), (float4)(0.0, 0.239, 0.419, 0.3), 1.0 - max((dist / 700.0f) - 0.3f, (float)0)), (float3)(lights[7], lights[8], lights[9]), face_mask));
return;
default:
//write_imagef(image, pixel, (float4)(.30, .10, .10, 1.00));
write_imagef(image, pixel, (float4)(.30, .10, .10, 1.00));
continue;
}
}
@ -249,7 +264,7 @@ __kernel void raycaster(
} while (dist / 700.0f < 1);
//dist < max_dist
write_imagef(image, pixel, white_light(mix(color, (float4)(0.40, 0.00, 0.40, 0.2), 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), mask));
write_imagef(image, pixel, white_light(mix(fog_color, (float4)(0.40, 0.00, 0.40, 0.2), 1.0 - max(dist / 700.0f, (float)0)), (float3)(lights[7], lights[8], lights[9]), face_mask));
//write_imagef(image, pixel, (float4)(.73, .81, .89, 1.0));
return;
}

@ -7,10 +7,10 @@ Camera::Camera() {
}
Camera::Camera(sf::Vector3f position, sf::Vector2f direction) :
position(position), direction(direction)
Camera::Camera(sf::Vector3f position, sf::Vector2f direction, sf::RenderWindow* window) :
position(position), direction(direction), window(window)
{
fixed = sf::Vector2i(sf::Vector2i(window->getSize().x/2, window->getSize().y/2));
}
Camera::~Camera() {
@ -124,6 +124,36 @@ void Camera::recieve_event(VrEventPublisher* publisher, std::unique_ptr<vr::Even
}
}
else if (event->type == vr::Event::KeyHeld) {
vr::KeyPressed *key_event = static_cast<vr::KeyPressed*>(event.get());
if (key_event->code == sf::Keyboard::M) {
if (mouse_enabled)
mouse_enabled = false;
else
mouse_enabled = true;
}
}
else if (event->type == vr::Event::MouseMoved) {
if (mouse_enabled) {
vr::MouseMoved *mouse_event = static_cast<vr::MouseMoved*>(event.get());
//deltas = fixed - sf::Mouse::getPosition();
deltas = fixed - sf::Vector2i(mouse_event->x, mouse_event->y);
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
sf::Mouse::setPosition(fixed, *window);
slew_camera(sf::Vector2f(
deltas.y / 1200.0f,
deltas.x / 1200.0f
));
}
}
}
}

@ -158,7 +158,7 @@ void Hardware_Caster::create_viewport(int width, int height, float v_fov, float
}
}
create_buffer("viewport_matrix", sizeof(float) * 4 * view_res.x * view_res.y, viewport_matrix);
create_buffer("viewport_matrix", sizeof(float) * 4 * view_res.x * view_res.y, viewport_matrix, CL_MEM_USE_HOST_PTR);
// Create the image that opencl's rays write to
viewport_image = new sf::Uint8[width * height * 4];
@ -181,15 +181,13 @@ void Hardware_Caster::create_viewport(int width, int height, float v_fov, float
}
void Hardware_Caster::assign_lights(std::vector<Light> lights) {
void Hardware_Caster::assign_lights(std::vector<Light> *lights) {
std::cout << sizeof(Light);
this->lights = lights;
this->lights = std::vector<Light>(lights);
light_count = static_cast<int>(lights->size());
light_count = static_cast<int>(lights.size());
create_buffer("lights", sizeof(float) * 10 * light_count, this->lights.data(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
create_buffer("lights", sizeof(float) * 10 * light_count, this->lights->data(), CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR);
create_buffer("light_count", sizeof(int), &light_count);
@ -199,6 +197,53 @@ void Hardware_Caster::draw(sf::RenderWindow* window) {
window->draw(viewport_sprite);
}
void Hardware_Caster::test_edit_viewport(int width, int height, float v_fov, float h_fov)
{
sf::Vector2i view_res(width, height);
double y_increment_radians = DegreesToRadians(v_fov / view_res.y);
double x_increment_radians = DegreesToRadians(h_fov / view_res.x);
for (int y = -view_res.y / 2; y < view_res.y / 2; y++) {
for (int x = -view_res.x / 2; x < view_res.x / 2; x++) {
// The base ray direction to slew from
sf::Vector3f ray(1, 0, 0);
// Y axis, pitch
ray = sf::Vector3f(
static_cast<float>(ray.z * sin(y_increment_radians * y) + ray.x * cos(y_increment_radians * y)),
static_cast<float>(ray.y),
static_cast<float>(ray.z * cos(y_increment_radians * y) - ray.x * sin(y_increment_radians * y))
);
// Z axis, yaw
ray = sf::Vector3f(
static_cast<float>(ray.x * cos(x_increment_radians * x) - ray.y * sin(x_increment_radians * x)),
static_cast<float>(ray.x * sin(x_increment_radians * x) + ray.y * cos(x_increment_radians * x)),
static_cast<float>(ray.z)
);
// correct for the base ray pointing to (1, 0, 0) as (0, 0). Should equal (1.57, 0)
ray = sf::Vector3f(
static_cast<float>(ray.z * sin(-1.57) + ray.x * cos(-1.57)),
static_cast<float>(ray.y),
static_cast<float>(ray.z * cos(-1.57) - ray.x * sin(-1.57))
);
int index = (x + view_res.x / 2) + view_res.x * (y + view_res.y / 2);
ray = Normalize(ray);
viewport_matrix[index] = sf::Vector4f(
ray.x,
ray.y,
ray.z,
0
);
}
}
}
int Hardware_Caster::acquire_platform_and_device() {
// Get the number of platforms

@ -40,6 +40,8 @@ void Input::handle_held_keys() {
// When they are depressed, remove them
for (auto&& event: event_queue) {
// Key
if (event->type == vr::Event::KeyPressed) {
vr::KeyPressed *e = static_cast<vr::KeyPressed*>(event.get());
held_keys.push_back(e->code);
@ -48,6 +50,8 @@ void Input::handle_held_keys() {
vr::KeyReleased *e = static_cast<vr::KeyReleased*>(event.get());
held_keys.erase(std::remove(held_keys.begin(), held_keys.end(), e->code), held_keys.end());
}
// Mouse Button
else if (event->type == vr::Event::MouseButtonPressed) {
vr::MouseButtonPressed *e = static_cast<vr::MouseButtonPressed*>(event.get());
held_mouse_buttons.push_back(e->button);

@ -138,14 +138,14 @@ void Old_Map::generate_terrain() {
}
//for (int x = 0; x < dimensions.x / 10; x++) {
// for (int y = 0; y < dimensions.y / 10; y++) {
for (int x = 0; x < dimensions.x; x++) {
for (int y = 0; y < dimensions.y; y++) {
// for (int z = 0; z < dimensions.z; z++) {
// if (rand() % 1000 < 1)
// voxel_data[x + dimensions.x * (y + dimensions.z * z)] = rand() % 6;
//if (rand() % 1000 < 1)
voxel_data[x + dimensions.x * (y + dimensions.z * 1)] = 6;
// }
// }
//}
}
}
}

@ -82,10 +82,10 @@ void Software_Caster::create_viewport(int width, int height, float v_fov, float
}
void Software_Caster::assign_lights(std::vector<Light> lights) {
this->lights = std::vector<Light>(lights);
void Software_Caster::assign_lights(std::vector<Light> *lights) {
this->lights = lights;
int light_count = static_cast<int>(lights.size());
int light_count = static_cast<int>(lights->size());
}
void Software_Caster::assign_map(Old_Map * map) {
@ -330,7 +330,7 @@ sf::Color Software_Caster::global_light(sf::Color in, sf::Vector3i mask) {
in.a = in.a + (int)acos(
DotProduct(
Normalize(lights.at(0).direction_cartesian),
Normalize(lights->at(0).direction_cartesian),
Normalize(mask_f)
)
)/ 2;

@ -36,8 +36,8 @@
#include "Input.h"
#include "Pub_Sub.h"
const int WINDOW_X = 1920;
const int WINDOW_Y = 1080;
const int WINDOW_X = 1000;
const int WINDOW_Y = 1000;
const int WORK_SIZE = WINDOW_X * WINDOW_Y;
const int MAP_X = 512;
@ -70,51 +70,64 @@ int main() {
//Map _map(sf::Vector3i(0, 0, 0));
//_map.generate_octree();
glewInit();
sf::RenderWindow window(sf::VideoMode(WINDOW_X, WINDOW_Y), "SFML");
window.setMouseCursorVisible(false);
GL_Testing t;
/*GL_Testing t;
t.compile_shader("../shaders/passthrough.frag", GL_Testing::Shader_Type::FRAGMENT);
t.compile_shader("../shaders/passthrough.vert", GL_Testing::Shader_Type::VERTEX);
t.create_program();
t.create_buffers();
t.create_buffers();*/
RayCaster *rc = new Hardware_Caster();
// Start up the raycaster
Hardware_Caster *raycaster = new Hardware_Caster();
if (rc->init() != 1) {
if (raycaster->init() != 1) {
abort();
}
// Set up the raycaster
std::cout << "map...";
sf::Vector3i map_dim(MAP_X, MAP_Y, MAP_Z);
Old_Map* map = new Old_Map(map_dim);
// Create and generate the old 3d array style map
Old_Map* map = new Old_Map(sf::Vector3i(MAP_X, MAP_Y, MAP_Z));
map->generate_terrain();
rc->assign_map(map);
// Send the data to the GPU
raycaster->assign_map(map);
// Create a new camera with (starting position, direction)
Camera *camera = new Camera(
sf::Vector3f(50, 50, 50),
sf::Vector2f(0.0f, 1.5707f)
sf::Vector2f(1.5f, 0.0f),
&window
);
rc->assign_camera(camera);
rc->create_viewport(WINDOW_X, WINDOW_Y, 50.0f, 80.0f);
// *link* the camera to the GPU
raycaster->assign_camera(camera);
// Generate and send the viewport to the GPU. Also creates the viewport texture
raycaster->create_viewport(WINDOW_X, WINDOW_Y, 50.0f, 50.0f);
float w = 60.0;
float h = 90.0;
// Light for the currently non functional Bling Phong shader
Light l;
l.direction_cartesian = sf::Vector3f(1.5f, 1.2f, 0.5f);
l.direction_cartesian = sf::Vector3f(+1.5f, -1.2f, -0.5f);
l.position = sf::Vector3f(100.0f, 100.0f, 100.0f);
l.rgbi = sf::Vector4f(0.3f, 0.4f, 0.3f, 1.0f);
rc->assign_lights(std::vector<Light>{l});
std::vector<Light> light_vec;
light_vec.push_back(l);
// *links* the lights to the GPU
raycaster->assign_lights(&light_vec);
// Checks to see if proper data was uploaded, then sets the kernel args
raycaster->validate();
rc->validate();
// Done setting up raycaster
// ========== DEBUG ==========
fps_counter fps;
@ -145,7 +158,9 @@ int main() {
Input input_handler;
input_handler.subscribe(camera, vr::Event::EventType::KeyHeld);
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::KeyHeld);
camera->subscribe_to_publisher(&input_handler, vr::Event::EventType::MouseMoved);
WindowHandler win_hand(&window);
win_hand.subscribe_to_publisher(&input_handler, vr::Event::EventType::Closed);
@ -157,46 +172,15 @@ int main() {
input_handler.consume_sf_events(&window);
input_handler.handle_held_keys();
input_handler.dispatch_events();
// Poll for events from the user
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::M) {
if (mouse_enabled)
mouse_enabled = false;
else
mouse_enabled = true;
} if (event.key.code == sf::Keyboard::R) {
reset = true;
} if (event.key.code == sf::Keyboard::X) {
std::vector<float> tvf = sfml_get_float_input(&window);
if (tvf.size() == 3){
sf::Vector3f tv3(tvf.at(0), tvf.at(1), tvf.at(2));
camera->set_position(tv3);
}
}
}
}
if (mouse_enabled) {
if (reset) {
reset = false;
sf::Mouse::setPosition(sf::Vector2i(2560/2, 1080/2));
prev_pos = sf::Vector2i(2560 / 2, 1080 / 2);
}
deltas = prev_pos - sf::Mouse::getPosition();
if (deltas != sf::Vector2i(0, 0) && mouse_enabled == true) {
// Mouse movement
sf::Mouse::setPosition(fixed);
prev_pos = sf::Mouse::getPosition();
camera->slew_camera(sf::Vector2f(
deltas.y / 600.0f,
deltas.x / 600.0f
));
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Equal)) {
raycaster->test_edit_viewport(WINDOW_X, WINDOW_Y, w += 5, h += 5);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Dash)) {
raycaster->test_edit_viewport(WINDOW_X, WINDOW_Y, w -= 5, h -= 5);
}
if (sf::Keyboard::isKeyPressed(sf::Keyboard::L)) {
light_vec.at(0).position.y += 0.5;
}
// Time keeping
@ -218,8 +202,8 @@ int main() {
window.clear(sf::Color::Black);
// Run the raycast
rc->compute();
rc->draw(&window);
raycaster->compute();
raycaster->draw(&window);
window.popGLStates();

Loading…
Cancel
Save