Skip to content
Snippets Groups Projects
Commit 2c5b9c6d authored by Lukas Werner's avatar Lukas Werner
Browse files

Added lambertian lighting and image output

parent 00fd747b
Branches
Tags
No related merge requests found
...@@ -189,7 +189,7 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n) { ...@@ -189,7 +189,7 @@ inline bool intersects(const BoxID box, const Ray& ray, real_t& t, Vec3& n) {
if (transformedRay.getDirection() * n > 0) { if (transformedRay.getDirection() * n > 0) {
n = -n; n = -n;
} }
n = box->vectorFromBFtoWF(n); n = box->vectorFromBFtoWF(n);
t = t_; t = t_;
......
//======================================================================================================================
//
// This file is part of waLBerla. waLBerla is free software: you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation, either version 3 of
// the License, or (at your option) any later version.
//
// waLBerla is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with waLBerla (see COPYING.txt). If not, see <http://www.gnu.org/licenses/>.
//
//! \file PointLight.h
//! \author Lukas Werner
//
//======================================================================================================================
#pragma once
#include <pe/basic.h>
#include <pe/Types.h>
#include <core/math/Vector3.h>
namespace walberla {
namespace pe {
namespace raytracing {
struct Lighting {
Vec3 pointLightOrigin;
Vec3 ambientLight;
Vec3 diffuseColor;
real_t diffusePower;
Vec3 specularColor;
real_t specularPower;
/*!\brief Instantiation constructor for the Lighting struct.
*/
Lighting () {
}
/*!\brief Instantiation constructor for the Lighting struct.
* \param pointLightOrigin Origin of the point light.
* \param ambientLight Color of the ambient light.
* \param diffuseColor Diffuse color.
* \param diffusePower Diffuse color power.
* \param specularColor Specular color.
* \param specularPower Specular color power.
*/
Lighting (const Vec3& _pointLightOrigin, const Vec3& _ambientLight,
const Vec3& _diffuseColor, real_t _diffusePower,
const Vec3& _specularColor, real_t _specularPower)
: pointLightOrigin(_pointLightOrigin), ambientLight(_ambientLight),
diffuseColor(_diffuseColor), diffusePower(_diffusePower),
specularColor(_specularColor), specularPower(_specularPower) {
}
/*!\brief Instantiation constructor for the Lighting struct.
* \param config Config handle.
*
* The config block has to contain a pointLightOrigin parameter (Vec3).
* Optional are ambientLight (Vec3), for diffuse coloring diffuseColor (Vec3) and diffusePower (real) and
* for specular color specularColor (Vec3) and specularPower (real).
* Colors are Vec3's with values from 0 to 1.
*/
Lighting (const Config::BlockHandle& config) {
WALBERLA_CHECK(config.isValid(), "No valid config passed to raytracer lighting.");
pointLightOrigin = config.getParameter<Vec3>("pointLightOrigin"),
ambientLight = config.getParameter<Vec3>("ambientLight", Vec3(0,0,0)),
diffuseColor = config.getParameter<Vec3>("diffuseColor", Vec3(0,0,0));
diffusePower = config.getParameter<real_t>("diffusePower", real_t(0));
specularColor = config.getParameter<Vec3>("specularColor", Vec3(0,0,0));
specularPower = config.getParameter<real_t>("specularPower", real_t(0));
}
};
}
}
}
...@@ -38,7 +38,7 @@ public: ...@@ -38,7 +38,7 @@ public:
} }
/*!\brief Instantiation constructor for the Raytracer class. /*!\brief Instantiation constructor for the Raytracer class.
* \param origin Origin of the ray. * \param origin Origin of the ray. ()
* \param direction Normalized direction of the ray. * \param direction Normalized direction of the ray.
*/ */
Ray (Vec3 origin, Vec3 direction) { Ray (Vec3 origin, Vec3 direction) {
......
...@@ -48,13 +48,17 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI ...@@ -48,13 +48,17 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
size_t pixelsHorizontal, size_t pixelsVertical, size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical, real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector, const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector,
const Lighting& lighting,
real_t blockAABBIntersectionPadding) real_t blockAABBIntersectionPadding)
: forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage), : forest_(forest), storageID_(storageID), globalBodyStorage_(globalBodyStorage),
pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical), pixelsHorizontal_(pixelsHorizontal), pixelsVertical_(pixelsVertical),
fov_vertical_(fov_vertical), fov_vertical_(fov_vertical),
cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector), cameraPosition_(cameraPosition), lookAtPoint_(lookAtPoint), upVector_(upVector),
lighting_(lighting),
blockAABBIntersectionPadding_(blockAABBIntersectionPadding), blockAABBIntersectionPadding_(blockAABBIntersectionPadding),
tBufferOutputEnabled_(false) tBufferOutputEnabled_(false),
imageOutputEnabled_(false),
localImageOutputEnabled_(false)
{ {
setupView_(); setupView_();
} }
...@@ -68,6 +72,10 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI ...@@ -68,6 +72,10 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
* The config block has to contain image_x (int), image_y (int), fov_vertical (real, in degrees) * The config block has to contain image_x (int), image_y (int), fov_vertical (real, in degrees)
* and tbuffer_output_directory (string) parameters. Additionally a vector of reals * and tbuffer_output_directory (string) parameters. Additionally a vector of reals
* for each of cameraPosition, lookAt and the upVector. Optional is blockAABBIntersectionPadding (real). * for each of cameraPosition, lookAt and the upVector. Optional is blockAABBIntersectionPadding (real).
* To output both process local and global tbuffers after raytracing, set tbuffer_output_directory (string).
* For image output after raytracing, set image_output_directory (string); for local image output additionally set
* local_image_output_enabled (bool) to true.
* For the lighting a config block named Lighting has to be defined, information about its contents is in Lighting.h.
*/ */
Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const shared_ptr<BodyStorage> globalBodyStorage, const shared_ptr<BodyStorage> globalBodyStorage,
...@@ -85,9 +93,20 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI ...@@ -85,9 +93,20 @@ Raytracer::Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageI
WALBERLA_LOG_INFO_ON_ROOT("t buffers will be written to " << getTBufferOutputDirectory() << "."); WALBERLA_LOG_INFO_ON_ROOT("t buffers will be written to " << getTBufferOutputDirectory() << ".");
} }
setLocalImageOutputEnabled(config.getParameter<bool>("local_image_output_enabled", false));
if (config.isDefined("image_output_directory")) {
setImageOutputEnabled(true);
setImageOutputDirectory(config.getParameter<std::string>("image_output_directory"));
WALBERLA_LOG_INFO_ON_ROOT("Images will be written to " << getImageOutputDirectory() << ".");
} else if (getLocalImageOutputEnabled()) {
WALBERLA_ABORT("Cannot enable local image output without image_output_directory parameter being set.");
}
cameraPosition_ = config.getParameter<Vec3>("cameraPosition"); cameraPosition_ = config.getParameter<Vec3>("cameraPosition");
lookAtPoint_ = config.getParameter<Vec3>("lookAt"); lookAtPoint_ = config.getParameter<Vec3>("lookAt");
upVector_ = config.getParameter<Vec3>("upVector"); upVector_ = config.getParameter<Vec3>("upVector");
lighting_ = Lighting(config.getBlock("Lighting"));
blockAABBIntersectionPadding_ = config.getParameter<real_t>("blockAABBIntersectionPadding", real_t(0.0)); blockAABBIntersectionPadding_ = config.getParameter<real_t>("blockAABBIntersectionPadding", real_t(0.0));
...@@ -180,6 +199,49 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std ...@@ -180,6 +199,49 @@ void Raytracer::writeTBufferToFile(const std::vector<real_t>& tBuffer, const std
ofs.close(); ofs.close();
} }
/*!\brief Writes a image buffer to a file in the image output directory.
* \param imageBuffer Buffer with color vectors.
* \param timestep Timestep this image is from.
* \param isGlobalImage Whether this image is the fully stitched together one.
*/
void Raytracer::writeImageBufferToFile(const std::vector<Vec3>& imageBuffer, size_t timestep, bool isGlobalImage) const {
WALBERLA_CHECK(timestep < 100000, "Raytracer only supports outputting 99 999 timesteps.");
mpi::MPIRank rank = mpi::MPIManager::instance()->rank();
uint8_t padding = (timestep < 10 ? 4 :
(timestep < 100 ? 3 :
(timestep < 1000 ? 2 :
(timestep < 10000 ? 1 :
0))));
std::string fileName = "image_" + std::string(padding, '0') + std::to_string(timestep) + "+" + (isGlobalImage ? "global" : std::to_string(rank)) + ".ppm";
writeImageBufferToFile(imageBuffer, fileName);
}
/*!\brief Writes the image buffer to a file in the image output directory.
* \param imageBuffer Buffer with color vectors.
* \param fileName Name of the output file.
*/
void Raytracer::writeImageBufferToFile(const std::vector<Vec3>& imageBuffer, const std::string& fileName) const {
namespace fs = boost::filesystem;
fs::path dir (getImageOutputDirectory());
fs::path file (fileName);
fs::path fullPath = dir / file;
std::ofstream ofs(fullPath.string<std::string>(), std::ios::out | std::ios::binary);
ofs << "P6\n" << pixelsHorizontal_ << " " << pixelsVertical_ << "\n255\n";
for (size_t y = pixelsVertical_-1; y > 0; y--) {
for (size_t x = 0; x < pixelsHorizontal_; x++) {
size_t i = coordinateToArrayIndex(x, y);
const Vec3& color = imageBuffer[i];
char r = (char)(255 * color[0]);
char g = (char)(255 * color[1]);
char b = (char)(255 * color[2]);
ofs << r << g << b;
}
}
ofs.close();
}
} }
} }
} }
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <core/timing/TimingTree.h> #include <core/timing/TimingTree.h>
#include "Ray.h" #include "Ray.h"
#include "Intersects.h" #include "Intersects.h"
#include "Lighting.h"
using namespace walberla; using namespace walberla;
using namespace walberla::pe; using namespace walberla::pe;
...@@ -45,6 +46,7 @@ struct BodyIntersectionInfo { ...@@ -45,6 +46,7 @@ struct BodyIntersectionInfo {
size_t imageY; //!< viewing plane y pixel coordinate the ray belongs to. size_t imageY; //!< viewing plane y pixel coordinate the ray belongs to.
walberla::id_t bodySystemID; //!< system ID of body which was hit. walberla::id_t bodySystemID; //!< system ID of body which was hit.
real_t t; //!< distance from camera to intersection point on body. real_t t; //!< distance from camera to intersection point on body.
Vec3 color; //!< color computed for the pixel.
}; };
class Raytracer { class Raytracer {
...@@ -56,6 +58,7 @@ public: ...@@ -56,6 +58,7 @@ public:
size_t pixelsHorizontal, size_t pixelsVertical, size_t pixelsHorizontal, size_t pixelsVertical,
real_t fov_vertical, real_t fov_vertical,
const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector, const Vec3& cameraPosition, const Vec3& lookAtPoint, const Vec3& upVector,
const Lighting& lighting,
real_t blockAABBIntersectionPadding = real_t(0.0)); real_t blockAABBIntersectionPadding = real_t(0.0));
explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID, explicit Raytracer(const shared_ptr<BlockStorage> forest, BlockDataID storageID,
const shared_ptr<BodyStorage> globalBodyStorage, const shared_ptr<BodyStorage> globalBodyStorage,
...@@ -77,11 +80,16 @@ private: ...@@ -77,11 +80,16 @@ private:
Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame, Vec3 lookAtPoint_; /*!< The point the camera looks at in the global world frame,
marks the center of the view plane.*/ marks the center of the view plane.*/
Vec3 upVector_; //!< The vector indicating the upwards direction of the camera. Vec3 upVector_; //!< The vector indicating the upwards direction of the camera.
Lighting lighting_; //!< The lighting of the scene.
real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as real_t blockAABBIntersectionPadding_; /*!< The padding applied in block AABB intersection pretesting, as
some objects within a block might protrude from the block's AABB.*/ some objects within a block might protrude from the block's AABB.*/
bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to a file bool tBufferOutputEnabled_; //!< Enable / disable dumping the tbuffer to file.
std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory std::string tBufferOutputDirectory_; //!< Path to the tbuffer output directory.
bool imageOutputEnabled_; //!< Enable / disable writing images to file.
bool localImageOutputEnabled_; //!< Enable / disable writing images of the local process to file.
std::string imageOutputDirectory_; //!< Path to the image output directory.
//@} //@}
Vec3 n_; //!< The normal vector of the viewing plane. Vec3 n_; //!< The normal vector of the viewing plane.
...@@ -107,12 +115,18 @@ public: ...@@ -107,12 +115,18 @@ public:
inline const Vec3& getUpVector() const; inline const Vec3& getUpVector() const;
inline bool getTBufferOutputEnabled() const; inline bool getTBufferOutputEnabled() const;
inline const std::string& getTBufferOutputDirectory() const; inline const std::string& getTBufferOutputDirectory() const;
inline bool getImageOutputEnabled() const;
inline bool getLocalImageOutputEnabled() const;
inline const std::string& getImageOutputDirectory() const;
//@} //@}
/*!\name Set functions */ /*!\name Set functions */
//@{ //@{
inline void setTBufferOutputEnabled(const bool enabled); inline void setTBufferOutputEnabled(const bool enabled);
inline void setTBufferOutputDirectory(const std::string& path); inline void setTBufferOutputDirectory(const std::string& path);
inline void setImageOutputEnabled(const bool enabled);
inline void setLocalImageOutputEnabled(const bool enabled);
inline void setImageOutputDirectory(const std::string& path);
//@} //@}
/*!\name Functions */ /*!\name Functions */
...@@ -124,8 +138,13 @@ public: ...@@ -124,8 +138,13 @@ public:
private: private:
void writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage = false) const; void writeTBufferToFile(const std::vector<real_t>& tBuffer, size_t timestep, bool isGlobalImage = false) const;
void writeTBufferToFile(const std::vector<real_t>& tBuffer, const std::string& fileName) const; void writeTBufferToFile(const std::vector<real_t>& tBuffer, const std::string& fileName) const;
void writeImageBufferToFile(const std::vector<Vec3>& imageBuffer, size_t timestep, bool isGlobalImage = false) const;
void writeImageBufferToFile(const std::vector<Vec3>& imageBuffer, const std::string& fileName) const;
inline bool isPlaneVisible(const PlaneID plane, const Ray& ray) const; inline bool isPlaneVisible(const PlaneID plane, const Ray& ray) const;
inline size_t coordinateToArrayIndex(size_t x, size_t y) const; inline size_t coordinateToArrayIndex(size_t x, size_t y) const;
inline Vec3 getColor(const BodyID body, const Ray& ray, real_t t, const Vec3& n) const;
//@} //@}
}; };
...@@ -200,7 +219,31 @@ inline const std::string& Raytracer::getTBufferOutputDirectory() const { ...@@ -200,7 +219,31 @@ inline const std::string& Raytracer::getTBufferOutputDirectory() const {
return tBufferOutputDirectory_; return tBufferOutputDirectory_;
} }
/*!\brief Enabled / disable outputting the tBuffer to a file in the specified directory. /*!\brief Returns true if image output to a file is enabled.
*
* \return True if image output enabled, otherwise false.
*/
inline bool Raytracer::getImageOutputEnabled() const {
return imageOutputEnabled_;
}
/*!\brief Returns true if local image output to a file is enabled.
*
* \return True if local image output enabled, otherwise false.
*/
inline bool Raytracer::getLocalImageOutputEnabled() const {
return localImageOutputEnabled_;
}
/*!\brief Returns the directory where the images will be saved in.
*
* \return Path to the image output directory.
*/
inline const std::string& Raytracer::getImageOutputDirectory() const {
return imageOutputDirectory_;
}
/*!\brief Enable / disable outputting the tBuffer to a file in the specified directory.
* \param enabled Set to true / false to enable / disable tbuffer output. * \param enabled Set to true / false to enable / disable tbuffer output.
*/ */
inline void Raytracer::setTBufferOutputEnabled(const bool enabled) { inline void Raytracer::setTBufferOutputEnabled(const bool enabled) {
...@@ -219,6 +262,32 @@ inline void Raytracer::setTBufferOutputDirectory(const std::string& path) { ...@@ -219,6 +262,32 @@ inline void Raytracer::setTBufferOutputDirectory(const std::string& path) {
tBufferOutputDirectory_ = path; tBufferOutputDirectory_ = path;
} }
/*!\brief Enable / disable outputting images in the specified directory.
* \param enabled Set to true / false to enable / disable image output.
*/
inline void Raytracer::setImageOutputEnabled(const bool enabled) {
imageOutputEnabled_ = enabled;
}
/*!\brief Enable / disable outputting local images in the specified directory.
* \param enabled Set to true / false to enable / disable image output.
*/
inline void Raytracer::setLocalImageOutputEnabled(const bool enabled) {
localImageOutputEnabled_ = enabled;
}
/*!\brief Enable / disable outputting images in the specified directory.
* \param enabled Set to true / false to enable / disable image output.
*/
inline void Raytracer::setImageOutputDirectory(const std::string& path) {
namespace fs = boost::filesystem;
fs::path dir (path);
WALBERLA_CHECK(fs::exists(dir) && fs::is_directory(dir), "Image output directory " << path << " is invalid.");
imageOutputDirectory_ = path;
}
/*!\brief Checks if a plane should get rendered. /*!\brief Checks if a plane should get rendered.
* \param plane Plane to check for visibility. * \param plane Plane to check for visibility.
* \param ray Ray which is intersected with plane. * \param ray Ray which is intersected with plane.
...@@ -251,11 +320,13 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -251,11 +320,13 @@ void Raytracer::rayTrace(const size_t timestep) {
real_t inf = std::numeric_limits<real_t>::max(); real_t inf = std::numeric_limits<real_t>::max();
std::vector<real_t> tBuffer(pixelsVertical_ * pixelsHorizontal_, inf); std::vector<real_t> tBuffer(pixelsVertical_ * pixelsHorizontal_, inf);
std::vector<Vec3> imageBuffer(pixelsVertical_ * pixelsHorizontal_);
std::vector<BodyIntersectionInfo> intersections; // contains for each pixel information about an intersection, if existent std::vector<BodyIntersectionInfo> intersections; // contains for each pixel information about an intersection, if existent
real_t t, t_closest; real_t t, t_closest;
Vec3 n; Vec3 n;
RigidBody* body_closest = NULL; Vec3 n_closest;
BodyID body_closest = NULL;
Ray ray(cameraPosition_, Vec3(1,0,0)); Ray ray(cameraPosition_, Vec3(1,0,0));
IntersectsFunctor func(ray, t, n); IntersectsFunctor func(ray, t, n);
tp_["Raytracing"].start(); tp_["Raytracing"].start();
...@@ -265,7 +336,7 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -265,7 +336,7 @@ void Raytracer::rayTrace(const size_t timestep) {
Vec3 direction = (pixelLocation - cameraPosition_).getNormalized(); Vec3 direction = (pixelLocation - cameraPosition_).getNormalized();
ray.setDirection(direction); ray.setDirection(direction);
n[0] = n[1] = n[2] = real_t(0); n.reset();
t_closest = inf; t_closest = inf;
body_closest = NULL; body_closest = NULL;
for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) { for (auto blockIt = forest_->begin(); blockIt != forest_->end(); ++blockIt) {
...@@ -289,6 +360,7 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -289,6 +360,7 @@ void Raytracer::rayTrace(const size_t timestep) {
// body was shot by ray and currently closest to camera // body was shot by ray and currently closest to camera
t_closest = t; t_closest = t;
body_closest = *bodyIt; body_closest = *bodyIt;
n_closest = n;
} }
} }
} }
...@@ -310,16 +382,20 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -310,16 +382,20 @@ void Raytracer::rayTrace(const size_t timestep) {
// body was shot by ray and currently closest to camera // body was shot by ray and currently closest to camera
t_closest = t; t_closest = t;
body_closest = *bodyIt; body_closest = *bodyIt;
n_closest = n;
} }
} }
} }
if (!realIsIdentical(t_closest, inf) && body_closest != NULL) { if (!realIsIdentical(t_closest, inf) && body_closest != NULL) {
Vec3 color = getColor(body_closest, ray, t_closest, n_closest);
imageBuffer[coordinateToArrayIndex(x, y)] = color;
BodyIntersectionInfo intersectionInfo = { BodyIntersectionInfo intersectionInfo = {
x, x,
y, y,
body_closest->getSystemID(), body_closest->getSystemID(),
t_closest t_closest,
color
}; };
intersections.push_back(intersectionInfo); intersections.push_back(intersectionInfo);
} }
...@@ -334,10 +410,13 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -334,10 +410,13 @@ void Raytracer::rayTrace(const size_t timestep) {
// intersections synchronisieren // intersections synchronisieren
mpi::SendBuffer sendBuffer; mpi::SendBuffer sendBuffer;
for (auto& info: intersections) { for (auto& info: intersections) {
sendBuffer << info.imageX << info.imageY << info.bodySystemID << info.t; sendBuffer << info.imageX << info.imageY
<< info.bodySystemID << info.t
<< info.color[0] << info.color[1] << info.color[2];
} }
int gatheredIntersectionCount = 0; int gatheredIntersectionCount = 0;
std::vector<real_t> fullImage(pixelsHorizontal_ * pixelsVertical_, inf); std::vector<real_t> fullTBuffer(pixelsHorizontal_ * pixelsVertical_, inf);
std::vector<Vec3> fullImageBuffer(pixelsHorizontal_ * pixelsVertical_);
mpi::RecvBuffer recvBuffer; mpi::RecvBuffer recvBuffer;
mpi::gathervBuffer(sendBuffer, recvBuffer, 0); mpi::gathervBuffer(sendBuffer, recvBuffer, 0);
...@@ -350,11 +429,15 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -350,11 +429,15 @@ void Raytracer::rayTrace(const size_t timestep) {
recvBuffer >> info.imageY; recvBuffer >> info.imageY;
recvBuffer >> info.bodySystemID; recvBuffer >> info.bodySystemID;
recvBuffer >> info.t; recvBuffer >> info.t;
recvBuffer >> info.color[0];
recvBuffer >> info.color[1];
recvBuffer >> info.color[2];
size_t i = coordinateToArrayIndex(info.imageX, info.imageY); size_t i = coordinateToArrayIndex(info.imageX, info.imageY);
real_t currentFullImageT = fullImage[i]; real_t currentFullTBufferT = fullTBuffer[i];
if (currentFullImageT > info.t) { if (currentFullTBufferT > info.t) {
fullImage[i] = info.t; fullTBuffer[i] = info.t;
fullImageBuffer[i] = info.color;
} }
gatheredIntersectionCount++; gatheredIntersectionCount++;
...@@ -372,14 +455,44 @@ void Raytracer::rayTrace(const size_t timestep) { ...@@ -372,14 +455,44 @@ void Raytracer::rayTrace(const size_t timestep) {
tpReduced->print(std::cout); tpReduced->print(std::cout);
} }
if (getImageOutputEnabled()) {
writeImageBufferToFile(imageBuffer, timestep);
WALBERLA_ROOT_SECTION() {
writeImageBufferToFile(fullImageBuffer, timestep, true);
}
}
if (getTBufferOutputEnabled()) { if (getTBufferOutputEnabled()) {
writeTBufferToFile(tBuffer, timestep); writeTBufferToFile(tBuffer, timestep);
WALBERLA_ROOT_SECTION() { WALBERLA_ROOT_SECTION() {
writeTBufferToFile(fullImage, timestep, true); writeTBufferToFile(fullTBuffer, timestep, true);
} }
} }
} }
inline Vec3 Raytracer::getColor(const BodyID body, const Ray& ray, real_t t, const Vec3& n) const {
Vec3 objectColor(real_t(0.6), real_t(0), real_t(0.9));
if (body->getTypeID() == Plane::getStaticTypeID()) {
objectColor = Vec3(real_t(0.7), real_t(0.7), real_t(0.7));
}
if (body->getTypeID() == Sphere::getStaticTypeID()) {
objectColor = Vec3(real_t(1), real_t(0.1), real_t(0.1));
}
const Vec3 intersectionPoint = ray.getOrigin() + ray.getDirection() * t;
Vec3 lightDirection = lighting_.pointLightOrigin - intersectionPoint;
lightDirection = lightDirection.getNormalized();
real_t lambertian = std::max(real_t(0), lightDirection * n);
Vec3 color = objectColor * lambertian + lighting_.ambientLight;
for (size_t c = 0; c < 2; c++) {
color[c] = std::min(color[c], real_t(1));
}
return color;
}
} }
} }
} }
...@@ -98,6 +98,13 @@ void PlaneIntersectsTest() { ...@@ -98,6 +98,13 @@ void PlaneIntersectsTest() {
// plane with center -10,3,3 and parallel to y-z plane // plane with center -10,3,3 and parallel to y-z plane
Plane pl4(1, 1, Vec3(-10, 3, 3), Vec3(1, 0, 0), real_t(1.0), iron); Plane pl4(1, 1, Vec3(-10, 3, 3), Vec3(1, 0, 0), real_t(1.0), iron);
WALBERLA_CHECK(!intersects(&pl4, ray1, t, n), "ray hit plane behind origin"); WALBERLA_CHECK(!intersects(&pl4, ray1, t, n), "ray hit plane behind origin");
Plane pl6(1, 1, Vec3(3, 3, 0), Vec3(-1, 0, 0), real_t(1.0), iron);
Ray ray4(Vec3(0,0,5), Vec3(1, 0, -1).getNormalized());
WALBERLA_CHECK(intersects(&pl6, ray4, t, n), "ray didnt hit");
WALBERLA_CHECK_FLOAT_EQUAL(n[0], real_t(-1), "incorrect normal calculated");
WALBERLA_CHECK_FLOAT_EQUAL(n[1], real_t(0), "incorrect normal calculated");
WALBERLA_CHECK_FLOAT_EQUAL(n[2], real_t(0), "incorrect normal calculated");
} }
void BoxIntersectsTest() { void BoxIntersectsTest() {
...@@ -181,11 +188,14 @@ void RaytracerTest() { ...@@ -181,11 +188,14 @@ void RaytracerTest() {
shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>(); shared_ptr<BodyStorage> globalBodyStorage = make_shared<BodyStorage>();
shared_ptr<BlockForest> forest = createBlockForest(AABB(0,-5,-5,10,5,5), Vec3(1,1,1), Vec3(false, false, false)); shared_ptr<BlockForest> forest = createBlockForest(AABB(0,-5,-5,10,5,5), Vec3(1,1,1), Vec3(false, false, false));
auto storageID = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage"); auto storageID = forest->addBlockData(createStorageDataHandling<BodyTuple>(), "Storage");
Lighting lighting(Vec3(0, 3, 3), Vec3(0.1, 0.1, 0.1),
Vec3(0.1, 0.1, 0.1), real_t(2),
Vec3(0.4, 0.4, 0.4), real_t(4));
Raytracer raytracer(forest, storageID, globalBodyStorage, Raytracer raytracer(forest, storageID, globalBodyStorage,
size_t(640), size_t(480), size_t(640), size_t(480),
49.13, 49.13,
Vec3(-5,0,0), Vec3(-1,0,0), Vec3(0,0,1)); Vec3(-5,0,0), Vec3(-1,0,0), Vec3(0,0,1),
lighting);
MaterialID iron = Material::find("iron"); MaterialID iron = Material::find("iron");
...@@ -214,6 +224,8 @@ void RaytracerTest() { ...@@ -214,6 +224,8 @@ void RaytracerTest() {
raytracer.setTBufferOutputDirectory("/Users/ng/Desktop/walberla"); raytracer.setTBufferOutputDirectory("/Users/ng/Desktop/walberla");
raytracer.setTBufferOutputEnabled(true); raytracer.setTBufferOutputEnabled(true);
raytracer.setImageOutputDirectory("/Users/ng/Desktop/walberla");
raytracer.setImageOutputEnabled(true);
raytracer.rayTrace<BodyTuple>(0); raytracer.rayTrace<BodyTuple>(0);
} }
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment