Browse Source

More reflections work

Panagiotis Christopoulos Charitos 10 years ago
parent
commit
942b07966e
4 changed files with 76 additions and 23 deletions
  1. 8 4
      include/anki/math/Vec3.h
  2. 18 14
      include/anki/math/Vec4.h
  3. 49 4
      shaders/ImageReflections.glsl
  4. 1 1
      src/renderer/Clusterer.cpp

+ 8 - 4
include/anki/math/Vec3.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_MATH_VEC3_H
-#define ANKI_MATH_VEC3_H
+#pragma once
 
 #include "anki/math/CommonIncludes.h"
 #include "anki/math/Vec.h"
@@ -76,10 +75,16 @@ public:
 			x() * b.y() - y() * b.x());
 	}
 
-	TVec3 getProjection(const TVec3& toThis) const
+	TVec3 projectTo(const TVec3& toThis) const
 	{
 		return toThis * ((*this).dot(toThis) / (toThis.dot(toThis)));
 	}
+
+	TVec3 projectTo(const TVec3& rayOrigin, const TVec3& rayDir) const
+	{
+		const auto& a = *this;
+		return rayOrigin + rayDir * ((a - rayOrigin).dot(rayDir));
+	}
 	/// @}
 };
 
@@ -127,4 +132,3 @@ typedef TVec3<U32> UVec3;
 
 } // end namespace anki
 
-#endif

+ 18 - 14
include/anki/math/Vec4.h

@@ -3,8 +3,7 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_MATH_VEC4_H
-#define ANKI_MATH_VEC4_H
+#pragma once
 
 #include "anki/math/CommonIncludes.h"
 
@@ -38,7 +37,7 @@ struct TVec4Simd<F32>
 
 /// 4D vector. SIMD optimized
 template<typename T>
-class alignas(16) TVec4: 
+class alignas(16) TVec4:
 	public TVec<T, 4, typename TVec4Simd<T>::Type, TVec4<T>>
 {
 	/// @name Friends
@@ -55,7 +54,7 @@ class alignas(16) TVec4:
 
 public:
 	using Base = TVec<T, 4, typename TVec4Simd<T>::Type, TVec4<T>>;
-	
+
 	using Base::x;
 	using Base::y;
 	using Base::z;
@@ -65,35 +64,35 @@ public:
 	/// @name Constructors
 	/// @{
 	explicit TVec4()
-	:	Base()
+		: Base()
 	{}
 
 	TVec4(const TVec4& b)
-	:	Base(b)
+		: Base(b)
 	{}
 
 	explicit TVec4(const T x_, const T y_, const T z_, const T w_)
-	:	Base(x_, y_, z_, w_)
+		: Base(x_, y_, z_, w_)
 	{}
 
 	explicit TVec4(const T f)
-	:	Base(f)
+		: Base(f)
 	{}
 
 	explicit TVec4(const T arr[])
-	:	Base(arr)
+		: Base(arr)
 	{}
 
 	explicit TVec4(const typename Base::Simd& simd)
-	:	Base(simd)
+		: Base(simd)
 	{}
 
 	explicit TVec4(const TVec2<T>& v, const T z_, const T w_)
-	:	Base(v.x(), v.y(), z_, w_)
+		: Base(v.x(), v.y(), z_, w_)
 	{}
 
 	explicit TVec4(const TVec3<T>& v, const T w_)
-	:	Base(v.x(), v.y(), v.z(), w_)
+		: Base(v.x(), v.y(), v.z(), w_)
 	{}
 	/// @}
 
@@ -108,11 +107,17 @@ public:
 		return TVec4(Base::xyz().cross(b.xyz()), static_cast<T>(0));
 	}
 
-	TVec4 getProjection(const TVec4& toThis) const
+	TVec4 projectTo(const TVec4& toThis) const
 	{
 		ANKI_ASSERT(w() == T(0));
 		return (toThis * ((*this).dot(toThis) / (toThis.dot(toThis)))).xyz0();
 	}
+
+	TVec4 projectTo(const TVec4& rayOrigin, const TVec4& rayDir) const
+	{
+		const auto& a = *this;
+		return rayOrigin + rayDir * ((a - rayOrigin).dot(rayDir));
+	}
 	/// @{
 
 	/// @name Operators with other
@@ -212,4 +217,3 @@ typedef TVec4<U32> UVec4;
 
 #include "anki/math/Vec4.inl.h"
 
-#endif

+ 49 - 4
shaders/ImageReflections.glsl

@@ -13,27 +13,72 @@
 // Representation of a reflection probe
 struct ReflectionProbe
 {
-	vec3 position;
-	float radius;
+	// Position of the prove in view space. Radius of probe squared
+	vec4 positionRadiusSq;
+
+	// Slice in u_reflectionsTex vector.
+	vec4 cubemapSlicePad3;
 };
 
-layout(std430, row_major, SS_BINDING(IMAGE_REFLECTIONS_SET,
+layout(std140, row_major, SS_BINDING(IMAGE_REFLECTIONS_SET,
 	IMAGE_REFLECTIONS_SS_BINDING)) readonly buffer _irs0
 {
+	uvec4 u_reflectionProbeCountPad3;
 	ReflectionProbe u_reflectionProbes[];
 };
 
 layout(TEX_BINDING(IMAGE_REFLECTIONS_SET, IMAGE_REFLECTIONS_TEX_BINDING))
 	uniform samplerCubeArray u_reflectionsTex;
 
+//==============================================================================
+// Compute the cubemap texture lookup vector given the reflection vector (r)
+// the radius squared of the probe (R2) and the frag pos in sphere space (f)
+vec3 computeCubemapVec(in vec3 r, in float R2, in vec3 f)
+{
+	// Compute the collision of the r to the inner part of the sphere
+	// From now on we work on the sphere's space
+
+	// Project the center of the sphere (it's zero now since we are in sphere
+	// space) in ray "f,r"
+	vec3 p = f - r * dot(f, r);
+
+	// The collision to the sphere is point x where x = p + T * r
+	// Because of the pythagorean theorem: R^2 = dot(p, p) + dot(T * r, T * r)
+	// solving for T, T = R / |p|
+	// then x becomes x = sqrt(R^2 - dot(p, p)) * r + p;
+	float pp = dot(p, p);
+	pp = min(pp, R2);
+	float sq = sqrt(R2 - pp);
+	vec3 x = p + sq * r;
+}
+
 //==============================================================================
 vec3 readReflection(in vec3 posVSpace, in vec3 normalVSpace)
 {
+	vec3 color = vec3(0.0);
+
 	// Reflection direction
 	vec3 eye = normalize(posVSpace);
 	vec3 r = reflect(eye, normalVSpace);
 
-	// Compute the collision into the sphere
+	// Iterate probes
+	uint count = u_reflectionProbeCountPad3.x;
+	for(uint i = 0; i < count; ++i)
+	{
+		float R2 = u_reflectionProbes[i].positionRadiusSq.w;
+		vec3 c = u_reflectionProbes[i].positionRadius.xyz;
+
+		// Check if posVSpace is inside the sphere
+		vec3 f = posVSpace - c;
+		if(dot(f) < R2)
+		{
+			vec3 uv = computeCubemapVec(r, R2, f);
+			color += texture(u_reflectionsTex, vec4(uv,
+				u_reflectionProbes[i].cubemapSlicePad3.x));
+		}
+	}
+
+	return color;
 }
 
 #endif

+ 1 - 1
src/renderer/Clusterer.cpp

@@ -361,7 +361,7 @@ void Clusterer::binSphere(const Sphere& s, const Aabb& aabb,
 
 			// Do a simple ray-sphere test
 			Vec4 dir = view;
-			Vec4 proj = sphereCenterVSpace.getProjection(dir);
+			Vec4 proj = sphereCenterVSpace.projectTo(dir);
 			F32 lenSq = (sphereCenterVSpace - proj).getLengthSquared();
 			Bool inside = lenSq <= (srad * srad);