Added AO normal to Luci

This commit is contained in:
Olivier Prat 2018-09-20 18:01:02 +02:00
parent 1c2da13309
commit cf739db3a5
7 changed files with 31 additions and 24 deletions

View file

@ -141,6 +141,10 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture(int resolution
return _normalTexture; return _normalTexture;
} }
gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() {
return _normalTexture;
}
class GaussianDistribution { class GaussianDistribution {
public: public:
@ -540,7 +544,7 @@ void AmbientOcclusionEffect::run(const render::RenderContextPointer& renderConte
batch.popProfileRange(); batch.popProfileRange();
#if SSAO_USE_QUAD_SPLIT #if SSAO_USE_QUAD_SPLIT
// Build derivative normals pass // Build face normals pass
batch.pushProfileRange("Build Normals"); batch.pushProfileRange("Build Normals");
batch.setViewportTransform(occlusionViewport); batch.setViewportTransform(occlusionViewport);
batch.setPipeline(buildNormalsPipeline); batch.setPipeline(buildNormalsPipeline);

View file

@ -33,6 +33,7 @@ public:
gpu::FramebufferPointer getNormalFramebuffer(int resolutionLevel); gpu::FramebufferPointer getNormalFramebuffer(int resolutionLevel);
gpu::TexturePointer getNormalTexture(int resolutionLevel); gpu::TexturePointer getNormalTexture(int resolutionLevel);
gpu::TexturePointer getNormalTexture();
// Update the source framebuffer size which will drive the allocation of all the other resources. // Update the source framebuffer size which will drive the allocation of all the other resources.
bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer); bool updateLinearDepth(const gpu::TexturePointer& linearDepthBuffer);

View file

@ -321,6 +321,8 @@ std::string DebugDeferredBuffer::getShaderSourceCode(Mode mode, std::string cust
return DEFAULT_AMBIENT_OCCLUSION_SHADER; return DEFAULT_AMBIENT_OCCLUSION_SHADER;
case AmbientOcclusionBlurredMode: case AmbientOcclusionBlurredMode:
return DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER; return DEFAULT_AMBIENT_OCCLUSION_BLURRED_SHADER;
case AmbientOcclusionNormalMode:
return DEFAULT_HALF_NORMAL_SHADER;
case VelocityMode: case VelocityMode:
return DEFAULT_VELOCITY_SHADER; return DEFAULT_VELOCITY_SHADER;
case CustomMode: case CustomMode:
@ -469,6 +471,8 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I
batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionTexture()); batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionTexture());
} else if (_mode == AmbientOcclusionBlurredMode) { } else if (_mode == AmbientOcclusionBlurredMode) {
batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionBlurredTexture()); batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getOcclusionBlurredTexture());
} else if (_mode == AmbientOcclusionNormalMode) {
batch.setResourceTexture(Textures::DebugTexture0, ambientOcclusionFramebuffer->getNormalTexture());
} }
} }
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f); const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);

View file

@ -88,6 +88,7 @@ protected:
ScatteringDebugMode, ScatteringDebugMode,
AmbientOcclusionMode, AmbientOcclusionMode,
AmbientOcclusionBlurredMode, AmbientOcclusionBlurredMode,
AmbientOcclusionNormalMode,
VelocityMode, VelocityMode,
CustomMode, // Needs to stay last CustomMode, // Needs to stay last

View file

@ -223,7 +223,7 @@ vec3 getNormalEyeAtPixel(ivec2 pixel, int level) {
} }
int evalMipFromRadius(float radius) { int evalMipFromRadius(float radius) {
const int LOG_MAX_OFFSET = 2; const int LOG_MAX_OFFSET = 1;
const int MAX_MIP_LEVEL = 5; const int MAX_MIP_LEVEL = 5;
return clamp(findMSB(int(radius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL); return clamp(findMSB(int(radius)) - LOG_MAX_OFFSET, 0, MAX_MIP_LEVEL);
} }
@ -231,10 +231,8 @@ int evalMipFromRadius(float radius) {
vec4 fetchTap(ivec4 side, vec2 tapSidePixelPos, float tapRadius, vec2 sideImageSize) { vec4 fetchTap(ivec4 side, vec2 tapSidePixelPos, float tapRadius, vec2 sideImageSize) {
int mipLevel = evalMipFromRadius(tapRadius * float(doFetchMips())); int mipLevel = evalMipFromRadius(tapRadius * float(doFetchMips()));
// We need to divide by 2^mipLevel to read the appropriately scaled coordinate from a MIP-map.
// Manually clamp to the texture size because texelFetch bypasses the texture unit
vec2 tapUV = (tapSidePixelPos + vec2(0.5)) / sideImageSize; vec2 tapUV = (tapSidePixelPos + vec2(0.5)) / sideImageSize;
vec2 fetchUV = mix(tapUV, vec2((tapUV.x + getStereoSide(side)) * 0.5, tapUV.y), isStereoFromInfo(side)); vec2 fetchUV = mix(tapUV, vec2((tapUV.x + getStereoSide(side)) * 0.5, tapUV.y), isStereo());
vec4 P; vec4 P;
P.xy = tapUV; P.xy = tapUV;
@ -250,21 +248,21 @@ vec3 buildPosition(ivec4 side, vec2 fragUVPos, ivec2 depthTexFragPixelPos, ivec2
return evalEyePositionFromZeye(side.x, Zeye, fragUVPos); return evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
} }
vec3 getMinDiff(vec3 centralPoint, vec3 offsetPoint0, vec3 offsetPoint1) { vec3 getMinDelta(vec3 centralPoint, vec3 offsetPointPos, vec3 offsetPointNeg) {
vec3 delta0 = offsetPoint0 - centralPoint; vec3 delta0 = offsetPointPos - centralPoint;
vec3 delta1 = centralPoint - offsetPoint1; vec3 delta1 = centralPoint - offsetPointNeg;
return dot(delta0, delta0) < dot(delta1, delta1) ? delta0 : delta1; return dot(delta0, delta0) < dot(delta1, delta1) ? delta0 : delta1;
} }
vec3 buildNormal(ivec4 side, vec2 fragUVPos, ivec2 depthTexFragPixelPos, vec3 fragPositionES, ivec2 depthTextureScale, vec2 sideImageSize) { vec3 buildNormal(ivec4 side, vec2 fragUVPos, ivec2 depthTexFragPixelPos, vec3 fragPosition, ivec2 depthTextureScale, vec2 sideImageSize) {
vec2 uvScale = vec2(1.0) / (sideImageSize * depthTextureScale); vec2 uvScale = vec2(1.0) / (sideImageSize * depthTextureScale);
vec3 fragPositionDxPos = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(1,0), uvScale); vec3 fragPositionDxPos = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(1, 0), uvScale);
vec3 fragPositionDxNeg = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(-1,0), uvScale); vec3 fragPositionDyPos = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(0, 1), uvScale);
vec3 fragPositionDyPos = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(0,1), uvScale); vec3 fragPositionDxNeg = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(-1, 0), uvScale);
vec3 fragPositionDyNeg = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(0,-1), uvScale); vec3 fragPositionDyNeg = buildPosition(side, fragUVPos, depthTexFragPixelPos, ivec2(0, -1), uvScale);
vec3 fragPositionDx = getMinDiff(fragPositionES, fragPositionDxPos, fragPositionDxNeg); vec3 fragPositionDx = getMinDelta(fragPosition, fragPositionDxPos, fragPositionDxNeg);
vec3 fragPositionDy = getMinDiff(fragPositionES, fragPositionDyPos, fragPositionDyNeg); vec3 fragPositionDy = getMinDelta(fragPosition, fragPositionDyPos, fragPositionDyNeg);
return normalize( cross(fragPositionDx, fragPositionDy) ); return normalize( cross(fragPositionDx, fragPositionDy) );
} }
@ -287,31 +285,30 @@ float evalVisibilitySSAO(in vec3 centerPosition, in vec3 centerNormal, in vec3 t
float vv = dot(v, v); float vv = dot(v, v);
float vn = dot(v, centerNormal); float vn = dot(v, centerNormal);
// Fall off function as recommended in SSAO paper // Falloff function as recommended in SSAO paper
const float epsilon = 0.01; const float epsilon = 0.01;
float f = max(getRadius2() - vv, 0.0); float f = max(getRadius2() - vv, 0.0);
return f * f * f * max((vn - getFalloffAngle()) / (epsilon + vv), 0.0); return f * f * f * max((vn - getFalloffAngle()) / (epsilon + vv), 0.0);
} }
float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNormalES) { float computeHorizonFromTap(vec3 tapPositionES, vec3 fragPositionES, vec3 fragNormalES) {
const float epsilon = 0.01; const float epsilon = 0.001;
vec3 deltaVec = tapPositionES - fragPositionES; vec3 deltaVec = tapPositionES - fragPositionES;
float distance = length(deltaVec); float distance = length(deltaVec);
float cosHorizonAngle = 0.0; float cosHorizonAngle = dot(deltaVec, fragNormalES) / (distance + epsilon);
float radiusFalloff = max(0.0, 1.0 - (distance*distance / getRadius2())); float radiusFalloff = max(0.0, 1.0 - (distance*distance / getRadius2()));
cosHorizonAngle = dot(deltaVec, fragNormalES) / (distance + epsilon);
cosHorizonAngle = max(0.0, (cosHorizonAngle - getFalloffAngle()) * getFalloffAngleScale()); cosHorizonAngle = max(0.0, (cosHorizonAngle - getFalloffAngle()) * getFalloffAngleScale());
cosHorizonAngle *= radiusFalloff; cosHorizonAngle *= radiusFalloff;
return cosHorizonAngle; return cosHorizonAngle;
} }
<@func computeHorizon()@> <@func computeHorizon()@>
vec2 tapSidePixelPos = tapPixelOffset + shadedPixelPos; vec2 tapSidePixelPos = tapPixelOffset + shadedPixelPos;
if (tapSidePixelPos.x<0 && tapSidePixelPos.y<0 && tapSidePixelPos.x>=sideImageSize.x && tapSidePixelPos.y>=sideImageSize.y) { if (tapSidePixelPos.x<0 || tapSidePixelPos.y<0 || tapSidePixelPos.x>=sideImageSize.x || tapSidePixelPos.y>=sideImageSize.y) {
// Early exit because we've hit the borders of the frame
break; break;
} }
vec4 tapUVZ_mip = fetchTap(side, tapSidePixelPos, radius, sideImageSize); vec4 tapUVZ_mip = fetchTap(side, tapSidePixelPos, radius, sideImageSize);
@ -426,7 +423,7 @@ float fetchOcclusion(vec2 coords) {
return raw.x; return raw.x;
} }
const float BLUR_EDGE_DISTANCE_SCALE = 300.0; const float BLUR_EDGE_DISTANCE_SCALE = 1000.0;
vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) { vec2 evalTapWeightedValue(ivec3 side, int r, ivec2 destPixelCoord, vec2 scaledTexCoord, vec2 fullTexCoord, float fragDepth) {
ivec2 tapOffset = <$axis$> * r; ivec2 tapOffset = <$axis$> * r;

View file

@ -40,7 +40,6 @@ void main(void) {
// The position and normal of the pixel fragment in Eye space // The position and normal of the pixel fragment in Eye space
vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos); vec3 fragPositionES = evalEyePositionFromZeye(side.x, Zeye, fragUVPos);
vec3 fragNormalES = buildNormal(side, fragUVPos, depthTexFragPixelPos, fragPositionES, depthTextureScale, sideImageSize); vec3 fragNormalES = buildNormal(side, fragUVPos, depthTexFragPixelPos, fragPositionES, depthTextureScale, sideImageSize);
vec3 absFragNormalES = abs(fragNormalES);
outFragColor = vec4(vec3(fragNormalES)*0.5 + vec3(0.5), 1.0); outFragColor = vec4(vec3(fragNormalES)*0.5 + vec3(0.5), 1.0);
} }

View file

@ -202,6 +202,7 @@ Rectangle {
ListElement { text: "Debug Scattering"; color: "White" } ListElement { text: "Debug Scattering"; color: "White" }
ListElement { text: "Ambient Occlusion"; color: "White" } ListElement { text: "Ambient Occlusion"; color: "White" }
ListElement { text: "Ambient Occlusion Blurred"; color: "White" } ListElement { text: "Ambient Occlusion Blurred"; color: "White" }
ListElement { text: "Ambient Occlusion Normal"; color: "White" }
ListElement { text: "Velocity"; color: "White" } ListElement { text: "Velocity"; color: "White" }
ListElement { text: "Custom"; color: "White" } ListElement { text: "Custom"; color: "White" }
} }