reorganize lamp related code.

This commit is contained in:
tianlei.richard 2024-04-02 19:32:06 +08:00
parent 27419f73b5
commit a19de7f4c3
11 changed files with 102 additions and 63 deletions

View File

@ -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_);

View File

@ -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;

15
src/lamp.cc Normal file
View File

@ -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();
}

21
src/lamp.h Normal file
View File

@ -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_;
};

View File

@ -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);

View File

@ -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));
} }

View File

@ -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;
} }
@ -195,7 +200,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_);
} }
} }
} }

View File

@ -13,6 +13,7 @@ public:
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 +39,5 @@ private:
float aspect_ratio_; float aspect_ratio_;
std::vector<Mesh> meshes_; std::vector<Mesh> meshes_;
std::vector<std::shared_ptr<PointLamp>> lamps_;
}; };

View File

@ -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 &current_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 &current_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;
} }

View File

@ -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_;
}; };

View File

@ -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);
} }