General Purpose library for Freestanding C++ and POSIX systems
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 

76 行
1.7 KiB

#pragma once
#include "gp_config.hpp"
#include "gp/math.hpp"
#include "gp/function.hpp"
#include "gp/algorithm/min_of.hpp"
#include "gp/indexed_array.hpp"
using vec2 = gp::vec2_g<>;
using vec3 = gp::vec3_g<>;
using vec4 = gp::vec4_g<>;
struct camera{
vec3 position;
vec3 normal;
};
using index_t = size_t;
using distance_t = gp_config::rendering::default_type;
using color_t = GP_CONFIG__RENDERING__COLOR_T;
struct render_point{
distance_t distance;
index_t material;
bool operator<(const render_point& rhs) {
return distance < rhs.distance;
}
};
using sdf_t = gp::function<render_point(vec3)>;
using material_t = gp::function<color_t(vec3)>;
class renderer {
using g_t = gp_config::rendering::default_type;
constexpr static auto epsilon = gp_config::rendering::epsilon;
public:
gp::indexed_array<sdf_t, 4096> scene_elements;
gp::indexed_array<material_t, 4096> materials;
material_t sky_box = [](vec3) -> color_t { return vec4{0,0,0,0};};
vec2 _resolution{128,64};
camera _camera{{0, 0, -1}, {0, 0, 0}};
vec2 _fov{90, 45};
distance_t projection_start = 1;
distance_t projection_end = 50;
size_t passes = 12;
renderer() = default;
color_t render(vec2 pixel) {
g_t depth = projection_start;
vec3 target{0,0,0};
target = target.normalize();
vec3 render_target{_camera.position};
for(int i = 0; i < passes; ++i) {
render_target = _camera.position+depth*target;
render_point distance = gp::min_of(
scene_elements.begin(),
scene_elements.end(),
[&](auto& p){
return p(render_target);
}
);
if(distance.distance < epsilon) {
return materials[distance.material](render_target);
}
depth += distance.distance;
if(depth >= projection_end) {
break;
}
}
return sky_box(render_target);
}
};