Hello, World!
Yeah this is quite a thicc first commit but there's no way I'm untangling this mess just for a nice set of starting commits :^)
This commit is contained in:
166
include/Raychel/Core/Deserialize.h
Normal file
166
include/Raychel/Core/Deserialize.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* \file Deserializer.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Deserializer class
|
||||
* \date 2022-05-19
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_DESERIALIZER_H
|
||||
#define RAYCHEL_DESERIALIZER_H
|
||||
|
||||
#include <istream>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
#include "SDFTransforms.h"
|
||||
#include "Scene.h"
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename T>
|
||||
concept DeserializableWithoutTarget = requires()
|
||||
{
|
||||
// clang-format off
|
||||
requires !has_target_v<T>;
|
||||
{ do_deserialize(std::declval<std::istream&>(), DeserializationTag<T>{}) } -> std::same_as<std::optional<T>>;
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
template <typename T, typename Container>
|
||||
concept DeserializableWithTarget = requires()
|
||||
{
|
||||
// clang-format off
|
||||
requires has_target_v<T>;
|
||||
{ do_deserialize(std::declval<std::istream&>(), std::declval<Container>(), DeserializationTag<T>{}) } -> std::same_as<std::optional<T>>;
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
template <typename T, typename Container>
|
||||
concept Deserializable = DeserializableWithoutTarget<T> || DeserializableWithTarget<T, Container>;
|
||||
|
||||
template <typename Container>
|
||||
struct IDeserializer
|
||||
{
|
||||
IDeserializer() = default;
|
||||
|
||||
RAYCHEL_MAKE_NONCOPY_NONMOVE(IDeserializer)
|
||||
|
||||
virtual std::optional<Container>
|
||||
deserialize(std::istream& is, std::optional<Container>&& maybe_target) const noexcept = 0;
|
||||
|
||||
virtual SerializableObjectData<Container> get_serializer() const noexcept = 0;
|
||||
|
||||
virtual std::string_view contained_type_name() const noexcept = 0;
|
||||
|
||||
virtual ~IDeserializer() = default;
|
||||
};
|
||||
|
||||
template <typename Container, Deserializable<Container> Object>
|
||||
class Deserializer final : public IDeserializer<Container>
|
||||
{
|
||||
public:
|
||||
Deserializer() = default;
|
||||
|
||||
std::optional<Container> deserialize(std::istream& is, std::optional<Container>&& maybe_target) const noexcept final
|
||||
{
|
||||
if constexpr (has_target_v<Object>) {
|
||||
return _deserialize_with_target(is, std::move(maybe_target));
|
||||
} else {
|
||||
if (maybe_target.has_value()) {
|
||||
Logger::warn("Type ", Logger::details::type_name<Object>(), " did not expect to have a target!\n");
|
||||
return std::nullopt;
|
||||
}
|
||||
return _deserialize_without_target(is);
|
||||
}
|
||||
}
|
||||
|
||||
SerializableObjectData<Container> get_serializer() const noexcept final
|
||||
{
|
||||
return SerializableObjectData<Container>{SerializableObjectDescriptor<Object>{}};
|
||||
}
|
||||
|
||||
std::string_view contained_type_name() const noexcept final
|
||||
{
|
||||
return serializable_type_name_for<Object>();
|
||||
}
|
||||
|
||||
virtual ~Deserializer() = default;
|
||||
|
||||
private:
|
||||
static std::optional<Container> _deserialize_without_target(std::istream& is) noexcept
|
||||
{
|
||||
auto maybe_object = do_deserialize(is, DeserializationTag<Object>{});
|
||||
if (!maybe_object.has_value())
|
||||
return std::nullopt;
|
||||
return Container{std::move(maybe_object).value()};
|
||||
}
|
||||
|
||||
static std::optional<Container>
|
||||
_deserialize_with_target(std::istream& is, std::optional<Container> maybe_target) noexcept
|
||||
{
|
||||
if (!maybe_target.has_value()) {
|
||||
Logger::warn("Type ", Logger::details::type_name<Object>(), " expectec to have a target!\n");
|
||||
return std::nullopt;
|
||||
}
|
||||
auto maybe_object = do_deserialize(is, std::move(maybe_target).value(), DeserializationTag<Object>{});
|
||||
if (!maybe_object.has_value())
|
||||
return std::nullopt;
|
||||
return Container{std::move(maybe_object).value()};
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Container>
|
||||
using DeserializerPtr = std::unique_ptr<IDeserializer<Container>>;
|
||||
|
||||
template <typename Container, typename... Args>
|
||||
auto object_deserializers()
|
||||
{
|
||||
std::vector<DeserializerPtr<Container>> res{};
|
||||
|
||||
((res.emplace_back(std::make_unique<Deserializer<Container, Args>>())), ...);
|
||||
|
||||
return res;
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
template <typename... Objects>
|
||||
auto object_deserializers()
|
||||
{
|
||||
return details::object_deserializers<SDFContainer, Objects...>();
|
||||
}
|
||||
|
||||
template <typename... Materials>
|
||||
auto material_deserializers()
|
||||
{
|
||||
return details::object_deserializers<MaterialContainer, Materials...>();
|
||||
}
|
||||
|
||||
[[nodiscard]] Scene deserialize_scene(
|
||||
std::istream& is, const std::vector<details::DeserializerPtr<SDFContainer>>& object_deserializers,
|
||||
const std::vector<details::DeserializerPtr<MaterialContainer>>& material_deserializers) noexcept;
|
||||
|
||||
} //namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_DESERIALIZER_H
|
||||
66
include/Raychel/Core/Raymarch.h
Normal file
66
include/Raychel/Core/Raymarch.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* \file Raymarch.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Raymarch class
|
||||
* \date 2022-04-11
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_RAYMARCH_H
|
||||
#define RAYCHEL_RAYMARCH_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#include <limits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
constexpr static auto no_hit = std::numeric_limits<std::size_t>::max();
|
||||
|
||||
struct RaymarchResult
|
||||
{
|
||||
vec3 point{};
|
||||
double ray_depth{};
|
||||
std::size_t ray_steps{};
|
||||
std::size_t hit_index{no_hit};
|
||||
};
|
||||
|
||||
struct RaymarchOptions
|
||||
{
|
||||
std::size_t max_ray_steps{1'000};
|
||||
double max_ray_depth{100};
|
||||
double surface_epsilon{1e-3};
|
||||
};
|
||||
|
||||
[[nodiscard]] std::pair<double, std::size_t>
|
||||
evaluate_distance_field(const std::vector<SDFContainer>& surfaces, const vec3& point) noexcept;
|
||||
|
||||
[[nodiscard]] RaymarchResult raymarch(
|
||||
vec3 current_point, const vec3& direction, const std::vector<SDFContainer>& surfaces, RaymarchOptions options) noexcept;
|
||||
|
||||
[[nodiscard]] vec3 get_normal(const vec3& point, const SDFContainer& surface, double normal_offset = 1e-6) noexcept;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_RAYMARCH_H
|
||||
87
include/Raychel/Core/SDFBooleans.h
Normal file
87
include/Raychel/Core/SDFBooleans.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* \file SDFBooleans.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for boolean operations on SDFs
|
||||
* \date 2022-05-27
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SDF_BOOLEANS_H
|
||||
#define RAYCHEL_SDF_BOOLEANS_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
template <typename Target1, typename Target2>
|
||||
struct Union
|
||||
{
|
||||
Target1 target1;
|
||||
Target2 target2;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
Union(T1, T2) -> Union<T1, T2>;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
double evaluate_sdf(const Union<T1, T2>& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::min(evaluate_sdf(object.target1, p), evaluate_sdf(object.target2, p));
|
||||
}
|
||||
|
||||
template <typename Target1, typename Target2>
|
||||
struct Difference
|
||||
{
|
||||
Target1 target1;
|
||||
Target2 target2;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
Difference(T1, T2) -> Difference<T1, T2>;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
double evaluate_sdf(const Difference<T1, T2>& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::max(-evaluate_sdf(object.target1, p), evaluate_sdf(object.target2, p));
|
||||
}
|
||||
|
||||
template <typename Target1, typename Target2>
|
||||
struct Intersection
|
||||
{
|
||||
Target1 target1;
|
||||
Target2 target2;
|
||||
};
|
||||
|
||||
template <typename T1, typename T2>
|
||||
Intersection(T1, T2) -> Intersection<T1, T2>;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
double evaluate_sdf(const Intersection<T1, T2>& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::max(evaluate_sdf(object.target1, p), evaluate_sdf(object.target2, p));
|
||||
}
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_SDF_BOOLEANS_H
|
||||
213
include/Raychel/Core/SDFContainer.h
Normal file
213
include/Raychel/Core/SDFContainer.h
Normal file
@@ -0,0 +1,213 @@
|
||||
/**
|
||||
* \file SDFContainer.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for SDFContainer class
|
||||
* \date 2022-04-09
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SDF_CONTAINER_H
|
||||
#define RAYCHEL_SDF_CONTAINER_H
|
||||
|
||||
#include "Raychel/Core/SDFPrimitives.h"
|
||||
#include "Types.h"
|
||||
|
||||
#include "RaychelCore/Badge.h"
|
||||
#include "RaychelCore/ClassMacros.h"
|
||||
|
||||
#include <RaychelCore/Raychel_assert.h>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_custom_normal_v = requires(T t)
|
||||
{
|
||||
{
|
||||
evaluate_normal(t, vec3{})
|
||||
} -> std::same_as<vec3>;
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename T>
|
||||
class TypeId
|
||||
{
|
||||
static char _;
|
||||
|
||||
public:
|
||||
static std::uintptr_t id()
|
||||
{
|
||||
return reinterpret_cast<std::uintptr_t>(&_);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
char TypeId<T>::_{};
|
||||
|
||||
struct ISDFContainerImpl
|
||||
{
|
||||
ISDFContainerImpl() = default;
|
||||
|
||||
RAYCHEL_MAKE_NONCOPY_NONMOVE(ISDFContainerImpl)
|
||||
|
||||
[[nodiscard]] virtual std::uintptr_t type_id() const noexcept = 0;
|
||||
|
||||
virtual void debug_log() const noexcept = 0;
|
||||
|
||||
virtual ~ISDFContainerImpl() = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SDFContainerImpl final : public ISDFContainerImpl
|
||||
{
|
||||
public:
|
||||
explicit SDFContainerImpl(T&& object) noexcept(std::is_nothrow_move_constructible_v<T>)
|
||||
: object_{std::forward<T>(object)}
|
||||
{}
|
||||
|
||||
void debug_log() const noexcept override
|
||||
{
|
||||
std::cout << "SDFContainer with object type " << Logger::details::type_name<T>() << " (type id " << type_id()
|
||||
<< ")";
|
||||
if constexpr (has_target_v<T>) {
|
||||
std::cout << " and target ";
|
||||
if constexpr (std::is_same_v<decltype(T::target), SDFContainer>) {
|
||||
object_.target.unsafe_impl()->debug_log();
|
||||
} else {
|
||||
std::cout << Logger::details::type_name<decltype(T::target)>() << '\n';
|
||||
}
|
||||
} else {
|
||||
std::cout << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] std::uintptr_t type_id() const noexcept override
|
||||
{
|
||||
return TypeId<T>::id();
|
||||
}
|
||||
|
||||
[[nodiscard]] T& object() noexcept
|
||||
{
|
||||
return object_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& object() const noexcept
|
||||
{
|
||||
return object_;
|
||||
}
|
||||
|
||||
~SDFContainerImpl() override = default;
|
||||
|
||||
private:
|
||||
T object_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct Eval
|
||||
{
|
||||
static double eval(ISDFContainerImpl* ptr, const vec3& p)
|
||||
{
|
||||
auto& obj = get_ref(ptr);
|
||||
return evaluate_sdf(obj, p);
|
||||
}
|
||||
|
||||
static vec3 get_normal(ISDFContainerImpl* ptr, const vec3& p)
|
||||
{
|
||||
if constexpr (has_custom_normal_v<T>) {
|
||||
auto& obj = get_ref(ptr);
|
||||
return evaluate_normal(obj, p);
|
||||
}
|
||||
RAYCHEL_ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
static T& get_ref(ISDFContainerImpl* ptr)
|
||||
{
|
||||
return reinterpret_cast<SDFContainerImpl<T>*>(ptr)->object();
|
||||
}
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
class SDFContainer
|
||||
{
|
||||
using EvalFunction = double (*)(details::ISDFContainerImpl*, const vec3&);
|
||||
using NormalFunction = vec3 (*)(details::ISDFContainerImpl*, const vec3&);
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
using Impl = details::SDFContainerImpl<T>;
|
||||
|
||||
template <typename T>
|
||||
requires(!std::is_same_v<std::remove_all_extents_t<T>, SDFContainer>) //otherwise the move constructor would be hidden
|
||||
explicit SDFContainer(T&& object) noexcept(std::is_nothrow_move_constructible_v<T>)
|
||||
: impl_{std::make_unique<Impl<T>>(std::forward<T>(object))},
|
||||
eval_{details::Eval<T>::eval},
|
||||
get_normal_(details::Eval<T>::get_normal),
|
||||
has_custom_normal_{has_custom_normal_v<T>}
|
||||
{}
|
||||
|
||||
RAYCHEL_MAKE_NONCOPY(SDFContainer)
|
||||
|
||||
RAYCHEL_MAKE_DEFAULT_MOVE(SDFContainer)
|
||||
|
||||
[[nodiscard]] double evaluate(const vec3& p) const noexcept
|
||||
{
|
||||
return eval_(impl_.get(), p);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool has_custom_normal() const noexcept
|
||||
{
|
||||
return has_custom_normal_;
|
||||
}
|
||||
|
||||
[[nodiscard]] vec3 get_normal(const vec3& p) const noexcept
|
||||
{
|
||||
return get_normal_(impl_.get(), p);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto type_id() const noexcept
|
||||
{
|
||||
return impl_->type_id();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto* unsafe_impl() const noexcept
|
||||
{
|
||||
return impl_.get();
|
||||
}
|
||||
|
||||
~SDFContainer() = default;
|
||||
|
||||
private:
|
||||
std::unique_ptr<details::ISDFContainerImpl> impl_{};
|
||||
EvalFunction eval_;
|
||||
NormalFunction get_normal_;
|
||||
bool has_custom_normal_ : 1 {};
|
||||
};
|
||||
|
||||
inline double evaluate_sdf(const SDFContainer& obj, const vec3& p)
|
||||
{
|
||||
return obj.evaluate(p);
|
||||
}
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //! RAYCHEL_SDF_CONTAINER_H
|
||||
84
include/Raychel/Core/SDFModifiers.h
Normal file
84
include/Raychel/Core/SDFModifiers.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* \file SDFModifiers.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for modifiers on SDFs
|
||||
* \date 2022-05-27
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SDF_MODIFIERS_H
|
||||
#define RAYCHEL_SDF_MODIFIERS_H
|
||||
|
||||
#include "Raychel/Core/Types.h"
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
template <typename Target>
|
||||
struct Hollow
|
||||
{
|
||||
Target target;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Hollow(T) -> Hollow<T>;
|
||||
|
||||
template <typename T>
|
||||
double evaluate_sdf(const Hollow<T>& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::abs(evaluate_sdf(object.target, p));
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
struct Rounded
|
||||
{
|
||||
Target target;
|
||||
double radius;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Rounded(T, double) -> Rounded<T>;
|
||||
|
||||
template <typename T>
|
||||
double evaluate_sdf(const Rounded<T>& object, const vec3& p) noexcept
|
||||
{
|
||||
return evaluate_sdf(object.target, p) - object.radius;
|
||||
}
|
||||
|
||||
template <typename Target>
|
||||
struct Onion
|
||||
{
|
||||
Target target;
|
||||
double thickness;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
Onion(T, double) -> Onion<T>;
|
||||
|
||||
template <typename T>
|
||||
double evaluate_sdf(const Onion<T>& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::abs(evaluate_sdf(object.target, p)) - object.thickness;
|
||||
}
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_SDF_MODIFIERS_H
|
||||
105
include/Raychel/Core/SDFPrimitives.h
Normal file
105
include/Raychel/Core/SDFPrimitives.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
* \file SDFPrimitives.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for SDF primitives
|
||||
* \date 2022-05-27
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SDF_PRIMITIVES_H
|
||||
#define RAYCHEL_SDF_PRIMITIVES_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct Sphere
|
||||
{
|
||||
double radius{1.0};
|
||||
};
|
||||
|
||||
inline double evaluate_sdf(const Sphere& object, const vec3& p) noexcept
|
||||
{
|
||||
return mag(p) - object.radius;
|
||||
}
|
||||
|
||||
//optimized normal calculation for spheres
|
||||
inline vec3 evaluate_normal(const Sphere& /*unused*/, const vec3& p) noexcept
|
||||
{
|
||||
return normalize(p);
|
||||
}
|
||||
|
||||
bool do_serialize(std::ostream& os, const Sphere& object) noexcept;
|
||||
|
||||
std::optional<Sphere> do_deserialize(std::istream& is, DeserializationTag<Sphere>) noexcept;
|
||||
|
||||
struct Box
|
||||
{
|
||||
vec3 size{1, 1, 1};
|
||||
};
|
||||
|
||||
inline double evaluate_sdf(const Box& box, const vec3& p) noexcept
|
||||
{
|
||||
using std::abs, std::max, std::min;
|
||||
const auto q = vec3{abs(p.x()), abs(p.y()), abs(p.z())} - box.size;
|
||||
|
||||
return mag(vec3{max(q.x(), 0.0), max(q.y(), 0.0), max(q.z(), 0.0)}) + min(max(q.x(), max(q.y(), q.z())), 0.0);
|
||||
}
|
||||
|
||||
bool do_serialize(std::ostream& os, const Box& object) noexcept;
|
||||
|
||||
std::optional<Box> do_deserialize(std::istream& is, DeserializationTag<Box>) noexcept;
|
||||
|
||||
struct Plane
|
||||
{
|
||||
vec3 normal{0, 1, 0};
|
||||
};
|
||||
|
||||
inline double evaluate_sdf(const Plane& object, const vec3& p) noexcept
|
||||
{
|
||||
return std::abs(dot(object.normal, p));
|
||||
}
|
||||
|
||||
inline vec3 evaluate_normal(const Plane& object, const vec3&) noexcept
|
||||
{
|
||||
return object.normal;
|
||||
}
|
||||
|
||||
bool do_serialize(std::ostream& os, const Plane& object) noexcept;
|
||||
|
||||
std::optional<Plane> do_deserialize(std::istream& is, DeserializationTag<Plane>) noexcept;
|
||||
|
||||
struct DeserializationErrorPlaceHolder
|
||||
{};
|
||||
|
||||
inline double evaluate_sdf(const DeserializationErrorPlaceHolder /*unused*/, const vec3& /*unused*/) noexcept
|
||||
{
|
||||
return 1e9;
|
||||
}
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_SDF_PRIMITIVES_H
|
||||
115
include/Raychel/Core/SDFTransforms.h
Normal file
115
include/Raychel/Core/SDFTransforms.h
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* \file SDFTransforms.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for SDFTransforms class
|
||||
* \date 2022-05-27
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SDF_TRANSFORM_H
|
||||
#define RAYCHEL_SDF_TRANSFORM_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "SDFContainer.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <optional>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
template <typename Target = SDFContainer>
|
||||
struct Translate
|
||||
{
|
||||
Target target;
|
||||
vec3 translation{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_target<Translate<T>> : std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
Translate(T, vec3) -> Translate<T>;
|
||||
|
||||
template <typename T>
|
||||
double evaluate_sdf(const Translate<T>& object, const vec3& p) noexcept
|
||||
{
|
||||
return evaluate_sdf(object.target, p - object.translation);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool do_serialize(std::ostream& os, const Translate<T>& object) noexcept
|
||||
{
|
||||
os << object.translation << '\n';
|
||||
return os.good();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<Translate<T>> do_deserialize(std::istream& is, SDFContainer target, DeserializationTag<Translate<T>>) noexcept
|
||||
{
|
||||
vec3 translation{};
|
||||
|
||||
if (!(is >> translation))
|
||||
return std::nullopt;
|
||||
return Translate<T>{std::move(target), translation};
|
||||
}
|
||||
|
||||
template <typename Target = SDFContainer>
|
||||
struct Rotate
|
||||
{
|
||||
Target target;
|
||||
Quaternion rotation{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_target<Rotate<T>> : std::true_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
Rotate(T, Quaternion) -> Rotate<T>;
|
||||
|
||||
template <typename T>
|
||||
double evaluate_sdf(const Rotate<T>& object, const vec3& p) noexcept
|
||||
{
|
||||
return evaluate_sdf(object.target, p * inverse(object.rotation));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool do_serialize(std::ostream& os, const Rotate<T>& object) noexcept
|
||||
{
|
||||
os << object.rotation << '\n';
|
||||
return os.good();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::optional<Rotate<T>> do_deserialize(std::istream& is, SDFContainer target, DeserializationTag<Rotate<T>>) noexcept
|
||||
{
|
||||
Quaternion rotation{};
|
||||
|
||||
if (!(is >> rotation))
|
||||
return std::nullopt;
|
||||
return Rotate{std::move(target), rotation};
|
||||
}
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_SDF_TRANSFORM_H
|
||||
36
include/Raychel/Core/SDFs.h
Normal file
36
include/Raychel/Core/SDFs.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* \file SDFs.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for predefined signed distance functions
|
||||
* \date 2022-04-12
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_PREDEFINED_SIGNED_DISTANCE_FUNCTIONS_H
|
||||
#define RAYCHEL_PREDEFINED_SIGNED_DISTANCE_FUNCTIONS_H
|
||||
|
||||
#include "SDFBooleans.h"
|
||||
#include "SDFModifiers.h"
|
||||
#include "SDFPrimitives.h"
|
||||
#include "SDFTransforms.h"
|
||||
|
||||
#endif //!RAYCHEL_PREDEFINED_SIGNED_DISTANCE_FUNCTIONS_H
|
||||
141
include/Raychel/Core/Scene.h
Normal file
141
include/Raychel/Core/Scene.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* \file Scene.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Scene class
|
||||
* \date 2022-04-09
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SCENE_H
|
||||
#define RAYCHEL_SCENE_H
|
||||
|
||||
#include "Raychel/Render/MaterialContainer.h"
|
||||
#include "SDFContainer.h"
|
||||
#include "Serialize.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
template <typename Object, typename Material>
|
||||
struct RaymarchableObject
|
||||
{
|
||||
std::size_t index_in_scene;
|
||||
Object& object;
|
||||
Material& material;
|
||||
};
|
||||
|
||||
//Clang needs this deduction guide
|
||||
template <typename Object, typename Material>
|
||||
RaymarchableObject(std::size_t, Object&, Material&) -> RaymarchableObject<Object, Material>;
|
||||
|
||||
class Scene
|
||||
{
|
||||
public:
|
||||
Scene() = default;
|
||||
|
||||
static Scene unsafe_from_data(
|
||||
std::vector<SDFContainer> objects, std::vector<SerializableObjectData<SDFContainer>> object_serializers,
|
||||
std::vector<MaterialContainer> materials,
|
||||
std::vector<SerializableObjectData<MaterialContainer>> material_serializers) noexcept;
|
||||
|
||||
template <typename Object, typename Material>
|
||||
auto add_object(Object&& object, Material&& material) noexcept
|
||||
{
|
||||
const auto where = std::lower_bound(
|
||||
objects_.begin(), objects_.end(), details::TypeId<Object>::id(), [](const auto& cont, const auto& id) {
|
||||
return cont.type_id() < id;
|
||||
});
|
||||
|
||||
const auto obj = objects_.emplace(where, std::forward<Object>(object));
|
||||
const auto index = std::distance(objects_.begin(), obj);
|
||||
|
||||
const auto mat = materials_.emplace(materials_.begin() + index, std::forward<Material>(material));
|
||||
|
||||
object_serializers_.emplace(object_serializers_.begin() + index, details::SerializableObjectDescriptor<Object>{});
|
||||
material_serializers_.emplace(
|
||||
material_serializers_.begin() + index, details::SerializableObjectDescriptor<Material>{});
|
||||
|
||||
return RaymarchableObject{
|
||||
objects_.size() - 1U,
|
||||
details::get_container_content<Object>(*obj),
|
||||
details::get_container_content<Material>(*mat)};
|
||||
}
|
||||
|
||||
void remove_object(std::size_t index) noexcept;
|
||||
|
||||
template <std::invocable<const RenderData&> F>
|
||||
requires(std::is_same_v<std::invoke_result_t<F, const RenderData&>, color>) void set_background_function(F&& f) noexcept
|
||||
{
|
||||
background_function_ = f;
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto& objects() const noexcept
|
||||
{
|
||||
return objects_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto& materials() const noexcept
|
||||
{
|
||||
return materials_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto& background_function() const noexcept
|
||||
{
|
||||
return background_function_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto& object_serializers() const noexcept
|
||||
{
|
||||
return object_serializers_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const auto& material_serializers() const noexcept
|
||||
{
|
||||
return material_serializers_;
|
||||
}
|
||||
|
||||
private:
|
||||
Scene(
|
||||
std::vector<SDFContainer> objects, std::vector<SerializableObjectData<SDFContainer>> object_serializers,
|
||||
std::vector<MaterialContainer> materials, std::vector<SerializableObjectData<MaterialContainer>> material_serializers)
|
||||
: object_serializers_{std::move(object_serializers)},
|
||||
material_serializers_{std::move(material_serializers)},
|
||||
objects_{std::move(objects)},
|
||||
materials_{std::move(materials)}
|
||||
{}
|
||||
|
||||
std::vector<SerializableObjectData<SDFContainer>> object_serializers_{};
|
||||
std::vector<SerializableObjectData<MaterialContainer>> material_serializers_{};
|
||||
|
||||
std::vector<SDFContainer> objects_{};
|
||||
std::vector<MaterialContainer> materials_{};
|
||||
BackgroundFunction background_function_{};
|
||||
};
|
||||
|
||||
bool serialize_scene(const Scene& scene, std::ostream& os) noexcept;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //! RAYCHEL_SCENE_H
|
||||
163
include/Raychel/Core/Serialize.h
Normal file
163
include/Raychel/Core/Serialize.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* \file SerializableObjectData.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for SerializableObjectData class
|
||||
* \date 2022-05-18
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_SERIALIZABLE_OBJECT_DATA_H
|
||||
#define RAYCHEL_SERIALIZABLE_OBJECT_DATA_H
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#include "RaychelCore/ClassMacros.h"
|
||||
#include "RaychelCore/Raychel_assert.h"
|
||||
#include "RaychelLogger/Logger.h"
|
||||
|
||||
#include <concepts>
|
||||
#include <functional>
|
||||
#include <ostream>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
|
||||
template <typename Contained, typename Container>
|
||||
auto& get_container_content(Container& container) noexcept
|
||||
{
|
||||
using Impl = typename Container::template Impl<Contained>;
|
||||
|
||||
auto* impl_interface = container.unsafe_impl();
|
||||
auto* impl = dynamic_cast<Impl*>(impl_interface);
|
||||
RAYCHEL_ASSERT(impl != nullptr);
|
||||
|
||||
return impl->object();
|
||||
}
|
||||
|
||||
template <typename Contained, typename Container>
|
||||
const auto& get_container_content(const Container& container) noexcept
|
||||
{
|
||||
using Impl = typename Container::template Impl<Contained>;
|
||||
|
||||
auto* impl_interface = container.unsafe_impl();
|
||||
auto* impl = dynamic_cast<Impl*>(impl_interface);
|
||||
RAYCHEL_ASSERT(impl != nullptr);
|
||||
return impl->object();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
requires(has_target_v<T>) constexpr std::string_view serializable_type_name_for()
|
||||
{
|
||||
constexpr auto full_type_name = Logger::details::type_name<T>();
|
||||
constexpr auto bracket_index = full_type_name.find('<');
|
||||
static_assert(bracket_index != std::string_view::npos);
|
||||
constexpr std::string_view base_type_name{full_type_name.begin(), full_type_name.begin() + bracket_index};
|
||||
|
||||
return base_type_name;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr std::string_view serializable_type_name_for()
|
||||
{
|
||||
return Logger::details::type_name<T>();
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
template <typename Object>
|
||||
concept Serializable = requires(const Object& obj)
|
||||
{
|
||||
{ do_serialize(std::declval<std::ostream&>(), obj) } -> std::same_as<bool>;
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
template <typename Object>
|
||||
struct SerializableObjectDescriptor
|
||||
{};
|
||||
|
||||
template <Serializable T>
|
||||
bool serialize_internal(std::ostream&, const T&, std::size_t = 0) noexcept;
|
||||
|
||||
template <typename T>
|
||||
bool serialize_internal(std::ostream&, const T&, std::size_t = 0) noexcept;
|
||||
|
||||
template <Serializable Object>
|
||||
requires(has_target_v<Object>) bool serialize_with_target(
|
||||
std::ostream& os, const Object& object, std::size_t recursion_depth) noexcept
|
||||
{
|
||||
os << serializable_type_name_for<Object>() << "<> with ";
|
||||
return os.good() && do_serialize(os, object) && serialize_internal(os, object.target, recursion_depth + 1);
|
||||
}
|
||||
|
||||
template <Serializable Object>
|
||||
bool serialize_with_target(std::ostream& os, const Object& object, std::size_t /*unused*/) noexcept
|
||||
{
|
||||
os << serializable_type_name_for<Object>() << " with ";
|
||||
return os.good() && do_serialize(os, object);
|
||||
}
|
||||
|
||||
template <Serializable Object>
|
||||
bool serialize_internal(std::ostream& os, const Object& object, std::size_t recursion_depth) noexcept
|
||||
{
|
||||
for (std::size_t i{}; i != recursion_depth; ++i)
|
||||
os << " ";
|
||||
return serialize_with_target(os, object, recursion_depth);
|
||||
}
|
||||
|
||||
template <typename Object>
|
||||
bool serialize_internal(std::ostream& os, const Object& /*unused*/, std::size_t /*unused*/) noexcept
|
||||
{
|
||||
constexpr auto type_name = Logger::details::type_name<Object>();
|
||||
Logger::warn(
|
||||
"Object of type '",
|
||||
type_name,
|
||||
"' cannot be serialized. Make sure the function bool do_serialize(std::ostream&, const ",
|
||||
type_name,
|
||||
"&) exists and can be located by ADL\n");
|
||||
os << "__NONSERIALIZABLE__\n";
|
||||
return os.good();
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
template <typename Container>
|
||||
class SerializableObjectData
|
||||
{
|
||||
public:
|
||||
template <typename Contained>
|
||||
explicit SerializableObjectData(details::SerializableObjectDescriptor<Contained>&& /*unused*/)
|
||||
: serialize_{[](std::ostream& os, const Container& container) -> bool {
|
||||
return details::serialize_internal(os, details::get_container_content<Contained>(container));
|
||||
}}
|
||||
{}
|
||||
|
||||
bool serialize(const Container& container, std::ostream& os) const noexcept
|
||||
{
|
||||
return serialize_(os, container);
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<bool(std::ostream&, const Container&)> serialize_;
|
||||
};
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_SERIALIZABLE_OBJECT_DATA_H
|
||||
70
include/Raychel/Core/Types.h
Normal file
70
include/Raychel/Core/Types.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/**
|
||||
* \file Types.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Types class
|
||||
* \date 2022-04-10
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_TYPES_H
|
||||
#define RAYCHEL_TYPES_H
|
||||
|
||||
#include "RaychelMath/Transform.h"
|
||||
#include "RaychelMath/color.h"
|
||||
#include "RaychelMath/vec2.h"
|
||||
#include "RaychelMath/vec3.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
using vec3 = basic_vec3<double>;
|
||||
using color = basic_color<double>;
|
||||
using Quaternion = basic_quaternion<double>;
|
||||
using Transform = basic_transform<double>;
|
||||
|
||||
using Size2D = basic_vec2<std::size_t>;
|
||||
|
||||
class SDFContainer;
|
||||
|
||||
class Scene;
|
||||
|
||||
struct RenderData;
|
||||
|
||||
using BackgroundFunction = std::function<color(const RenderData&)>;
|
||||
|
||||
template <typename T>
|
||||
struct DeserializationTag
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
struct has_target : std::false_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool has_target_v = has_target<T>::value && requires(T t){
|
||||
t.target;
|
||||
};
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_TYPES_H
|
||||
153
include/Raychel/Core/Xoroshiro128+.h
Normal file
153
include/Raychel/Core/Xoroshiro128+.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* \file Xoroshiro128+.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Xoroshiro128+ class
|
||||
* \date 2022-04-24
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_XOROSHIRO128_H
|
||||
#define RAYCHEL_XOROSHIRO128_H
|
||||
|
||||
#include <bit>
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
//This is an implementation of the xoroshiro128+ algorithm as described at https://prng.di.unimi.it/xoroshiro128plus.c ported to C++20
|
||||
|
||||
// template<int A=24, int B=16, int C=37>
|
||||
|
||||
//TODO: template this once we figure out how jump() and long_jump() can be generalized
|
||||
class Xoroshiro128
|
||||
{
|
||||
struct TwoUint64s
|
||||
{
|
||||
std::uint64_t first, second;
|
||||
};
|
||||
|
||||
public:
|
||||
static constexpr std::int32_t A = 24, B = 16, C = 37;
|
||||
|
||||
constexpr Xoroshiro128() = default;
|
||||
|
||||
constexpr Xoroshiro128(std::uint64_t seed) : state_{seed, 0}
|
||||
{
|
||||
jump(); //jump through the domain a bit so we don't get weird results on the first call to next()
|
||||
}
|
||||
|
||||
constexpr Xoroshiro128(std::uint64_t s0, std::uint64_t s1) : state_{s0, s1}
|
||||
{}
|
||||
|
||||
static constexpr auto min() noexcept
|
||||
{
|
||||
return std::numeric_limits<std::uint64_t>::min();
|
||||
}
|
||||
|
||||
static constexpr auto max() noexcept
|
||||
{
|
||||
return std::numeric_limits<std::uint64_t>::max();
|
||||
}
|
||||
|
||||
template <std::integral Result = std::uint64_t>
|
||||
[[nodiscard]] constexpr Result operator()() noexcept
|
||||
{
|
||||
return next<Result>();
|
||||
}
|
||||
|
||||
template <std::integral Result = std::uint64_t>
|
||||
constexpr Result next() noexcept
|
||||
{
|
||||
static_assert(sizeof(Result) <= sizeof(std::uint64_t), "Xoroshiro128+ cannot produce more than 64 random bits!");
|
||||
|
||||
auto [s0, s1] = state_;
|
||||
const auto result = static_cast<Result>(s0 + s1);
|
||||
|
||||
s1 ^= s0;
|
||||
state_.first = std::rotl(s0, A) ^ s1 ^ (s1 << B);
|
||||
state_.second = std::rotl(s1, C);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr void jump() noexcept
|
||||
{
|
||||
uint64_t s0{};
|
||||
uint64_t s1{};
|
||||
|
||||
for (std::size_t b{}; b != 64U; ++b) {
|
||||
if (short_jump_.first & std::uint64_t{1} << b) {
|
||||
s0 ^= state_.first;
|
||||
s1 ^= state_.second;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
for (std::size_t b{}; b != 64U; ++b) {
|
||||
if (short_jump_.second & std::uint64_t{1} << b) {
|
||||
s0 ^= state_.first;
|
||||
s1 ^= state_.second;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
state_.first = s0;
|
||||
state_.second = s1;
|
||||
}
|
||||
|
||||
constexpr void long_jump() noexcept
|
||||
{
|
||||
uint64_t s0{};
|
||||
uint64_t s1{};
|
||||
|
||||
for (std::size_t b{}; b != 64; ++b) {
|
||||
if (long_jump_.first & std::uint64_t{1} << b) {
|
||||
s0 ^= state_.first;
|
||||
s1 ^= state_.second;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
for (std::size_t b{}; b != 64; ++b) {
|
||||
if (long_jump_.second & std::uint64_t{1} << b) {
|
||||
s0 ^= state_.first;
|
||||
s1 ^= state_.second;
|
||||
}
|
||||
next();
|
||||
}
|
||||
|
||||
state_.first = s0;
|
||||
state_.second = s1;
|
||||
}
|
||||
|
||||
private:
|
||||
TwoUint64s state_{123456789, 987654321};
|
||||
|
||||
static constexpr TwoUint64s short_jump_{0xdf900294d8f554a5, 0x170865df4b3201fc};
|
||||
static constexpr TwoUint64s long_jump_{0xd2a98b26625eee7b, 0xdddf9b1090aa7ac1};
|
||||
};
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_XOROSHIRO128_H
|
||||
39
include/Raychel/Core/ZigguratNormal.h
Normal file
39
include/Raychel/Core/ZigguratNormal.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* \file ZigguratNormal.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for ZigguratNormal class
|
||||
* \date 2022-04-24
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_ZIGGURAT_NORMAL_H
|
||||
#define RAYCHEL_ZIGGURAT_NORMAL_H
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
[[nodiscard]] double uniform_random() noexcept;
|
||||
|
||||
[[nodiscard]] double ziggurat_normal() noexcept;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_ZIGGURAT_NORMAL_H
|
||||
43
include/Raychel/Render/Camera.h
Normal file
43
include/Raychel/Render/Camera.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* \file Camera.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Camera class
|
||||
* \date 2022-04-11
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_CAMERA_H
|
||||
#define RAYCHEL_CAMERA_H
|
||||
|
||||
#include "Raychel/Core/Types.h"
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct Camera
|
||||
{
|
||||
Transform transform;
|
||||
double zoom{1.0};
|
||||
};
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_CAMERA_H
|
||||
50
include/Raychel/Render/Denoise.h
Normal file
50
include/Raychel/Render/Denoise.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* \file Denoise.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Denoise class
|
||||
* \date 2022-05-06
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_DENOISE_H
|
||||
#define RAYCHEL_DENOISE_H
|
||||
|
||||
#include "FatPixel.h"
|
||||
#include "Framebuffer.h"
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct DenoisingOptions
|
||||
{
|
||||
std::size_t half_patch_size{1};
|
||||
std::size_t half_search_window_size{6};
|
||||
double distance_threshold{1.};
|
||||
std::size_t num_scales{3};
|
||||
};
|
||||
|
||||
Framebuffer denoise_single_scale(const FatFramebuffer& input_pixels, DenoisingOptions options = {}) noexcept;
|
||||
|
||||
Framebuffer denoise_multiscale(const FatFramebuffer& input_pixels, DenoisingOptions options = {}) noexcept;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_DENOISE_H
|
||||
64
include/Raychel/Render/FatPixel.h
Normal file
64
include/Raychel/Render/FatPixel.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* \file FatPixel.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for FatPixel class
|
||||
* \date 2022-05-01
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_FAT_PIXEL_H
|
||||
#define RAYCHEL_FAT_PIXEL_H
|
||||
|
||||
#include "RayHistogram.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
template <std::size_t NumBins>
|
||||
struct FatPixel
|
||||
{
|
||||
using Histogram = RayHistogram<NumBins>;
|
||||
|
||||
FatPixel operator+(const FatPixel& other) const noexcept
|
||||
{
|
||||
return {noisy_color + other.noisy_color, histogram + other.histogram};
|
||||
}
|
||||
|
||||
template <std::convertible_to<double> T>
|
||||
FatPixel operator/(T s) const noexcept
|
||||
{
|
||||
return {noisy_color / s, histogram / s};
|
||||
}
|
||||
|
||||
color noisy_color{};
|
||||
Histogram histogram{};
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
using FatPixel = details::FatPixel<30U>;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_FAT_PIXEL_H
|
||||
77
include/Raychel/Render/Framebuffer.h
Normal file
77
include/Raychel/Render/Framebuffer.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
* \file Framebuffer.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Framebuffer class
|
||||
* \date 2022-04-11
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_FRAMEBUFFER_H
|
||||
#define RAYCHEL_FRAMEBUFFER_H
|
||||
|
||||
#include "FatPixel.h"
|
||||
#include "Raychel/Core/Types.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
template <typename Pixel>
|
||||
struct BasicFramebuffer
|
||||
{
|
||||
|
||||
constexpr Pixel& at(std::size_t x, std::size_t y)
|
||||
{
|
||||
return const_cast<Pixel&>(const_cast<const BasicFramebuffer*>(this)->at(x, y));
|
||||
}
|
||||
|
||||
constexpr const Pixel& at(std::size_t x, std::size_t y) const
|
||||
{
|
||||
RAYCHEL_ASSERT((x < size.x()) && (y < size.y()));
|
||||
|
||||
return pixel_data.at(x + (y * size.x()));
|
||||
}
|
||||
|
||||
const Size2D size{};
|
||||
std::vector<Pixel> pixel_data{};
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
constexpr auto begin(const BasicFramebuffer<T>& obj)
|
||||
{
|
||||
return obj.pixel_data.begin();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
constexpr auto end(const BasicFramebuffer<T>& obj)
|
||||
{
|
||||
return obj.pixel_data.end();
|
||||
}
|
||||
} // namespace details
|
||||
|
||||
using Framebuffer = details::BasicFramebuffer<color>;
|
||||
using FatFramebuffer = details::BasicFramebuffer<FatPixel>;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_FRAMEBUFFER_H
|
||||
130
include/Raychel/Render/MaterialContainer.h
Normal file
130
include/Raychel/Render/MaterialContainer.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/**
|
||||
* \file MaterialContainer.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for MaterialContainer class
|
||||
* \date 2022-04-10
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_MATERIAL_CONTAINER_H
|
||||
#define RAYCHEL_MATERIAL_CONTAINER_H
|
||||
|
||||
#include "Materials.h"
|
||||
|
||||
#include "Raychel/Core/Types.h"
|
||||
#include "RaychelCore/Badge.h"
|
||||
#include "RaychelCore/ClassMacros.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
|
||||
struct IMaterialContainerImpl
|
||||
{
|
||||
IMaterialContainerImpl() = default;
|
||||
|
||||
RAYCHEL_MAKE_NONCOPY_NONMOVE(IMaterialContainerImpl)
|
||||
|
||||
[[nodiscard]] virtual color get_surface_color_internal(const ShadingData& data) const noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual double get_material_ior_internal() const noexcept = 0;
|
||||
|
||||
virtual ~IMaterialContainerImpl() = default;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class MaterialContainerImpl final : public IMaterialContainerImpl
|
||||
{
|
||||
public:
|
||||
explicit MaterialContainerImpl(T&& object) noexcept(std::is_nothrow_move_constructible_v<T>)
|
||||
: object_{std::forward<T>(object)}
|
||||
{}
|
||||
|
||||
[[nodiscard]] color get_surface_color_internal(const ShadingData& data) const noexcept override
|
||||
{
|
||||
return get_surface_color(object_, data);
|
||||
}
|
||||
|
||||
[[nodiscard]] double get_material_ior_internal() const noexcept override
|
||||
{
|
||||
if constexpr (is_transparent_material_v<T>)
|
||||
return get_material_ior(object_);
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
[[nodiscard]] T& object() noexcept
|
||||
{
|
||||
return object_;
|
||||
}
|
||||
|
||||
[[nodiscard]] const T& object() const noexcept
|
||||
{
|
||||
return object_;
|
||||
}
|
||||
|
||||
private:
|
||||
T object_;
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
class MaterialContainer
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
using Impl = details::MaterialContainerImpl<T>;
|
||||
|
||||
template <typename T>
|
||||
requires(!std::is_same_v<T, MaterialContainer>) explicit MaterialContainer(T&& object) noexcept(
|
||||
std::is_nothrow_move_constructible_v<T>)
|
||||
: impl_{std::make_unique<details::MaterialContainerImpl<T>>(std::forward<T>(object))}
|
||||
{}
|
||||
|
||||
RAYCHEL_MAKE_NONCOPY(MaterialContainer)
|
||||
RAYCHEL_MAKE_DEFAULT_MOVE(MaterialContainer)
|
||||
|
||||
[[nodiscard]] color get_surface_color(const ShadingData& data) const noexcept
|
||||
{
|
||||
return impl_->get_surface_color_internal(data);
|
||||
}
|
||||
|
||||
[[nodiscard]] double get_material_ior() const noexcept
|
||||
{
|
||||
return impl_->get_material_ior_internal();
|
||||
}
|
||||
|
||||
[[nodiscard]] auto* unsafe_impl() const noexcept
|
||||
{
|
||||
return impl_.get();
|
||||
}
|
||||
|
||||
~MaterialContainer() = default;
|
||||
|
||||
private:
|
||||
std::unique_ptr<details::IMaterialContainerImpl> impl_{};
|
||||
};
|
||||
|
||||
} //namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_MATERIAL_CONTAINER_H
|
||||
66
include/Raychel/Render/Materials.h
Normal file
66
include/Raychel/Render/Materials.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* \file Materials.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Materials class
|
||||
* \date 2022-05-20
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_MATERIALS_H
|
||||
#define RAYCHEL_MATERIALS_H
|
||||
|
||||
#include "Raychel/Core/Types.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct RenderState;
|
||||
|
||||
struct ShadingData
|
||||
{
|
||||
vec3 position;
|
||||
vec3 normal;
|
||||
vec3 incoming_direction;
|
||||
|
||||
const RenderState& state;
|
||||
std::size_t recursion_depth;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_transparent_material : std::false_type
|
||||
{};
|
||||
|
||||
template <typename T>
|
||||
constexpr bool is_transparent_material_v = is_transparent_material<T>::value;
|
||||
|
||||
struct DeserializationErrorMaterial
|
||||
{};
|
||||
|
||||
constexpr color get_surface_color(DeserializationErrorMaterial /*unused*/, const ShadingData& /*unused*/) noexcept
|
||||
{
|
||||
return color{1, 0, 1};
|
||||
}
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_MATERIALS_H
|
||||
153
include/Raychel/Render/RayHistogram.h
Normal file
153
include/Raychel/Render/RayHistogram.h
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* \file RayHistogram.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for RayHistogram class
|
||||
* \date 2022-04-30
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_RAY_HISTOGRAM_H
|
||||
#define RAYCHEL_RAY_HISTOGRAM_H
|
||||
|
||||
#include "Raychel/Core/Types.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
namespace details {
|
||||
|
||||
struct BinData
|
||||
{
|
||||
std::size_t low_bin_index{};
|
||||
double low_bin_weight{};
|
||||
|
||||
std::size_t high_bin_index{};
|
||||
double high_bin_weight{};
|
||||
};
|
||||
}; // namespace details
|
||||
|
||||
template <std::size_t NumBins>
|
||||
requires(NumBins > 2U) class RayHistogram
|
||||
{
|
||||
using BinnedChannel = std::array<double, NumBins>;
|
||||
|
||||
public:
|
||||
RayHistogram() = default;
|
||||
|
||||
void add_sample(color c) noexcept
|
||||
{
|
||||
_add_channel(red_, c.r());
|
||||
_add_channel(green_, c.g());
|
||||
_add_channel(blue_, c.b());
|
||||
}
|
||||
|
||||
const auto& red_channel() const noexcept
|
||||
{
|
||||
return red_;
|
||||
}
|
||||
|
||||
const auto& green_channel() const noexcept
|
||||
{
|
||||
return green_;
|
||||
}
|
||||
|
||||
const auto& blue_channel() const noexcept
|
||||
{
|
||||
return blue_;
|
||||
}
|
||||
|
||||
RayHistogram operator+(const RayHistogram& other) const noexcept
|
||||
{
|
||||
BinnedChannel union_red{}, union_green{}, union_blue{};
|
||||
|
||||
for (std::size_t i{}; i != NumBins; ++i) {
|
||||
union_red[i] = red_[i] + other.red_[i];
|
||||
union_green[i] = green_[i] + other.green_[i];
|
||||
union_blue[i] = blue_[i] + other.blue_[i];
|
||||
}
|
||||
|
||||
return {std::move(union_red), std::move(union_green), std::move(union_blue)};
|
||||
}
|
||||
|
||||
template <std::convertible_to<double> T>
|
||||
RayHistogram operator/(T _s) const noexcept
|
||||
{
|
||||
const auto s = static_cast<double>(_s);
|
||||
|
||||
BinnedChannel new_red{}, new_green{}, new_blue{};
|
||||
for (std::size_t i{}; i != NumBins; ++i) {
|
||||
new_red[i] = red_[i] / s;
|
||||
new_green[i] = green_[i] / s;
|
||||
new_blue[i] = blue_[i] / s;
|
||||
}
|
||||
|
||||
return {std::move(new_red), std::move(new_green), std::move(new_blue)};
|
||||
}
|
||||
|
||||
private:
|
||||
RayHistogram(BinnedChannel red, BinnedChannel green, BinnedChannel blue)
|
||||
: red_{std::move(red)}, green_{std::move(green)}, blue_{std::move(blue)}
|
||||
{}
|
||||
|
||||
static void _add_channel(BinnedChannel& channel, double value) noexcept
|
||||
{
|
||||
const auto [low_bin, low_weight, high_bin, high_weight] = _get_bin_data(value);
|
||||
channel.at(low_bin) += low_weight;
|
||||
channel.at(high_bin) += high_weight;
|
||||
}
|
||||
|
||||
static details::BinData _get_bin_data(double value) noexcept
|
||||
{
|
||||
constexpr auto max_value = 7.5;
|
||||
constexpr auto saturated_value = 2.5;
|
||||
constexpr auto fbin_factor = static_cast<double>(NumBins - 2U);
|
||||
|
||||
auto v = std::max(value, 0.0);
|
||||
v = std::pow(v, 1.0 / 2.2);
|
||||
v /= max_value;
|
||||
|
||||
v = std::min(saturated_value, v);
|
||||
|
||||
const auto fbin = v * fbin_factor;
|
||||
|
||||
const auto bin_low = static_cast<std::size_t>(fbin);
|
||||
if (bin_low < (NumBins - 2U)) {
|
||||
const auto high_weight = std::fmod(fbin, 1.0);
|
||||
const auto low_weight = 1.0 - high_weight;
|
||||
|
||||
return {bin_low, low_weight, bin_low + 1U, high_weight};
|
||||
}
|
||||
const auto high_weight = (v - 1) / (saturated_value - 1);
|
||||
const auto low_weight = 1.0 - high_weight;
|
||||
|
||||
return {NumBins - 2U, low_weight, NumBins - 1U, high_weight};
|
||||
}
|
||||
|
||||
BinnedChannel red_{};
|
||||
BinnedChannel green_{};
|
||||
BinnedChannel blue_{};
|
||||
};
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_RAY_HISTOGRAM_H
|
||||
55
include/Raychel/Render/RenderUtils.h
Normal file
55
include/Raychel/Render/RenderUtils.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* \file RenderHelper.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for RenderHelper class
|
||||
* \date 2022-04-12
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_RENDER_UTILS_H
|
||||
#define RAYCHEL_RENDER_UTILS_H
|
||||
|
||||
#include "Renderer.h"
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct RefractionData
|
||||
{
|
||||
vec3 surface_point;
|
||||
vec3 incoming_direction;
|
||||
vec3 normal;
|
||||
|
||||
double material_ior;
|
||||
double ior_variation;
|
||||
|
||||
const RenderState& state;
|
||||
std::size_t recursion_depth;
|
||||
};
|
||||
|
||||
[[nodiscard]] color get_shaded_color(const RenderData& data) noexcept;
|
||||
|
||||
[[nodiscard]] color get_diffuse_lighting(const ShadingData& data) noexcept;
|
||||
|
||||
[[nodiscard]] color get_refraction(const RefractionData& data) noexcept;
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_RENDER_UTILS_H
|
||||
95
include/Raychel/Render/Renderer.h
Normal file
95
include/Raychel/Render/Renderer.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* \file Renderer.h
|
||||
* \author Weckyy702 (weckyy702@gmail.com)
|
||||
* \brief Header file for Renderer class
|
||||
* \date 2022-04-11
|
||||
*
|
||||
* MIT License
|
||||
* Copyright (c) [2022] [Weckyy702 (weckyy702@gmail.com | https://github.com/Weckyy702)]
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#ifndef RAYCHEL_RENDERER_H
|
||||
#define RAYCHEL_RENDERER_H
|
||||
|
||||
#include "Camera.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "MaterialContainer.h"
|
||||
#include "Raychel/Core/SDFContainer.h"
|
||||
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
namespace Raychel {
|
||||
|
||||
struct RenderOptions
|
||||
{
|
||||
//Size of the output image
|
||||
Size2D output_size{1280, 720};
|
||||
|
||||
//Maximum number of steps until raymarching terminates
|
||||
std::size_t max_ray_steps{1'024};
|
||||
|
||||
//Maximum depth for recursive algorithms
|
||||
std::size_t max_recursion_depth{6};
|
||||
|
||||
//Maximum number of light bounces for indirect lighting
|
||||
std::size_t max_lighting_bounces{2};
|
||||
|
||||
//Number of samples per pixel for rendering. Dramatically increases render times!
|
||||
std::size_t samples_per_pixel{128};
|
||||
|
||||
//If antialiasing is used. (Low performance impact)
|
||||
bool do_aa{true};
|
||||
|
||||
//How many threads are used for rendering. If 0, the library will choose
|
||||
std::size_t thread_count{0};
|
||||
|
||||
//Maximum distance a ray can travel
|
||||
double max_ray_depth{500};
|
||||
|
||||
//Maximum distance between the ray and a surface
|
||||
double surface_epsilon{1e-6};
|
||||
//Radius used for normal calculation. Should be smaller than surface_epsilon to avoid weirdness
|
||||
double normal_epsilon{1e-12};
|
||||
//Offset along the surface normal to avoid shadow weirdness. Should be larger than surface_epsilon
|
||||
double shading_epsilon{1e-5};
|
||||
};
|
||||
|
||||
struct RenderState
|
||||
{
|
||||
const std::vector<SDFContainer>& surfaces;
|
||||
const std::vector<MaterialContainer>& materials;
|
||||
BackgroundFunction get_background{};
|
||||
RenderOptions options{};
|
||||
};
|
||||
|
||||
struct RenderData
|
||||
{
|
||||
vec3 origin, direction;
|
||||
|
||||
const RenderState& state;
|
||||
std::size_t recursion_depth;
|
||||
};
|
||||
|
||||
FatFramebuffer render_scene(const Scene& scene, const Camera& camera, const RenderOptions& options = {}) noexcept;
|
||||
|
||||
} // namespace Raychel
|
||||
|
||||
#endif //!RAYCHEL_RENDERER_H
|
||||
Reference in New Issue
Block a user