Skip to content

Commit

Permalink
Upgrades SDFGI to HDDAGI
Browse files Browse the repository at this point in the history
Supersedes godotengine#86007

This is a new global illumination system that is a full upgrade to SDFGI
Key advantages are:

* Significantly faster base frame time.
* An order of magnitude faster updates (SDFGI drops frames very significantly when moving, as a consequence of having to redo its entire SDF even for a small motion).
* Higher quality (less light leaks, properly energy conservation, much better reflections, others)
* Occlusion remains the same as in SDFGI. I experimented with other systems (the one in DDGI) but everything has worse tradeoffs.

It is meant as a drop-in replacement, so games using SDFGI should get HDDAGI transparently.

TODO:

- [ ] For some reason gets DEVICE LOST on Intel GPUs. Can´t figure out why.
- [ ] Waiting for a PR fixing the normal buffer precision in order to fix some issues.

TODO AFTER MERGING:

- [ ] High density probes support.
- [ ] Dynamic objects support.

Known issues:
  • Loading branch information
reduz authored and fire committed Mar 31, 2024
1 parent 0acfb38 commit 5d1bbcd
Show file tree
Hide file tree
Showing 77 changed files with 8,078 additions and 6,117 deletions.
70 changes: 70 additions & 0 deletions core/math/vector2i.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,73 @@ Vector2i::operator String() const {
Vector2i::operator Vector2() const {
return Vector2((int32_t)x, (int32_t)y);
}

Vector2i &Vector2i::operator>>=(const Vector2i &p_v) {
x >>= p_v.x;
y >>= p_v.y;
return *this;
}

Vector2i Vector2i::operator>>(const Vector2i &p_v) const {
return Vector2i(x >> p_v.x, y >> p_v.y);
}

Vector2i &Vector2i::operator<<=(const Vector2i &p_v) {
x <<= p_v.x;
y <<= p_v.y;
return *this;
}

Vector2i Vector2i::operator<<(const Vector2i &p_v) const {
return Vector2i(x << p_v.x, y << p_v.y);
}

Vector2i &Vector2i::operator<<=(const int32_t p_scalar) {
x <<= p_scalar;
y <<= p_scalar;
return *this;
}

Vector2i Vector2i::operator<<(const int32_t p_scalar) const {
return Vector2i(x << p_scalar, y << p_scalar);
}

Vector2i &Vector2i::operator>>=(const int32_t p_scalar) {
x >>= p_scalar;
y >>= p_scalar;
return *this;
}

Vector2i Vector2i::operator>>(const int32_t p_scalar) const {
return Vector2i(x >> p_scalar, y >> p_scalar);
}

Vector2i Vector2i::operator|(const Vector2i &p_v) const {
return Vector2i(x | p_v.x, y | p_v.y);
}

Vector2i &Vector2i::operator|=(const Vector2i &p_v) {
x |= p_v.x;
y |= p_v.y;
return *this;
}

Vector2i Vector2i::operator&(const Vector2i &p_v) const {
return Vector2i(x & p_v.x, y & p_v.y);
}

Vector2i &Vector2i::operator&=(const Vector2i &p_v) {
x &= p_v.x;
y &= p_v.y;
return *this;
}

Vector2i Vector2i::operator^(const Vector2i &p_v) const {
return Vector2i(x ^ p_v.x, y ^ p_v.y);
}

Vector2i &Vector2i::operator^=(const Vector2i &p_v) {
x ^= p_v.x;
y ^= p_v.y;
return *this;
}
17 changes: 17 additions & 0 deletions core/math/vector2i.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,23 @@ struct _NO_DISCARD_ Vector2i {
bool operator==(const Vector2i &p_vec2) const;
bool operator!=(const Vector2i &p_vec2) const;

Vector2i operator>>(const Vector2i &p_v) const;
Vector2i &operator>>=(const Vector2i &p_v);
Vector2i operator<<(const Vector2i &p_v) const;
Vector2i &operator<<=(const Vector2i &p_v);

Vector2i &operator>>=(const int32_t p_scalar);
Vector2i operator>>(const int32_t p_scalar) const;
Vector2i &operator<<=(const int32_t p_scalar);
Vector2i operator<<(const int32_t p_scalar) const;

Vector2i operator|(const Vector2i &p_v) const;
Vector2i &operator|=(const Vector2i &p_v);
Vector2i operator&(const Vector2i &p_v) const;
Vector2i &operator&=(const Vector2i &p_v);
Vector2i operator^(const Vector2i &p_v) const;
Vector2i &operator^=(const Vector2i &p_v);

int64_t length_squared() const;
double length() const;

Expand Down
95 changes: 95 additions & 0 deletions core/math/vector3i.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,31 @@ struct _NO_DISCARD_ Vector3i {
_FORCE_INLINE_ Vector3i &operator%=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator%(const Vector3i &p_v) const;


_FORCE_INLINE_ Vector3i &operator*=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator/=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator/(int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator%=(int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator%(int32_t p_scalar) const;

_FORCE_INLINE_ Vector3i operator>>(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator>>=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator<<(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator<<=(const Vector3i &p_v);

_FORCE_INLINE_ Vector3i &operator>>=(const int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator>>(const int32_t p_scalar) const;
_FORCE_INLINE_ Vector3i &operator<<=(const int32_t p_scalar);
_FORCE_INLINE_ Vector3i operator<<(const int32_t p_scalar) const;

_FORCE_INLINE_ Vector3i operator|(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator|=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator&(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator&=(const Vector3i &p_v);
_FORCE_INLINE_ Vector3i operator^(const Vector3i &p_v) const;
_FORCE_INLINE_ Vector3i &operator^=(const Vector3i &p_v);

_FORCE_INLINE_ Vector3i operator-() const;

_FORCE_INLINE_ bool operator==(const Vector3i &p_v) const;
Expand Down Expand Up @@ -222,6 +240,61 @@ Vector3i Vector3i::operator*(int32_t p_scalar) const {
return Vector3i(x * p_scalar, y * p_scalar, z * p_scalar);
}

Vector3i &Vector3i::operator>>=(const Vector3i &p_v) {
x >>= p_v.x;
y >>= p_v.y;
z >>= p_v.z;
return *this;
}

Vector3i Vector3i::operator>>(const Vector3i &p_v) const {
return Vector3i(x >> p_v.x, y >> p_v.y, z >> p_v.z);
}

Vector3i &Vector3i::operator<<=(const Vector3i &p_v) {
x <<= p_v.x;
y <<= p_v.y;
z <<= p_v.z;
return *this;
}

Vector3i Vector3i::operator<<(const Vector3i &p_v) const {
return Vector3i(x << p_v.x, y << p_v.y, z << p_v.z);
}

Vector3i &Vector3i::operator&=(const Vector3i &p_v) {
x &= p_v.x;
y &= p_v.y;
z &= p_v.z;
return *this;
}

Vector3i Vector3i::operator&(const Vector3i &p_v) const {
return Vector3i(x & p_v.x, y & p_v.y, z & p_v.z);
}

Vector3i &Vector3i::operator|=(const Vector3i &p_v) {
x |= p_v.x;
y |= p_v.y;
z |= p_v.z;
return *this;
}

Vector3i Vector3i::operator|(const Vector3i &p_v) const {
return Vector3i(x | p_v.x, y | p_v.y, z | p_v.z);
}

Vector3i &Vector3i::operator^=(const Vector3i &p_v) {
x ^= p_v.x;
y ^= p_v.y;
z ^= p_v.z;
return *this;
}

Vector3i Vector3i::operator^(const Vector3i &p_v) const {
return Vector3i(x ^ p_v.x, y ^ p_v.y, z ^ p_v.z);
}

// Multiplication operators required to workaround issues with LLVM using implicit conversion.

_FORCE_INLINE_ Vector3i operator*(int32_t p_scalar, const Vector3i &p_vector) {
Expand Down Expand Up @@ -262,6 +335,28 @@ Vector3i Vector3i::operator%(int32_t p_scalar) const {
return Vector3i(x % p_scalar, y % p_scalar, z % p_scalar);
}

Vector3i &Vector3i::operator<<=(const int32_t p_scalar) {
x <<= p_scalar;
y <<= p_scalar;
z <<= p_scalar;
return *this;
}

Vector3i Vector3i::operator<<(const int32_t p_scalar) const {
return Vector3i(x << p_scalar, y << p_scalar, z << p_scalar);
}

Vector3i &Vector3i::operator>>=(const int32_t p_scalar) {
x >>= p_scalar;
y >>= p_scalar;
z >>= p_scalar;
return *this;
}

Vector3i Vector3i::operator>>(const int32_t p_scalar) const {
return Vector3i(x >> p_scalar, y >> p_scalar, z >> p_scalar);
}

Vector3i Vector3i::operator-() const {
return Vector3i(-x, -y, -z);
}
Expand Down
18 changes: 18 additions & 0 deletions core/variant/variant_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,24 @@ void Variant::_register_variant_operators() {
register_op<OperatorEvaluatorPos<Plane, Plane>>(Variant::OP_POSITIVE, Variant::PLANE, Variant::NIL);
register_op<OperatorEvaluatorPos<Color, Color>>(Variant::OP_POSITIVE, Variant::COLOR, Variant::NIL);

register_op<OperatorEvaluatorShiftLeft<Vector2i, Vector2i, int64_t>>(Variant::OP_SHIFT_LEFT, Variant::VECTOR2I, Variant::INT);
register_op<OperatorEvaluatorShiftRight<Vector2i, Vector2i, int64_t>>(Variant::OP_SHIFT_RIGHT, Variant::VECTOR2I, Variant::INT);
register_op<OperatorEvaluatorShiftLeftVector<Vector2i, Vector2i, Vector2i>>(Variant::OP_SHIFT_LEFT, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorShiftRightVector<Vector2i, Vector2i, Vector2i>>(Variant::OP_SHIFT_RIGHT, Variant::VECTOR2I, Variant::VECTOR2I);

register_op<OperatorEvaluatorShiftLeft<Vector3i, Vector3i, int64_t>>(Variant::OP_SHIFT_LEFT, Variant::VECTOR3I, Variant::INT);
register_op<OperatorEvaluatorShiftRight<Vector3i, Vector3i, int64_t>>(Variant::OP_SHIFT_RIGHT, Variant::VECTOR3I, Variant::INT);
register_op<OperatorEvaluatorShiftLeftVector<Vector3i, Vector3i, Vector3i>>(Variant::OP_SHIFT_LEFT, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorShiftRightVector<Vector3i, Vector3i, Vector3i>>(Variant::OP_SHIFT_RIGHT, Variant::VECTOR3I, Variant::VECTOR3I);

register_op<OperatorEvaluatorBitOr<Vector2i, Vector2i, Vector2i>>(Variant::OP_BIT_OR, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorBitAnd<Vector2i, Vector2i, Vector2i>>(Variant::OP_BIT_AND, Variant::VECTOR2I, Variant::VECTOR2I);
register_op<OperatorEvaluatorBitXor<Vector2i, Vector2i, Vector2i>>(Variant::OP_BIT_XOR, Variant::VECTOR2I, Variant::VECTOR2I);

register_op<OperatorEvaluatorBitOr<Vector3i, Vector3i, Vector3i>>(Variant::OP_BIT_OR, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorBitAnd<Vector3i, Vector3i, Vector3i>>(Variant::OP_BIT_AND, Variant::VECTOR3I, Variant::VECTOR3I);
register_op<OperatorEvaluatorBitXor<Vector3i, Vector3i, Vector3i>>(Variant::OP_BIT_XOR, Variant::VECTOR3I, Variant::VECTOR3I);

register_op<OperatorEvaluatorShiftLeft<int64_t, int64_t, int64_t>>(Variant::OP_SHIFT_LEFT, Variant::INT, Variant::INT);
register_op<OperatorEvaluatorShiftRight<int64_t, int64_t, int64_t>>(Variant::OP_SHIFT_RIGHT, Variant::INT, Variant::INT);
register_op<OperatorEvaluatorBitOr<int64_t, int64_t, int64_t>>(Variant::OP_BIT_OR, Variant::INT, Variant::INT);
Expand Down
46 changes: 42 additions & 4 deletions core/variant/variant_op.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ class OperatorEvaluatorShiftLeft {
const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right);

#if defined(DEBUG_ENABLED)
if (b < 0 || a < 0) {
*r_ret = "Invalid operands for bit shifting. Only positive operands are supported.";
if (b < 0) {
*r_ret = "Invalid operands for bit shifting. Only positive shifts are supported.";
r_valid = false;
return;
}
Expand All @@ -439,8 +439,8 @@ class OperatorEvaluatorShiftRight {
const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right);

#if defined(DEBUG_ENABLED)
if (b < 0 || a < 0) {
*r_ret = "Invalid operands for bit shifting. Only positive operands are supported.";
if (b < 0) {
*r_ret = "Invalid operands for bit shifting. Only positive shifts are supported.";
r_valid = false;
return;
}
Expand All @@ -457,6 +457,44 @@ class OperatorEvaluatorShiftRight {
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};

template <typename R, typename A, typename B>
class OperatorEvaluatorShiftRightVector {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left);
const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right);

*r_ret = a >> b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
*VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) >> *VariantGetInternalPtr<B>::get_ptr(right);
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<R>::encode(PtrToArg<A>::convert(left) >> PtrToArg<B>::convert(right), r_ret);
}
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};

template <typename R, typename A, typename B>
class OperatorEvaluatorShiftLeftVector {
public:
static void evaluate(const Variant &p_left, const Variant &p_right, Variant *r_ret, bool &r_valid) {
const A &a = *VariantGetInternalPtr<A>::get_ptr(&p_left);
const B &b = *VariantGetInternalPtr<B>::get_ptr(&p_right);

*r_ret = a << b;
r_valid = true;
}
static inline void validated_evaluate(const Variant *left, const Variant *right, Variant *r_ret) {
*VariantGetInternalPtr<R>::get_ptr(r_ret) = *VariantGetInternalPtr<A>::get_ptr(left) << *VariantGetInternalPtr<B>::get_ptr(right);
}
static void ptr_evaluate(const void *left, const void *right, void *r_ret) {
PtrToArg<R>::encode(PtrToArg<A>::convert(left) << PtrToArg<B>::convert(right), r_ret);
}
static Variant::Type get_return_type() { return GetTypeInfo<R>::VARIANT_TYPE; }
};

template <typename R, typename A, typename B>
class OperatorEvaluatorBitOr {
public:
Expand Down

0 comments on commit 5d1bbcd

Please sign in to comment.