I recently implemented MSAA in my deferred renderer, it looks good but I just got a feeling I might have done it wrong.
Here is what for example the directional light fragment shader looks like:
const float DEPTH_BIAS = 0.00005; \n \ \n \ layout(std140) uniform UnifDirLight \n \ { \n \ mat4 mVPMatrix[4]; \n \ mat4 mCamViewMatrix; \n \ vec4 mSplitDistance; \n \ vec4 mLightColor; \n \ vec4 mLightDir; \n \ vec4 mGamma; \n \ vec2 mScreenSize; \n \ int mNumSamples; \n \ } UnifDirLightPass; \n \ \n \ layout (binding = 2) uniform sampler2DMS unifPositionTexture; \n \ layout (binding = 3) uniform sampler2DMS unifNormalTexture; \n \ layout (binding = 4) uniform sampler2DMS unifDiffuseTexture; \n \ layout (binding = 6) uniform sampler2DArrayShadow unifShadowmap; \n \ \n \ out vec4 fragColor; \n \ \n \ void main() \n \ { \n \ ivec2 texcoord = ivec2(textureSize(unifDiffuseTexture) * (gl_FragCoord.xy / UnifDirLightPass.mScreenSize)); \n \ \n \ vec3 worldPos = vec3(0.0), normal = vec3(0.0), diffuse = vec3(0.0); \n \ for (int i = 0; i < UnifDirLightPass.mNumSamples; i++) \n \ { \n \ worldPos += texelFetch(unifPositionTexture, texcoord, i).rgb; \n \ normal += texelFetch(unifNormalTexture, texcoord, i).rgb; \n \ diffuse += texelFetch(unifDiffuseTexture, texcoord, i).rgb; \n \ } \n \ worldPos /= UnifDirLightPass.mNumSamples; \n \ normal /= UnifDirLightPass.mNumSamples; \n \ diffuse /= UnifDirLightPass.mNumSamples; \n \ normal = normalize(normal); \n \ \n \ vec4 camPos = UnifDirLightPass.mCamViewMatrix * vec4(worldPos, 1.0); \n \ \n \ int index = 3; \n \ if (camPos.z > UnifDirLightPass.mSplitDistance.x) \n \ index = 0; \n \ else if (camPos.z > UnifDirLightPass.mSplitDistance.y) \n \ index = 1; \n \ else if (camPos.z > UnifDirLightPass.mSplitDistance.z) \n \ index = 2; \n \ \n \ vec4 projCoords = UnifDirLightPass.mVPMatrix[index] * vec4(worldPos, 1.0); \n \ projCoords.w = projCoords.z - DEPTH_BIAS; \n \ projCoords.z = float(index); \n \ float visibilty = texture(unifShadowmap, projCoords); \n \ \n \ float angleNormal = clamp(dot(normal, UnifDirLightPass.mLightDir.xyz), 0, 1); \n \ \n \ fragColor = vec4(diffuse, 1.0) * visibilty * angleNormal * UnifDirLightPass.mLightColor; \n \ } \n"; I average the position/normals/diffuse before light and shadow calculations, but I just realised perhaps I should average the computed results instead. Which one is correct?
Right now I'm using hardware PCF for my shadows. Since I'm fetching several samples anyway for MSAA, couldn't I use that for shadow filtering aswell? Any downsides?