Correcting the Z sign

This commit is contained in:
samcake 2016-06-06 09:29:50 -07:00
parent 0ea1e7c6b5
commit 8d90570f72
5 changed files with 145 additions and 52 deletions

View file

@ -19,7 +19,7 @@ struct DeferredFrameTransform {
vec4 _depthInfo;
vec4 _stereoInfo;
mat4 _projection[2];
mat4 _invView;
mat4 _viewInverse;
};
uniform deferredFrameTransformBuffer {
@ -91,5 +91,4 @@ ivec2 getPixelPosNclipPosAndSide(in vec2 glFragCoord, out ivec2 pixelPos, out ve
<@endfunc@>
<@endif@>

View file

@ -18,6 +18,9 @@
const int SurfaceGeometryPass_FrameTransformSlot = 0;
const int SurfaceGeometryPass_ParamsSlot = 1;
const int SurfaceGeometryPass_DepthMapSlot = 0;
const int SurfaceGeometryPass_NormalMapSlot = 1;
#include "surfaceGeometry_makeLinearDepth_frag.h"
#include "surfaceGeometry_makeCurvature_frag.h"
@ -36,8 +39,10 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
auto framebufferCache = DependencyManager::get<FramebufferCache>();
auto depthBuffer = framebufferCache->getPrimaryDepthTexture();
// auto normalBuffer = framebufferCache->getDeferredNormalTexture();
// auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer();
auto normalTexture = framebufferCache->getDeferredNormalTexture();
auto pyramidFBO = framebufferCache->getDepthPyramidFramebuffer();
auto pyramidTexture = framebufferCache->getDepthPyramidTexture();
auto curvatureFBO = framebufferCache->getCurvatureFramebuffer();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
@ -47,13 +52,12 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
float tHeight = args->_viewport.w / (float)framebufferSize.height();
auto linearDepthPipeline = getLinearDepthPipeline();
auto curvaturePipeline = getCurvaturePipeline();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
// _gpuTimer.begin(batch);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
@ -64,20 +68,55 @@ void SurfaceGeometryPass::run(const render::SceneContextPointer& sceneContext, c
batch.setModelTransform(model);
batch.setUniformBuffer(SurfaceGeometryPass_FrameTransformSlot, frameTransform->getFrameTransformBuffer());
// batch.setUniformBuffer(SurfaceGeometryPass_ParamsSlot, _parametersBuffer);
// Pyramid pass
batch.setFramebuffer(curvatureFBO);
batch.setFramebuffer(pyramidFBO);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(args->getViewFrustum().getFarClip(), 0.0f, 0.0f, 0.0f));
batch.setPipeline(curvaturePipeline);
batch.setPipeline(linearDepthPipeline);
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, depthBuffer);
batch.draw(gpu::TRIANGLE_STRIP, 4);
// Pyramid pass
batch.setFramebuffer(curvatureFBO);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0));
batch.setPipeline(curvaturePipeline);
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, pyramidTexture);
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, normalTexture);
batch.draw(gpu::TRIANGLE_STRIP, 4);
batch.setResourceTexture(SurfaceGeometryPass_DepthMapSlot, nullptr);
batch.setResourceTexture(SurfaceGeometryPass_NormalMapSlot, nullptr);
});
}
const gpu::PipelinePointer& SurfaceGeometryPass::getLinearDepthPipeline() {
if (!_linearDepthPipeline) {
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
auto ps = gpu::Shader::createPixel(std::string(surfaceGeometry_makeLinearDepth_frag));
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), SurfaceGeometryPass_DepthMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
// Stencil test the curvature pass for objects pixels only, not the background
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
state->setColorWriteMask(true, false, false, false);
// Good to go add the brand new pipeline
_linearDepthPipeline = gpu::Pipeline::create(program, state);
}
return _linearDepthPipeline;
}
const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
if (!_curvaturePipeline) {
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
@ -88,6 +127,7 @@ const gpu::PipelinePointer& SurfaceGeometryPass::getCurvaturePipeline() {
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), SurfaceGeometryPass_FrameTransformSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("ambientOcclusionParamsBuffer"), SurfaceGeometryPass_ParamsSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), SurfaceGeometryPass_DepthMapSlot));
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), SurfaceGeometryPass_NormalMapSlot));
gpu::Shader::makeProgram(*program, slotBindings);

View file

@ -65,8 +65,11 @@ private:
};
gpu::BufferView _parametersBuffer;
const gpu::PipelinePointer& getLinearDepthPipeline();
const gpu::PipelinePointer& getCurvaturePipeline();
gpu::PipelinePointer _linearDepthPipeline;
gpu::PipelinePointer _curvaturePipeline;
gpu::RangeTimer _gpuTimer;

View file

@ -13,16 +13,58 @@
<$declareDeferredFrameTransform()$>
uniform sampler2D depthMap;
uniform sampler2D linearDepthMap;
float getZEye(ivec2 pixel) {
return -texelFetch(linearDepthMap, pixel, 0).x;
}
float getZEyeLinear(vec2 texcoord) {
return -texture(linearDepthMap, texcoord).x;
}
vec2 signNotZero(vec2 v) {
return vec2((v.x >= 0.0) ? +1.0 : -1.0, (v.y >= 0.0) ? +1.0 : -1.0);
}
vec3 oct_to_float32x3(in vec2 e) {
vec3 v = vec3(e.xy, 1.0 - abs(e.x) - abs(e.y));
if (v.z < 0) {
v.xy = (1.0 - abs(v.yx)) * signNotZero(v.xy);
}
return normalize(v);
}
vec2 unorm8x3_to_snorm12x2(vec3 u) {
u *= 255.0;
u.y *= (1.0 / 16.0);
vec2 s = vec2( u.x * 16.0 + floor(u.y),
fract(u.y) * (16.0 * 256.0) + u.z);
return clamp(s * (1.0 / 2047.0) - 1.0, vec2(-1.0), vec2(1.0));
}
vec3 unpackNormal(in vec3 p) {
return oct_to_float32x3(unorm8x3_to_snorm12x2(p));
}
uniform sampler2D normalMap;
vec3 getWorldNormal(vec2 texcoord) {
vec3 rawNormal = texture(normalMap, texcoord).xyz;
return unpackNormal(rawNormal);
}
vec3 getWorldNormalDiff(vec2 texcoord, vec2 delta) {
vec3 normal0 = getWorldNormal(texcoord - delta);
vec3 normal1 = getWorldNormal(texcoord + delta);
return normal1 - normal0;
}
float getEyeDepthDiff(vec2 texcoord, vec2 delta) {
vec3 normal0 = getWorldNormal(texcoord - delta);
vec3 normal1 = getWorldNormal(texcoord + delta);
return getZEyeLinear(texcoord + delta) - getZEyeLinear(texcoord - delta);
}
out vec4 outFragColor;
/*
void main(void) {
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
float Zeye = -evalZeyeFromZdb(Zdb);
outFragColor = vec4(Zeye, 0.0, 0.0, 1.0);
}
*/
void main(void) {
// Pixel being shaded
@ -32,42 +74,20 @@ void main(void) {
ivec2 framePixelPos = getPixelPosNclipPosAndSide(gl_FragCoord.xy, pixelPos, nclipPos, stereoSide);
// Fetch the z under the pixel (stereo or not)
float Zdb = texelFetch(depthMap, pixelPos, 0).x;
float Zeye = -evalZeyeFromZdb(Zdb);
float Zeye = getZEye(framePixelPos);
// The position and normal of the pixel fragment in Eye space
// The position of the pixel fragment in Eye space then in world space
vec3 eyePos = evalEyePositionFromZeye(stereoSide.x, Zeye, nclipPos);
vec3 worldPos = (frameTransform._invView * vec4(eyePos, 1.0)).xyz;
vec3 worldPos = (frameTransform._viewInverse * vec4(eyePos, 1.0)).xyz;
vec3 moduloPos = fract(worldPos);
outFragColor = vec4(moduloPos, 1.0);
/*
return;
// Choose the screen-space sample radius
// proportional to the projected area of the sphere
float ssDiskRadius = -getProjScale() * getRadius() / Cp.z;
vec2 texUV = gl_FragCoord.xy * getInvWidthHeight();
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
float Zeye = -evalZeyeFromZdb(Zdb);
ivec3 stereoInfo = getStereoSideInfo(gl_FragCoord.x, 0);
// World Pos
vec4 samplePos = evalEyePositionFromZeye(stereoInfo.x, )
// Calculate the width scale.
./ Choose the screen-space sample radius
// proportional to the projected area of the sphere
// float ssDiskRadius = -getProjScale() * getRadius() / Cp.z;
// float distanceToProjectionWindow = 1.0f / tan(0.5f * radians(fov));
float scale = getProjScaleEye() / Zeye;
float scale = -getProjScaleEye() / Zeye;
vec2 viewportScale = scale * getInvWidthHeight();
@ -75,11 +95,17 @@ void main(void) {
vec2 du = vec2( 1.0f, 0.0f ) * viewportScale.x;
vec2 dv = vec2( 0.0f, 1.0f ) * viewportScale.y;
vec4 dFdu = texture(depthMap, texUV + du.xy) - texture(depthMap, texUV - du.xy);
vec4 dFdv = texture(depthMap, texUV + dv.xy) - texture(depthMap, texUV - dv.xy);
dFdu *= step(abs(dFdu.w), 0.1f); dFdv *= step(abs(dFdv.w), 0.1f);
// Calculate ( du/dx, du/dy, du/dz ) and ( dv/dx, dv/dy, dv/dz )
outFragColor = vec4(du.x, dv.y, scale, 1.0);
vec4 dFdu = vec4(getWorldNormalDiff(nclipPos, du), getEyeDepthDiff(nclipPos, du));
vec4 dFdv = vec4(getWorldNormalDiff(nclipPos, dv), getEyeDepthDiff(nclipPos, dv));
dFdu *= step(abs(dFdu.w), 0.1f); dFdv *= step(abs(dFdv.w), 0.1f);
outFragColor = vec4(dFdu.xyz, 1.0);
/*
// Calculate ( du/dx, du/dy, du/dz ) and ( dv/dx, dv/dy, dv/dz )
float dist = 1.0f; samplePos.w = 1.0f;
vec2 centerOffset = ((input.texUV - 0.5f) * 2.0f);
vec4 px = mul( samplePos + vec4( dist, 0.0f, 0.0f, 0.0f ), matViewProj );

View file

@ -0,0 +1,25 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// Created by Sam Gateau on 6/3/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
<@include DeferredTransform.slh@>
<$declareDeferredFrameTransform()$>
uniform sampler2D depthMap;
out vec4 outFragColor;
void main(void) {
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
float Zeye = -evalZeyeFromZdb(Zdb);
outFragColor = vec4(Zeye, 0.0, 0.0, 1.0);
}