Browse Source

Some preparation for the IR refactoring

Panagiotis Christopoulos Charitos 9 years ago
parent
commit
c46c4aefa9

+ 14 - 0
include/anki/renderer/Common.h

@@ -57,6 +57,20 @@ inline void computeLinearizeDepthOptimal(F32 near, F32 far, F32& a, F32& b)
 	a = (far + near) / (2.0 * near);
 	b = (near - far) / (2.0 * near);
 }
+
+const U MS_COLOR_ATTACHMENT_COUNT = 3;
+
+static const Array<PixelFormat, MS_COLOR_ATTACHMENT_COUNT>
+	MS_COLOR_ATTACHMENT_PIXEL_FORMATS = {
+		{PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM),
+			PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM),
+			PixelFormat(ComponentFormat::R8G8B8A8, TransformFormat::UNORM)}};
+
+static const PixelFormat MS_DEPTH_ATTACHMENT_PIXEL_FORMAT(
+	ComponentFormat::D24, TransformFormat::UNORM);
+
+static const PixelFormat IS_COLOR_ATTACHMENT_PIXEL_FORMAT(
+	ComponentFormat::R11G11B10, TransformFormat::FLOAT);
 /// @}
 
 } // end namespace anki

+ 11 - 7
shaders/FsCommonFrag.glsl

@@ -14,7 +14,7 @@ layout(TEX_BINDING(1, 0)) uniform sampler2D anki_msDepthRt;
 #define LIGHT_UBO_BINDING 0
 #define LIGHT_SS_BINDING 0
 #define LIGHT_TEX_BINDING 1
-#include "shaders/LightResources.glsl"
+#include "shaders/IsFsCommon.glsl"
 
 #define anki_u_time u_lightingUniforms.rendererSizeTimePad1.z
 #define RENDERER_SIZE (u_lightingUniforms.rendererSizeTimePad1.xy * 0.5)
@@ -24,8 +24,6 @@ layout(location = 1) flat in float in_alpha;
 
 layout(location = 0) out vec4 out_color;
 
-#include "shaders/LightFunctions.glsl"
-
 //==============================================================================
 #if PASS == COLOR
 #define texture_DEFINED
@@ -179,8 +177,11 @@ vec3 computeLightColor(vec3 diffCol)
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(light.diffuseColorShadowmapId.w < 128.0)
 		{
-			shadow = computeShadowFactorOmni(
-				frag2Light, shadowmapLayerIdx, -1.0 / light.posRadius.w);
+			shadow = computeShadowFactorOmni(frag2Light,
+				shadowmapLayerIdx,
+				-1.0 / light.posRadius.w,
+				u_lightingUniforms.viewMat,
+				u_omniMapArr);
 		}
 #endif
 
@@ -213,8 +214,11 @@ vec3 computeLightColor(vec3 diffCol)
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(shadowmapLayerIdx < 128.0)
 		{
-			shadow = computeShadowFactorSpot(
-				light.texProjectionMat, fragPos, shadowmapLayerIdx, 1);
+			shadow = computeShadowFactorSpot(light.texProjectionMat,
+				fragPos,
+				shadowmapLayerIdx,
+				1,
+				u_spotMapArr);
 		}
 #endif
 

+ 1 - 1
shaders/FsCommonVert.glsl

@@ -11,7 +11,7 @@
 #define LIGHT_SS_BINDING 0
 #define LIGHT_TEX_BINDING 1
 #define LIGHT_UBO_BINDING 0
-#include "shaders/LightResources.glsl"
+#include "shaders/IsFsCommon.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 #undef LIGHT_TEX_BINDING

+ 56 - 6
shaders/Is.frag.glsl

@@ -11,7 +11,7 @@
 #define LIGHT_SS_BINDING 0
 #define LIGHT_UBO_BINDING 0
 #define LIGHT_TEX_BINDING 4
-#include "shaders/LightResources.glsl"
+#include "shaders/IsFsCommon.glsl"
 #undef LIGHT_SET
 #undef LIGHT_SS_BINDING
 #undef LIGHT_TEX_BINDING
@@ -28,8 +28,6 @@ layout(location = 2) in vec2 in_projectionParams;
 
 layout(location = 0) out vec3 out_color;
 
-#include "shaders/LightFunctions.glsl"
-
 const uint TILE_COUNT = TILE_COUNT_X * TILE_COUNT_Y;
 
 //==============================================================================
@@ -70,6 +68,54 @@ void debugIncorrectColor(inout vec3 c)
 	}
 }
 
+//==============================================================================
+void readIndirect(in uint indexOffset,
+	in uint probeCount,
+	in vec3 posVSpace,
+	in vec3 r,
+	in vec3 n,
+	in float lod,
+	out vec3 specIndirect,
+	out vec3 diffIndirect)
+{
+	specIndirect = vec3(0.0);
+	diffIndirect = vec3(0.0);
+
+	// Check proxy
+	for(uint i = 0; i < probeCount; ++i)
+	{
+		uint probeIndex = u_lightIndices[indexOffset++];
+		ReflectionProbe probe = u_reflectionProbes[probeIndex];
+
+		float R2 = probe.positionRadiusSq.w;
+		vec3 center = probe.positionRadiusSq.xyz;
+
+		// Get distance from the center of the probe
+		vec3 f = posVSpace - center;
+
+		// Cubemap UV in view space
+		vec3 uv = computeCubemapVecAccurate(
+			r, R2, f, u_lightingUniforms.invViewRotation);
+
+		// Read!
+		float cubemapIndex = probe.cubemapIndexPad3.x;
+		vec3 c = textureLod(u_reflectionsTex, vec4(uv, cubemapIndex), lod).rgb;
+
+		// Combine (lerp) with previous color
+		float d = dot(f, f);
+		float factor = d / R2;
+		factor = min(factor, 1.0);
+		specIndirect = mix(c, specIndirect, factor);
+		// Same as: specIndirect = c * (1.0 - factor) + specIndirect * factor
+
+		// Do the same for diffuse
+		uv = computeCubemapVecCheap(
+			n, R2, f, u_lightingUniforms.invViewRotation);
+		vec3 id = texture(u_irradianceTex, vec4(uv, cubemapIndex)).rgb;
+		diffIndirect = mix(id, diffIndirect, factor);
+	}
+}
+
 //==============================================================================
 void main()
 {
@@ -133,8 +179,11 @@ void main()
 		float shadowmapLayerIdx = light.diffuseColorShadowmapId.w;
 		if(light.diffuseColorShadowmapId.w < 128.0)
 		{
-			shadow = computeShadowFactorOmni(
-				frag2Light, shadowmapLayerIdx, 1.0 / sqrt(light.posRadius.w));
+			shadow = computeShadowFactorOmni(frag2Light,
+				shadowmapLayerIdx,
+				1.0 / sqrt(light.posRadius.w),
+				u_lightingUniforms.viewMat,
+				u_omniMapArr);
 
 			shadow = dither(shadow, 64.0);
 		}
@@ -163,7 +212,8 @@ void main()
 			shadow = computeShadowFactorSpot(light.texProjectionMat,
 				fragPos,
 				shadowmapLayerIdx,
-				shadowSampleCount);
+				shadowSampleCount,
+				u_spotMapArr);
 
 			shadow = dither(shadow, 64.0);
 		}

+ 1 - 1
shaders/Is.vert.glsl

@@ -6,7 +6,7 @@
 #define LIGHT_SET 0
 #define LIGHT_SS_BINDING 0
 #define LIGHT_UBO_BINDING 0
-#include "shaders/LightResources.glsl"
+#include "shaders/IsFsCommon.glsl"
 
 layout(location = 0) out vec2 out_texCoord;
 layout(location = 1) flat out int out_instanceId;

+ 18 - 3
shaders/LightResources.glsl → shaders/IsFsCommon.glsl

@@ -3,10 +3,10 @@
 // Code licensed under the BSD License.
 // http://www.anki3d.org/LICENSE
 
-#ifndef ANKI_SHADERS_LIGHT_RESOURCES_GLSL
-#define ANKI_SHADERS_LIGHT_RESOURCES_GLSL
+#ifndef ANKI_SHADERS_IS_FS_COMMON_GLSL
+#define ANKI_SHADERS_IS_FS_COMMON_GLSL
 
-#include "shaders/Common.glsl"
+#include "shaders/LightFunctions.glsl"
 
 // Common uniforms between lights
 struct LightingUniforms
@@ -98,6 +98,21 @@ layout(TEX_BINDING(
 layout(TEX_BINDING(
 	LIGHT_SET, LIGHT_TEX_BINDING + 4)) uniform sampler2D u_integrationLut;
 
+//==============================================================================
+// Get element count attached in a cluster
+void getClusterInfo(in uint clusterIdx,
+	out uint indexOffset,
+	out uint pointLightCount,
+	out uint spotLightCount,
+	out uint probeCount)
+{
+	uint cluster = u_clusters[clusterIdx];
+	indexOffset = cluster >> 16u;
+	probeCount = (cluster >> 8u) & 0xFu;
+	pointLightCount = (cluster >> 4u) & 0xFu;
+	spotLightCount = cluster & 0xFu;
+}
+
 #endif // FRAGMENT_SHADER
 
 #endif

+ 84 - 0
shaders/Light.frag.glsl

@@ -0,0 +1,84 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Packing.h"
+
+layout(location = 0) vec3 in_posViewSpace;
+
+layout(location = 0) vec3 out_color;
+
+// Point light
+struct PointLight
+{
+	vec4 posRadius; // xyz: Light pos in eye space. w: The -1/radius
+	vec4 diffuseColorPad1; // xyz: diff color
+	vec4 specularColorPad1; // xyz: spec color
+};
+
+// Spot light
+struct SpotLight
+{
+	vec4 posRadius; // xyz: Light pos in eye space. w: The -1/radius
+	vec4 diffuseColorOuterCos; // xyz: diff color, w: outer cosine of spot
+	vec4 specularColorInnerCos; // xyz: spec color, w: inner cosine of spot
+	vec4 lightDir;
+}
+
+layout(ANKI_TEX_BINDING(0, 0)) uniform sampler2D u_msRt0;
+layout(ANKI_TEX_BINDING(0, 1)) uniform sampler2D u_msRt1;
+layout(ANKI_TEX_BINDING(0, 2)) uniform sampler2D u_msRt2;
+
+layout(ANKI_UBO_BINDING(0, 1)) uniform u1_
+{
+#if defined(POINT_LIGHT)
+	PointLight u_light;
+#elif defined(SPOT_LIGHT)
+	SpotLight u_light;
+#else
+#error See file
+#endif
+};
+
+#if defined(POINT_LIGHT)
+#define u_ldiff u_light.diffuseColorPad1.xyz
+#define u_lspec u_light.specularColorPad1.xyz
+#else
+#define u_ldiff u_light.diffuseColorOuterCos.xyz
+#define u_lspec u_light.specularColorInnerCos.xyz
+#endif
+
+void main()
+{
+	// Read G-buffer
+	vec2 uv = vec2(gl_FragCoord.xy) / vec2(RENDERING_WIDTH, RENDERING_HEIGHT);
+	GbufferInfo gbuffer;
+	readGBuffer(u_msRt0, u_msRt1, u_msRt2, uv, 0.0, gbuffer);
+	float a2 = pow(roughness, 2.0);
+
+	// Calculate the light color
+	vec3 viewDir = normalize(-in_posViewSpace);
+	vec3 frag2Light = u_light.posRadius.xyz - in_posViewSpace;
+	vec3 l = normalize(frag2Light);
+	float nol = max(0.0, dot(normal, l));
+
+	vec3 specC = computeSpecularColorBrdf(
+		viewDir, l, gbuffer.normal, gbuffer.specCol, u_lspec, a2, nol);
+
+	vec3 diffC = computeDiffuseColor(gbuffer.diffuse, u_ldiff);
+
+	float att = computeAttenuationFactor(u_light.posRadius.w, frag2Light);
+	float lambert = nol;
+
+#if defined(POINT_LIGHT)
+	out_color = (specC + diffC) * (att * lambert);
+#else
+	float spot = computeSpotFactor(l,
+		u_light.diffuseColorOuterCos.w,
+		u_light.specularColorInnerCos.w,
+		u_light.lightDir.xyz);
+
+	out_color = (diffC + specC) * (att * spot * lambert);
+#endif
+}

+ 27 - 0
shaders/Light.vert.glsl

@@ -0,0 +1,27 @@
+// Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos and contributors.
+// All rights reserved.
+// Code licensed under the BSD License.
+// http://www.anki3d.org/LICENSE
+
+#include "shaders/Common.h"
+
+layout(location = 0) vec3 in_position;
+
+layout(location = 0) vec3 out_posViewSpace;
+
+out gl_PerVertex
+{
+	vec4 gl_Position;
+};
+
+layout(ANKI_UBO_BINDING(0, 0)) uniform u0_
+{
+	mat4 u_mvp;
+	mat4 u_mv;
+};
+
+void main()
+{
+	gl_Position = u_mvp * vec4(in_position, 1.0);
+	out_posViewSpace = (u_mv * vec4(in_position, 1.0)).xyz;
+};

+ 20 - 72
shaders/LightFunctions.glsl

@@ -15,21 +15,6 @@ const float OMNI_LIGHT_FRUSTUM_NEAR_PLANE = 0.1 / 4.0;
 
 const uint SHADOW_SAMPLE_COUNT = 16;
 
-//==============================================================================
-// Get element count attached in a cluster
-void getClusterInfo(in uint clusterIdx,
-	out uint indexOffset,
-	out uint pointLightCount,
-	out uint spotLightCount,
-	out uint probeCount)
-{
-	uint cluster = u_clusters[clusterIdx];
-	indexOffset = cluster >> 16u;
-	probeCount = (cluster >> 8u) & 0xFu;
-	pointLightCount = (cluster >> 4u) & 0xFu;
-	spotLightCount = cluster & 0xFu;
-}
-
 //==============================================================================
 float computeAttenuationFactor(float lightRadius, vec3 frag2Light)
 {
@@ -115,8 +100,11 @@ uint computeShadowSampleCount(const uint COUNT, float zVSpace)
 }
 
 //==============================================================================
-float computeShadowFactorSpot(
-	mat4 lightProjectionMat, vec3 fragPos, float layer, uint sampleCount)
+float computeShadowFactorSpot(mat4 lightProjectionMat,
+	vec3 fragPos,
+	float layer,
+	uint sampleCount,
+	sampler2DArrayShadow spotMapArr)
 {
 	vec4 texCoords4 = lightProjectionMat * vec4(fragPos, 1.0);
 	vec3 texCoords3 = texCoords4.xyz / texCoords4.w;
@@ -149,22 +137,26 @@ float computeShadowFactorSpot(
 		vec2 cordpart1 = texCoords3.xy + poissonDisk[i] / 512.0;
 		vec4 tcoord = vec4(cordpart1, cordpart0);
 
-		shadowFactor += texture(u_spotMapArr, tcoord);
+		shadowFactor += texture(spotMapArr, tcoord);
 	}
 
 	return shadowFactor / float(sampleCount);
 #else
 	vec4 tcoord = vec4(texCoords3.x, texCoords3.y, layer, texCoords3.z);
-	float shadowFactor = texture(u_spotMapArr, tcoord);
+	float shadowFactor = texture(spotMapArr, tcoord);
 
 	return shadowFactor;
 #endif
 }
 
 //==============================================================================
-float computeShadowFactorOmni(vec3 frag2Light, float layer, float radius)
+float computeShadowFactorOmni(in vec3 frag2Light,
+	in float layer,
+	in float radius,
+	in mat4 viewMat,
+	in samplerCubeArrayShadow omniMapArr)
 {
-	vec3 dir = (u_lightingUniforms.viewMat * vec4(-frag2Light, 1.0)).xyz;
+	vec3 dir = (viewMat * vec4(-frag2Light, 1.0)).xyz;
 	vec3 dirabs = abs(dir);
 	float dist = -max(dirabs.x, max(dirabs.y, dirabs.z));
 	dir = normalize(dir);
@@ -181,14 +173,15 @@ float computeShadowFactorOmni(vec3 frag2Light, float layer, float radius)
 	// Optimized:
 	float z = (far * (dist + near)) / (dist * (far - near));
 
-	float shadowFactor = texture(u_omniMapArr, vec4(dir, layer), z).r;
+	float shadowFactor = texture(omniMapArr, vec4(dir, layer), z).r;
 	return shadowFactor;
 }
 
 //==============================================================================
 // 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 computeCubemapVecAccurate(in vec3 r, in float R2, in vec3 f)
+vec3 computeCubemapVecAccurate(
+	in vec3 r, in float R2, in vec3 f, in mat3 invViewRotation)
 {
 	// Compute the collision of the r to the inner part of the sphere
 	// From now on we work on the sphere's space
@@ -207,62 +200,17 @@ vec3 computeCubemapVecAccurate(in vec3 r, in float R2, in vec3 f)
 	vec3 x = p + sq * r;
 
 	// Rotate UV to move it to world space
-	vec3 uv = u_lightingUniforms.invViewRotation * x;
+	vec3 uv = invViewRotation * x;
 
 	return uv;
 }
 
 //==============================================================================
 // Cheap version of computeCubemapVecAccurate
-vec3 computeCubemapVecCheap(in vec3 r, in float R2, in vec3 f)
+vec3 computeCubemapVecCheap(
+	in vec3 r, in float R2, in vec3 f, in mat3 invViewRotation)
 {
-	return u_lightingUniforms.invViewRotation * r;
-}
-
-//==============================================================================
-void readIndirect(in uint indexOffset,
-	in uint probeCount,
-	in vec3 posVSpace,
-	in vec3 r,
-	in vec3 n,
-	in float lod,
-	out vec3 specIndirect,
-	out vec3 diffIndirect)
-{
-	specIndirect = vec3(0.0);
-	diffIndirect = vec3(0.0);
-
-	// Check proxy
-	for(uint i = 0; i < probeCount; ++i)
-	{
-		uint probeIndex = u_lightIndices[indexOffset++];
-		ReflectionProbe probe = u_reflectionProbes[probeIndex];
-
-		float R2 = probe.positionRadiusSq.w;
-		vec3 center = probe.positionRadiusSq.xyz;
-
-		// Get distance from the center of the probe
-		vec3 f = posVSpace - center;
-
-		// Cubemap UV in view space
-		vec3 uv = computeCubemapVecAccurate(r, R2, f);
-
-		// Read!
-		float cubemapIndex = probe.cubemapIndexPad3.x;
-		vec3 c = textureLod(u_reflectionsTex, vec4(uv, cubemapIndex), lod).rgb;
-
-		// Combine (lerp) with previous color
-		float d = dot(f, f);
-		float factor = d / R2;
-		factor = min(factor, 1.0);
-		specIndirect = mix(c, specIndirect, factor);
-		// Same as: specIndirect = c * (1.0 - factor) + specIndirect * factor
-
-		// Do the same for diffuse
-		uv = computeCubemapVecCheap(n, R2, f);
-		vec3 id = texture(u_irradianceTex, vec4(uv, cubemapIndex)).rgb;
-		diffIndirect = mix(id, diffIndirect, factor);
-	}
+	return invViewRotation * r;
 }
 
 #endif