reorganize lamp related code.
This commit is contained in:
parent
27419f73b5
commit
bc0c2c8c73
|
@ -9,7 +9,10 @@ Camera::Camera(const Vector3d &up)
|
||||||
: gaze_(Vector3d::Identity()), up_(up), camera_speed_(0.3) {}
|
: gaze_(Vector3d::Identity()), up_(up), camera_speed_(0.3) {}
|
||||||
|
|
||||||
Camera::Camera(const Vector3d &up, const float camera_speed)
|
Camera::Camera(const Vector3d &up, const float camera_speed)
|
||||||
: gaze_(Vector3d::Identity()), up_(up), camera_speed_(camera_speed) {}
|
: gaze_(Vector3d{0, 0, 1}), up_(up), camera_speed_(camera_speed) {
|
||||||
|
spdlog::debug("Gaze: ({}, {}, {}), Up: ({}, {}, {})", gaze_.x(), gaze_.y(),
|
||||||
|
gaze_.z(), up_.x(), up_.y(), up_.z());
|
||||||
|
}
|
||||||
|
|
||||||
void Camera::move(const Point3d &offset) {
|
void Camera::move(const Point3d &offset) {
|
||||||
position_ = (offset * camera_speed_);
|
position_ = (offset * camera_speed_);
|
||||||
|
|
|
@ -21,11 +21,3 @@ typedef struct Vertex {
|
||||||
Vector3d normal;
|
Vector3d normal;
|
||||||
Point2d texture_coordinate; // Of course, in world space
|
Point2d texture_coordinate; // Of course, in world space
|
||||||
} Vertex;
|
} Vertex;
|
||||||
|
|
||||||
typedef struct Lamp {
|
|
||||||
Lamp(const Point3d &pos, const double intensity)
|
|
||||||
: position(pos), intensity(intensity) {}
|
|
||||||
|
|
||||||
Point3d position;
|
|
||||||
double intensity;
|
|
||||||
} Lamp;
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright 2024 Bytedance Inc. All Rights Reserved.
|
||||||
|
// Author: tianlei.richard@bytedance.com (tianlei.richard)
|
||||||
|
|
||||||
|
#include "lamp.h"
|
||||||
|
|
||||||
|
PointLamp::PointLamp(const Point3d &pos, const double intensity)
|
||||||
|
: position_(pos), intensity_(intensity) {}
|
||||||
|
|
||||||
|
double PointLamp::get_intensity() const { return intensity_; }
|
||||||
|
|
||||||
|
const Point3d &PointLamp::get_position() const { return position_; }
|
||||||
|
|
||||||
|
void PointLamp::transform(const TransformMatrix &mtx) {
|
||||||
|
position_ = (mtx * position_.homogeneous()).hnormalized();
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// Copyright 2024 Bytedance Inc. All Rights Reserved.
|
||||||
|
// Author: tianlei.richard@bytedance.com (tianlei.richard)
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
class PointLamp {
|
||||||
|
public:
|
||||||
|
PointLamp(const Point3d &pos, const double intensity);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void transform(const TransformMatrix &mtx);
|
||||||
|
|
||||||
|
double get_intensity() const;
|
||||||
|
const Point3d &get_position() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Point3d position_;
|
||||||
|
double intensity_;
|
||||||
|
};
|
|
@ -34,11 +34,11 @@ int main(int argc, char *argv[]) {
|
||||||
const std::string obj_path{result["obj"].as<std::string>()};
|
const std::string obj_path{result["obj"].as<std::string>()};
|
||||||
const std::string diffuse_map_path{result["diffuse_map"].as<std::string>()};
|
const std::string diffuse_map_path{result["diffuse_map"].as<std::string>()};
|
||||||
|
|
||||||
const int resolution_width = 1280;
|
const int resolution_width = 960;
|
||||||
const int resolution_height = 720;
|
const int resolution_height = 540;
|
||||||
const int far = -100;
|
const int far = -1000;
|
||||||
const int near = -1;
|
const int near = -1;
|
||||||
const float fov = 120. / 180. * M_PI;
|
const float fov = 150. / 180. * M_PI;
|
||||||
const float aspect_ratio = static_cast<float>(resolution_width) /
|
const float aspect_ratio = static_cast<float>(resolution_width) /
|
||||||
static_cast<float>(resolution_height);
|
static_cast<float>(resolution_height);
|
||||||
|
|
||||||
|
@ -111,6 +111,7 @@ int main(int argc, char *argv[]) {
|
||||||
MinusRenderer renderer{near, far, fov, aspect_ratio};
|
MinusRenderer renderer{near, far, fov, aspect_ratio};
|
||||||
renderer.set_meshes(
|
renderer.set_meshes(
|
||||||
Mesh::load_mesh(obj_path, {{Texture::DiffuseMap, diffuse_map_path}}));
|
Mesh::load_mesh(obj_path, {{Texture::DiffuseMap, diffuse_map_path}}));
|
||||||
|
renderer.set_lamps({std::make_shared<PointLamp>(Point3d{1, 1, -1}, 6.)});
|
||||||
TransformMatrix translate{
|
TransformMatrix translate{
|
||||||
{1., 0., 0., 3.}, {0., 1., 0., 3.}, {0., 0., 1., -5.}, {0., 0., 0., 1.}};
|
{1., 0., 0., 3.}, {0., 1., 0., 3.}, {0., 0., 1., -5.}, {0., 0., 0., 1.}};
|
||||||
renderer.model_transform(translate);
|
renderer.model_transform(translate);
|
||||||
|
|
|
@ -87,8 +87,7 @@ std::vector<Mesh> Mesh::load_mesh(
|
||||||
std::make_shared<Texture>(material_directory /
|
std::make_shared<Texture>(material_directory /
|
||||||
mesh.MeshMaterial.map_Kd)});
|
mesh.MeshMaterial.map_Kd)});
|
||||||
}
|
}
|
||||||
auto material = std::make_shared<PhoneMaterial>(
|
auto material = std::make_shared<PhoneMaterial>(textures);
|
||||||
textures, std::make_shared<Lamp>(Point3d{}, 16.));
|
|
||||||
|
|
||||||
res.push_back(Mesh(vertices, indices, material));
|
res.push_back(Mesh(vertices, indices, material));
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
|
|
||||||
#include "minus_renderer.h"
|
#include "minus_renderer.h"
|
||||||
#include "rasterizer.h"
|
|
||||||
|
|
||||||
MinusRenderer::MinusRenderer(float near, float far, float fov,
|
MinusRenderer::MinusRenderer(float near, float far, float fov,
|
||||||
float aspect_ratio)
|
float aspect_ratio)
|
||||||
: near_(near), far_(far), fov_(fov), aspect_ratio_(aspect_ratio) {
|
: near_(near), far_(far), fov_(fov), aspect_ratio_(aspect_ratio),
|
||||||
|
rasterizer_(std::make_unique<Rasterizer>()) {
|
||||||
spdlog::info("near: {}, far: {}, fov: {}, aspect ratio: {}", near_, far_,
|
spdlog::info("near: {}, far: {}, fov: {}, aspect ratio: {}", near_, far_,
|
||||||
fov_, aspect_ratio_);
|
fov_, aspect_ratio_);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,11 @@ void MinusRenderer::set_meshes(const std::vector<Mesh> &meshes) {
|
||||||
meshes_ = meshes;
|
meshes_ = meshes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MinusRenderer::set_lamps(
|
||||||
|
const std::vector<std::shared_ptr<PointLamp>> &lamps) {
|
||||||
|
lamps_ = lamps;
|
||||||
|
}
|
||||||
|
|
||||||
float MinusRenderer::calculate_height(const float fov, const float near) {
|
float MinusRenderer::calculate_height(const float fov, const float near) {
|
||||||
return std::fabs(near) * std::tan(fov * 0.5) * 2;
|
return std::fabs(near) * std::tan(fov * 0.5) * 2;
|
||||||
}
|
}
|
||||||
|
@ -33,16 +38,15 @@ std::pair<TransformMatrix, TransformMatrix>
|
||||||
MinusRenderer::construct_transform(const int resolution_width,
|
MinusRenderer::construct_transform(const int resolution_width,
|
||||||
const int resolution_height) const {
|
const int resolution_height) const {
|
||||||
// Squish Transform
|
// Squish Transform
|
||||||
const auto &squish_transform =
|
const TransformMatrix &squish_transform{{near_, 0, 0, 0},
|
||||||
TransformMatrix{{near_, 0, 0, 0},
|
{0, near_, 0, 0},
|
||||||
{0, near_, 0, 0},
|
{0, 0, near_ + far_, -near_ * far_},
|
||||||
{0, 0, near_ + far_, -near_ * far_},
|
{0, 0, 1, 0}};
|
||||||
{0, 0, 1, 0}};
|
const TransformMatrix &inv_squish_transform{
|
||||||
const auto &inv_squish_transform =
|
{1, 0, 0, 0},
|
||||||
TransformMatrix{{1, 0, 0, 0},
|
{0, 1, 0, 0},
|
||||||
{0, 1, 0, 0},
|
{0, 0, 0, near_},
|
||||||
{0, 0, 0, near_},
|
{0, 0, -1. / far_, (near_ + far_) / far_}};
|
||||||
{0, 0, -1. / far_, (near_ + far_) / far_}};
|
|
||||||
|
|
||||||
// Orthographic transform
|
// Orthographic transform
|
||||||
const float height = calculate_height(fov_, near_);
|
const float height = calculate_height(fov_, near_);
|
||||||
|
@ -52,7 +56,7 @@ MinusRenderer::construct_transform(const int resolution_width,
|
||||||
const float top = height * 0.5;
|
const float top = height * 0.5;
|
||||||
const float bottom = -top;
|
const float bottom = -top;
|
||||||
|
|
||||||
const auto &ortho_transform =
|
const TransformMatrix &ortho_transform =
|
||||||
TransformMatrix{{2 / (right - left), 0, 0, 0},
|
TransformMatrix{{2 / (right - left), 0, 0, 0},
|
||||||
{0, 2 / (top - bottom), 0, 0},
|
{0, 2 / (top - bottom), 0, 0},
|
||||||
{0, 0, 2 / std::fabs(far_ - near_), 0},
|
{0, 0, 2 / std::fabs(far_ - near_), 0},
|
||||||
|
@ -61,19 +65,19 @@ MinusRenderer::construct_transform(const int resolution_width,
|
||||||
{0, 1, 0, -0.5 * (top - bottom)},
|
{0, 1, 0, -0.5 * (top - bottom)},
|
||||||
{0, 0, 1, -0.5 * (far_ - near_)},
|
{0, 0, 1, -0.5 * (far_ - near_)},
|
||||||
{0, 0, 0, 1}};
|
{0, 0, 0, 1}};
|
||||||
const auto &inv_ortho_transform = TransformMatrix{
|
const TransformMatrix &inv_ortho_transform{
|
||||||
{(right - left) / 2., 0, 0, 0.5 * (right - left)},
|
{(right - left) / 2., 0, 0, 0.5 * (right - left)},
|
||||||
{0, (top - bottom) / 2., 0, 0.5 * (top - bottom)},
|
{0, (top - bottom) / 2., 0, 0.5 * (top - bottom)},
|
||||||
{0, 0, std::fabs(far_ - near_) / 2., 0.5 * (far_ - near_)},
|
{0, 0, std::fabs(far_ - near_) / 2., 0.5 * (far_ - near_)},
|
||||||
{0, 0, 0, 1}};
|
{0, 0, 0, 1}};
|
||||||
|
|
||||||
// View port transform
|
// View port transform
|
||||||
const auto &view_port_transform =
|
const TransformMatrix &view_port_transform{
|
||||||
TransformMatrix{{resolution_width / 2., 0, 0, resolution_width * 0.5},
|
{resolution_width / 2., 0, 0, resolution_width * 0.5},
|
||||||
{0, resolution_height / 2., 0, resolution_height * 0.5},
|
{0, resolution_height / 2., 0, resolution_height * 0.5},
|
||||||
{0, 0, 1, 0},
|
{0, 0, 1, 0},
|
||||||
{0, 0, 0, 1}};
|
{0, 0, 0, 1}};
|
||||||
const auto &inv_view_port_transform =
|
const TransformMatrix &inv_view_port_transform =
|
||||||
TransformMatrix{{2. / resolution_width, 0, 0, 0},
|
TransformMatrix{{2. / resolution_width, 0, 0, 0},
|
||||||
{0, 2. / resolution_height, 0, 0},
|
{0, 2. / resolution_height, 0, 0},
|
||||||
{0, 0, 1, 0},
|
{0, 0, 1, 0},
|
||||||
|
@ -136,20 +140,22 @@ cv::Mat MinusRenderer::render(const int resolution_width,
|
||||||
const auto [ss_transform, inv_ss_transform] =
|
const auto [ss_transform, inv_ss_transform] =
|
||||||
construct_transform(resolution_width, resolution_height);
|
construct_transform(resolution_width, resolution_height);
|
||||||
|
|
||||||
Rasterizer rasterizer{resolution_width, resolution_height};
|
spdlog::trace("Rasterize.");
|
||||||
|
rasterizer_->reset(resolution_width, resolution_height);
|
||||||
for (decltype(meshes_)::size_type mesh_index = 0; mesh_index < meshes_.size();
|
for (decltype(meshes_)::size_type mesh_index = 0; mesh_index < meshes_.size();
|
||||||
++mesh_index) {
|
++mesh_index) {
|
||||||
auto primitives = (meshes_[mesh_index]).get_primitives();
|
auto primitives = (meshes_[mesh_index]).get_primitives();
|
||||||
for (auto &t : primitives) {
|
for (auto &t : primitives) {
|
||||||
t.set_points(apply_transform(ss_transform, t.get_vertex_position()));
|
t.set_points(apply_transform(ss_transform, t.get_vertex_position()));
|
||||||
}
|
}
|
||||||
rasterizer.rasterize(mesh_index, primitives);
|
rasterizer_->rasterize(mesh_index, primitives);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &shading_points = rasterizer.get_shading_points();
|
const auto &shading_points = rasterizer_->get_shading_points();
|
||||||
assert(!shading_points.empty());
|
assert(!shading_points.empty());
|
||||||
cv::Mat color_image(shading_points.size(), (shading_points[0]).size(),
|
cv::Mat color_image(shading_points.size(), (shading_points[0]).size(),
|
||||||
CV_8UC3);
|
CV_8UC3);
|
||||||
|
spdlog::trace("Shading.");
|
||||||
for (size_t y = 0; y < shading_points.size(); ++y) {
|
for (size_t y = 0; y < shading_points.size(); ++y) {
|
||||||
for (size_t x = 0; x < shading_points[y].size(); ++x) {
|
for (size_t x = 0; x < shading_points[y].size(); ++x) {
|
||||||
auto &pixel_color =
|
auto &pixel_color =
|
||||||
|
@ -195,7 +201,7 @@ cv::Mat MinusRenderer::render(const int resolution_width,
|
||||||
|
|
||||||
const auto &material = mesh.get_material();
|
const auto &material = mesh.get_material();
|
||||||
pixel_color =
|
pixel_color =
|
||||||
material->shade(Vertex{position, normal, uv}, Point3d{});
|
material->shade(Vertex{position, normal, uv}, Point3d{}, lamps_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,19 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "mesh.h"
|
|
||||||
#include "util/math_util.h"
|
|
||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
|
|
||||||
|
#include "mesh.h"
|
||||||
|
#include "rasterizer.h"
|
||||||
|
#include "util/math_util.h"
|
||||||
|
|
||||||
class MinusRenderer {
|
class MinusRenderer {
|
||||||
public:
|
public:
|
||||||
MinusRenderer(float near, float far, float fov, float aspect_ratio);
|
MinusRenderer(float near, float far, float fov, float aspect_ratio);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void set_meshes(const std::vector<Mesh> &meshes);
|
void set_meshes(const std::vector<Mesh> &meshes);
|
||||||
|
void set_lamps(const std::vector<std::shared_ptr<PointLamp>> &lamps);
|
||||||
|
|
||||||
cv::Mat render(const int resolution_width, const int resolution_height);
|
cv::Mat render(const int resolution_width, const int resolution_height);
|
||||||
|
|
||||||
|
@ -38,4 +41,7 @@ private:
|
||||||
float aspect_ratio_;
|
float aspect_ratio_;
|
||||||
|
|
||||||
std::vector<Mesh> meshes_;
|
std::vector<Mesh> meshes_;
|
||||||
|
std::vector<std::shared_ptr<PointLamp>> lamps_;
|
||||||
|
|
||||||
|
std::unique_ptr<Rasterizer> rasterizer_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,52 +8,53 @@
|
||||||
|
|
||||||
PhoneMaterial::PhoneMaterial(
|
PhoneMaterial::PhoneMaterial(
|
||||||
const std::unordered_map<Texture::TextureType, std::shared_ptr<Texture>>
|
const std::unordered_map<Texture::TextureType, std::shared_ptr<Texture>>
|
||||||
&textures,
|
&textures)
|
||||||
const std::shared_ptr<Lamp> &lamp)
|
: textures_(textures), Ka(0.2), Ks(1.6),
|
||||||
: point_lamp_(lamp), textures_(textures), Ka(cv::Vec3b{24, 24, 24}),
|
|
||||||
Ks(cv::Vec3b(48, 48, 48)),
|
|
||||||
specular_attenuation_factor_(defaultAttenuationFactor) {
|
specular_attenuation_factor_(defaultAttenuationFactor) {
|
||||||
spdlog::info("Specular attenuation factor: {}", specular_attenuation_factor_);
|
spdlog::info("Specular attenuation factor: {}", specular_attenuation_factor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Vec3b PhoneMaterial::shade(const Vertex &shading_point,
|
cv::Vec3b PhoneMaterial::shade(
|
||||||
const Point3d &view_point) const {
|
const Vertex &shading_point, const Point3d &view_point,
|
||||||
|
const std::vector<std::shared_ptr<PointLamp>> &lamps) const {
|
||||||
cv::Vec3b shading_res{0, 0, 0};
|
cv::Vec3b shading_res{0, 0, 0};
|
||||||
|
for (const auto &lamp : lamps) {
|
||||||
|
// Diffuse
|
||||||
|
assert(textures_.find(Texture::DiffuseMap) != textures_.end());
|
||||||
|
const auto &diffuse_map = textures_.at(Texture::DiffuseMap);
|
||||||
|
const auto &base_color =
|
||||||
|
diffuse_map->sample(shading_point.texture_coordinate);
|
||||||
|
|
||||||
// Diffuse
|
const auto &point2light_vector =
|
||||||
assert(textures_.find(Texture::DiffuseMap) != textures_.end());
|
(lamp->get_position() - shading_point.position).normalized();
|
||||||
const auto &diffuse_map = textures_.at(Texture::DiffuseMap);
|
const auto &point2light_distance =
|
||||||
const auto &Kd = diffuse_map->sample(shading_point.texture_coordinate);
|
(shading_point.position - lamp->get_position()).norm();
|
||||||
|
const auto ¤t_intensity =
|
||||||
|
lamp->get_intensity() / (point2light_distance * point2light_distance);
|
||||||
|
|
||||||
const auto &point2light_vector =
|
const auto diffuse_coeff =
|
||||||
(point_lamp_->position - shading_point.position).normalized();
|
current_intensity *
|
||||||
const auto &point2light_distance =
|
std::max(shading_point.normal.dot(point2light_vector), 0.);
|
||||||
(shading_point.position - point_lamp_->position).norm();
|
cv::Vec3b diffuse_color = base_color * diffuse_coeff;
|
||||||
const auto ¤t_intensity =
|
shading_res += diffuse_color;
|
||||||
point_lamp_->intensity / (point2light_distance * point2light_distance);
|
|
||||||
|
|
||||||
const auto diffuse_coeff =
|
// Specular
|
||||||
current_intensity *
|
const auto &point2view_vector =
|
||||||
std::max(shading_point.normal.dot(point2light_vector), 0.);
|
(view_point - shading_point.position).normalized();
|
||||||
cv::Vec3b diffuse_color = Kd * diffuse_coeff;
|
const auto &half_vector =
|
||||||
shading_res += diffuse_color;
|
(point2light_vector + point2view_vector).normalized();
|
||||||
|
const auto specular_coeff =
|
||||||
|
current_intensity *
|
||||||
|
std::max(std::pow(shading_point.normal.dot(half_vector),
|
||||||
|
specular_attenuation_factor_),
|
||||||
|
0.);
|
||||||
|
cv::Vec3b specular_color = Ks * specular_coeff;
|
||||||
|
shading_res += specular_color;
|
||||||
|
|
||||||
// Specular
|
// Ambient
|
||||||
const auto &point2view_vector =
|
cv::Vec3b ambient_color = Ka * base_color;
|
||||||
(view_point - shading_point.position).normalized();
|
shading_res += ambient_color;
|
||||||
const auto &half_vector =
|
}
|
||||||
(point2light_vector + point2view_vector).normalized();
|
|
||||||
const auto specular_coeff =
|
|
||||||
current_intensity *
|
|
||||||
std::max(std::pow(shading_point.normal.dot(half_vector),
|
|
||||||
specular_attenuation_factor_),
|
|
||||||
0.);
|
|
||||||
cv::Vec3b specular_color = Ks * specular_coeff;
|
|
||||||
shading_res += specular_color;
|
|
||||||
|
|
||||||
// Ambient
|
|
||||||
cv::Vec3b ambient_color = Ka;
|
|
||||||
shading_res += ambient_color;
|
|
||||||
|
|
||||||
return shading_res;
|
return shading_res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,29 +7,29 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "lamp.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
// Bling-Phone Matrerial
|
// Bling-Phone Matrerial
|
||||||
class PhoneMaterial {
|
class PhoneMaterial {
|
||||||
public:
|
public:
|
||||||
PhoneMaterial(const std::unordered_map<Texture::TextureType,
|
explicit PhoneMaterial(
|
||||||
std::shared_ptr<Texture>> &textures,
|
const std::unordered_map<Texture::TextureType, std::shared_ptr<Texture>>
|
||||||
const std::shared_ptr<Lamp> &lamp);
|
&textures);
|
||||||
|
|
||||||
cv::Vec3b shade(const Vertex &shading_point, const Point3d &view_point) const;
|
cv::Vec3b shade(const Vertex &shading_point, const Point3d &view_point,
|
||||||
|
const std::vector<std::shared_ptr<PointLamp>> &lamps) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr int defaultAttenuationFactor = 12;
|
static constexpr int defaultAttenuationFactor = 128;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Lamp> point_lamp_;
|
|
||||||
|
|
||||||
std::unordered_map<Texture::TextureType, std::shared_ptr<Texture>> textures_;
|
std::unordered_map<Texture::TextureType, std::shared_ptr<Texture>> textures_;
|
||||||
|
|
||||||
// Ambient Related
|
// Ambient Related
|
||||||
cv::Vec3b Ka;
|
float Ka;
|
||||||
|
|
||||||
// Specular Related
|
// Specular Related
|
||||||
cv::Vec3b Ks;
|
float Ks;
|
||||||
int specular_attenuation_factor_;
|
int specular_attenuation_factor_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,8 @@ Rasterizer::Rasterizer(const int width, const int height)
|
||||||
shading_points_(std::vector<std::vector<RasterizerResult>>(
|
shading_points_(std::vector<std::vector<RasterizerResult>>(
|
||||||
height, std::vector<RasterizerResult>(width, RasterizerResult{}))) {}
|
height, std::vector<RasterizerResult>(width, RasterizerResult{}))) {}
|
||||||
|
|
||||||
|
Rasterizer::Rasterizer() : Rasterizer(960, 540) {}
|
||||||
|
|
||||||
void Rasterizer::rasterize(const int mesh_idx,
|
void Rasterizer::rasterize(const int mesh_idx,
|
||||||
const std::vector<Triangle> &primitives) {
|
const std::vector<Triangle> &primitives) {
|
||||||
const int thread_num = 8;
|
const int thread_num = 8;
|
||||||
|
@ -41,6 +43,7 @@ void Rasterizer::rasterize(const int mesh_idx,
|
||||||
void Rasterizer::rasterize(const int mesh_idx,
|
void Rasterizer::rasterize(const int mesh_idx,
|
||||||
const std::vector<Triangle> &primitives,
|
const std::vector<Triangle> &primitives,
|
||||||
const int begin, const int end) {
|
const int begin, const int end) {
|
||||||
|
spdlog::trace("Mesh index: {}, begin: {}, end: {}", mesh_idx, begin, end);
|
||||||
for (int t_id = begin; t_id < end; ++t_id) {
|
for (int t_id = begin; t_id < end; ++t_id) {
|
||||||
const auto &t = primitives[t_id];
|
const auto &t = primitives[t_id];
|
||||||
const auto &triangle_points = t.get_vertex_position();
|
const auto &triangle_points = t.get_vertex_position();
|
||||||
|
@ -64,6 +67,7 @@ void Rasterizer::rasterize(const int mesh_idx,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
spdlog::trace("Triangles in [{}, {}) is done.", begin, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<std::vector<RasterizerResult>> &
|
const std::vector<std::vector<RasterizerResult>> &
|
||||||
|
@ -71,7 +75,8 @@ Rasterizer::get_shading_points() const {
|
||||||
return shading_points_;
|
return shading_points_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rasterizer::reset() {
|
void Rasterizer::reset(const int width, const int height) {
|
||||||
|
width_ = width, height_ = height;
|
||||||
shading_points_ = std::vector<std::vector<RasterizerResult>>(
|
shading_points_ = std::vector<std::vector<RasterizerResult>>(
|
||||||
height_, std::vector<RasterizerResult>(width_, RasterizerResult{}));
|
height_, std::vector<RasterizerResult>(width_, RasterizerResult{}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,13 @@ typedef struct RasterizerResult {
|
||||||
class Rasterizer {
|
class Rasterizer {
|
||||||
public:
|
public:
|
||||||
Rasterizer(const int width, const int height);
|
Rasterizer(const int width, const int height);
|
||||||
|
Rasterizer();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void rasterize(const int mesh_idx, const std::vector<Triangle> &primitives);
|
void rasterize(const int mesh_idx, const std::vector<Triangle> &primitives);
|
||||||
|
|
||||||
const std::vector<std::vector<RasterizerResult>> &get_shading_points() const;
|
const std::vector<std::vector<RasterizerResult>> &get_shading_points() const;
|
||||||
void reset();
|
void reset(const int width, const int height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::pair<bool, double> inside(const Point2d &p_screen,
|
static std::pair<bool, double> inside(const Point2d &p_screen,
|
||||||
|
|
|
@ -13,7 +13,7 @@ Texture::Texture(const std::filesystem::path &texture_path) {
|
||||||
throw std::filesystem::filesystem_error("File not found",
|
throw std::filesystem::filesystem_error("File not found",
|
||||||
std::error_code{});
|
std::error_code{});
|
||||||
}
|
}
|
||||||
texture_ = (cv::imread(texture_path.c_str()));
|
texture_ = cv::imread(texture_path.c_str());
|
||||||
spdlog::debug("Texture at {}, shape: ({},{})", texture_path.c_str(),
|
spdlog::debug("Texture at {}, shape: ({},{})", texture_path.c_str(),
|
||||||
texture_.cols, texture_.rows);
|
texture_.cols, texture_.rows);
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,24 @@ cv::Vec3b Texture::sample(const Point2d &texture_coordinate) {
|
||||||
const int y_c = std::min(texture_.rows - 1, static_cast<int>(y + 1.));
|
const int y_c = std::min(texture_.rows - 1, static_cast<int>(y + 1.));
|
||||||
const float t_y = y - y_f;
|
const float t_y = y - y_f;
|
||||||
|
|
||||||
const cv::Vec3b &a = texture_.at<cv::Vec3b>(y_f, x_f);
|
auto in_range = [](auto index, auto range_begin, auto range_end) -> bool {
|
||||||
const cv::Vec3b &b = texture_.at<cv::Vec3b>(y_c, x_f);
|
return index >= range_begin && index < range_end;
|
||||||
const cv::Vec3b &c = texture_.at<cv::Vec3b>(y_f, x_c);
|
};
|
||||||
const cv::Vec3b &d = texture_.at<cv::Vec3b>(y_c, x_c);
|
|
||||||
|
|
||||||
res = bilerp(t_x, t_y, a, b, c, d);
|
if (in_range(t_x, 0., 1.) && in_range(t_y, 0., 1.) &&
|
||||||
|
in_range(x_f, 0, texture_.cols) && in_range(x_c, 0, texture_.cols) &&
|
||||||
|
in_range(y_f, 0, texture_.rows) && in_range(y_c, 0, texture_.rows)) {
|
||||||
|
const cv::Vec3b &a = texture_.at<cv::Vec3b>(y_f, x_f);
|
||||||
|
const cv::Vec3b &b = texture_.at<cv::Vec3b>(y_c, x_f);
|
||||||
|
const cv::Vec3b &c = texture_.at<cv::Vec3b>(y_f, x_c);
|
||||||
|
const cv::Vec3b &d = texture_.at<cv::Vec3b>(y_c, x_c);
|
||||||
|
|
||||||
|
res = bilerp(t_x, t_y, a, b, c, d);
|
||||||
|
} else {
|
||||||
|
spdlog::warn(
|
||||||
|
"Interpolation factor is invalid, {}, {}, {}, {}, {}, {}, ({}, {}).",
|
||||||
|
t_x, t_y, x_f, x_c, y_f, y_c, texture_coordinate.x(),
|
||||||
|
texture_coordinate.y());
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue