mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge pull request #12861 from Zvork/taapre
Bloom and Temporal Anti-Aliasing improvements
This commit is contained in:
commit
748c8cdc58
35 changed files with 341 additions and 213 deletions
|
@ -330,16 +330,20 @@ void Web3DOverlay::render(RenderArgs* args) {
|
|||
renderTransform.setScale(1.0f);
|
||||
batch.setModelTransform(renderTransform);
|
||||
|
||||
// Turn off jitter for these entities
|
||||
batch.pushProjectionJitter();
|
||||
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
if (color.a < OPAQUE_ALPHA_THRESHOLD) {
|
||||
geometryCache->bindWebBrowserProgram(batch, true);
|
||||
} else {
|
||||
geometryCache->bindWebBrowserProgram(batch);
|
||||
}
|
||||
|
||||
vec2 halfSize = vec2(size.x, size.y) / 2.0f;
|
||||
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color, _geometryId);
|
||||
batch.popProjectionJitter(); // Restore jitter
|
||||
batch.setResourceTexture(0, nullptr); // restore default white color after me
|
||||
|
||||
}
|
||||
|
||||
Transform Web3DOverlay::evalRenderTransform() {
|
||||
|
|
|
@ -249,8 +249,11 @@ void WebEntityRenderer::doRender(RenderArgs* args) {
|
|||
batch.setResourceTexture(0, _texture);
|
||||
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
|
||||
|
||||
// Turn off jitter for these entities
|
||||
batch.pushProjectionJitter();
|
||||
DependencyManager::get<GeometryCache>()->bindWebBrowserProgram(batch, fadeRatio < OPAQUE_ALPHA_THRESHOLD);
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio), _geometryId);
|
||||
batch.popProjectionJitter();
|
||||
}
|
||||
|
||||
bool WebEntityRenderer::hasWebSurface() {
|
||||
|
|
|
@ -44,8 +44,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
|||
|
||||
(&::gpu::gl::GLBackend::do_setModelTransform),
|
||||
(&::gpu::gl::GLBackend::do_setViewTransform),
|
||||
(&::gpu::gl::GLBackend::do_setProjectionTransform),
|
||||
(&::gpu::gl::GLBackend::do_setViewportTransform),
|
||||
(&::gpu::gl::GLBackend::do_setProjectionTransform),
|
||||
(&::gpu::gl::GLBackend::do_setProjectionJitter),
|
||||
(&::gpu::gl::GLBackend::do_setViewportTransform),
|
||||
(&::gpu::gl::GLBackend::do_setDepthRangeTransform),
|
||||
|
||||
(&::gpu::gl::GLBackend::do_setPipeline),
|
||||
|
@ -166,7 +167,18 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
|||
case Batch::COMMAND_drawIndexedInstanced:
|
||||
case Batch::COMMAND_multiDrawIndirect:
|
||||
case Batch::COMMAND_multiDrawIndexedIndirect:
|
||||
_transform.preUpdate(_commandIndex, _stereo);
|
||||
{
|
||||
Vec2u outputSize{ 1,1 };
|
||||
|
||||
if (_output._framebuffer) {
|
||||
outputSize.x = _output._framebuffer->getWidth();
|
||||
outputSize.y = _output._framebuffer->getHeight();
|
||||
} else if (glm::dot(_transform._projectionJitter, _transform._projectionJitter)>0.0f) {
|
||||
qCWarning(gpugllogging) << "Jittering needs to have a frame buffer to be set";
|
||||
}
|
||||
|
||||
_transform.preUpdate(_commandIndex, _stereo, outputSize);
|
||||
}
|
||||
break;
|
||||
|
||||
case Batch::COMMAND_disableContextStereo:
|
||||
|
@ -179,8 +191,10 @@ void GLBackend::renderPassTransfer(const Batch& batch) {
|
|||
|
||||
case Batch::COMMAND_setViewportTransform:
|
||||
case Batch::COMMAND_setViewTransform:
|
||||
case Batch::COMMAND_setProjectionTransform: {
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
case Batch::COMMAND_setProjectionTransform:
|
||||
case Batch::COMMAND_setProjectionJitter:
|
||||
{
|
||||
CommandCall call = _commandCalls[(*command)];
|
||||
(this->*(call))(batch, *offset);
|
||||
break;
|
||||
}
|
||||
|
@ -254,6 +268,8 @@ void GLBackend::render(const Batch& batch) {
|
|||
if (!batch.isStereoEnabled()) {
|
||||
_stereo._enable = false;
|
||||
}
|
||||
// Reset jitter
|
||||
_transform._projectionJitter = Vec2(0.0f, 0.0f);
|
||||
|
||||
{
|
||||
PROFILE_RANGE(render_gpu_gl_detail, "Transfer");
|
||||
|
|
|
@ -126,6 +126,7 @@ public:
|
|||
virtual void do_setModelTransform(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setViewTransform(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setProjectionTransform(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setProjectionJitter(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setViewportTransform(const Batch& batch, size_t paramOffset) final;
|
||||
virtual void do_setDepthRangeTransform(const Batch& batch, size_t paramOffset) final;
|
||||
|
||||
|
@ -367,6 +368,7 @@ protected:
|
|||
Mat4 _projection;
|
||||
Vec4i _viewport { 0, 0, 1, 1 };
|
||||
Vec2 _depthRange { 0.0f, 1.0f };
|
||||
Vec2 _projectionJitter{ 0.0f, 0.0f };
|
||||
bool _invalidView { false };
|
||||
bool _invalidProj { false };
|
||||
bool _invalidViewport { false };
|
||||
|
@ -379,7 +381,7 @@ protected:
|
|||
mutable List::const_iterator _camerasItr;
|
||||
mutable size_t _currentCameraOffset{ INVALID_OFFSET };
|
||||
|
||||
void preUpdate(size_t commandIndex, const StereoState& stereo);
|
||||
void preUpdate(size_t commandIndex, const StereoState& stereo, Vec2u framebufferSize);
|
||||
void update(size_t commandIndex, const StereoState& stereo) const;
|
||||
void bindCurrentCamera(int stereoSide) const;
|
||||
} _transform;
|
||||
|
|
|
@ -28,6 +28,12 @@ void GLBackend::do_setProjectionTransform(const Batch& batch, size_t paramOffset
|
|||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
void GLBackend::do_setProjectionJitter(const Batch& batch, size_t paramOffset) {
|
||||
_transform._projectionJitter.x = batch._params[paramOffset]._float;
|
||||
_transform._projectionJitter.y = batch._params[paramOffset+1]._float;
|
||||
_transform._invalidProj = true;
|
||||
}
|
||||
|
||||
void GLBackend::do_setViewportTransform(const Batch& batch, size_t paramOffset) {
|
||||
memcpy(&_transform._viewport, batch.readData(batch._params[paramOffset]._uint), sizeof(Vec4i));
|
||||
|
||||
|
@ -90,7 +96,7 @@ void GLBackend::syncTransformStateCache() {
|
|||
_transform._enabledDrawcallInfoBuffer = false;
|
||||
}
|
||||
|
||||
void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) {
|
||||
void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo, Vec2u framebufferSize) {
|
||||
// Check all the dirty flags and update the state accordingly
|
||||
if (_invalidViewport) {
|
||||
_camera._viewport = glm::vec4(_viewport);
|
||||
|
@ -117,20 +123,21 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo
|
|||
|
||||
if (_invalidView || _invalidProj || _invalidViewport) {
|
||||
size_t offset = _cameraUboSize * _cameras.size();
|
||||
Vec2 finalJitter = _projectionJitter / Vec2(framebufferSize);
|
||||
_cameraOffsets.push_back(TransformStageState::Pair(commandIndex, offset));
|
||||
|
||||
if (stereo.isStereo()) {
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
_cameras.push_back(CameraBufferElement(_camera.getEyeCamera(0, stereo, _view), _camera.getEyeCamera(1, stereo, _view)));
|
||||
_cameras.push_back(CameraBufferElement(_camera.getEyeCamera(0, stereo, _view, finalJitter), _camera.getEyeCamera(1, stereo, _view, finalJitter)));
|
||||
#else
|
||||
_cameras.push_back((_camera.getEyeCamera(0, stereo, _view)));
|
||||
_cameras.push_back((_camera.getEyeCamera(1, stereo, _view)));
|
||||
_cameras.push_back((_camera.getEyeCamera(0, stereo, _view, finalJitter)));
|
||||
_cameras.push_back((_camera.getEyeCamera(1, stereo, _view, finalJitter)));
|
||||
#endif
|
||||
} else {
|
||||
#ifdef GPU_STEREO_CAMERA_BUFFER
|
||||
_cameras.push_back(CameraBufferElement(_camera.recomputeDerived(_view)));
|
||||
_cameras.push_back(CameraBufferElement(_camera.getMonoCamera(_view, finalJitter)));
|
||||
#else
|
||||
_cameras.push_back((_camera.recomputeDerived(_view)));
|
||||
_cameras.push_back((_camera.getMonoCamera(_view, finalJitter)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,6 +265,22 @@ void Batch::setProjectionTransform(const Mat4& proj) {
|
|||
_params.emplace_back(cacheData(sizeof(Mat4), &proj));
|
||||
}
|
||||
|
||||
void Batch::setProjectionJitter(float jx, float jy) {
|
||||
_projectionJitter.x = jx;
|
||||
_projectionJitter.y = jy;
|
||||
pushProjectionJitter(jx, jy);
|
||||
}
|
||||
|
||||
void Batch::pushProjectionJitter(float jx, float jy) {
|
||||
ADD_COMMAND(setProjectionJitter);
|
||||
_params.emplace_back(jx);
|
||||
_params.emplace_back(jy);
|
||||
}
|
||||
|
||||
void Batch::popProjectionJitter() {
|
||||
pushProjectionJitter(_projectionJitter.x, _projectionJitter.y);
|
||||
}
|
||||
|
||||
void Batch::setViewportTransform(const Vec4i& viewport) {
|
||||
ADD_COMMAND(setViewportTransform);
|
||||
|
||||
|
|
|
@ -167,6 +167,10 @@ public:
|
|||
void resetViewTransform() { setViewTransform(Transform(), false); }
|
||||
void setViewTransform(const Transform& view, bool camera = true);
|
||||
void setProjectionTransform(const Mat4& proj);
|
||||
void setProjectionJitter(float jx = 0.0f, float jy = 0.0f);
|
||||
// Very simple 1 level stack management of jitter.
|
||||
void pushProjectionJitter(float jx = 0.0f, float jy = 0.0f);
|
||||
void popProjectionJitter();
|
||||
// Viewport is xy = low left corner in framebuffer, zw = width height of the viewport, expressed in pixels
|
||||
void setViewportTransform(const Vec4i& viewport);
|
||||
void setDepthRangeTransform(float nearDepth, float farDepth);
|
||||
|
@ -292,8 +296,9 @@ public:
|
|||
|
||||
COMMAND_setModelTransform,
|
||||
COMMAND_setViewTransform,
|
||||
COMMAND_setProjectionTransform,
|
||||
COMMAND_setViewportTransform,
|
||||
COMMAND_setProjectionTransform,
|
||||
COMMAND_setProjectionJitter,
|
||||
COMMAND_setViewportTransform,
|
||||
COMMAND_setDepthRangeTransform,
|
||||
|
||||
COMMAND_setPipeline,
|
||||
|
@ -496,6 +501,7 @@ public:
|
|||
|
||||
NamedBatchDataMap _namedData;
|
||||
|
||||
glm::vec2 _projectionJitter{ 0.0f, 0.0f };
|
||||
bool _enableStereo{ true };
|
||||
bool _enableSkybox { false };
|
||||
|
||||
|
|
|
@ -41,15 +41,19 @@ vec3 color_LinearToYCoCg(vec3 rgb) {
|
|||
);
|
||||
}
|
||||
|
||||
vec3 color_YCoCgToLinear(vec3 ycocg) {
|
||||
vec3 color_YCoCgToUnclampedLinear(vec3 ycocg) {
|
||||
// R = Y + Co - Cg
|
||||
// G = Y + Cg
|
||||
// B = Y - Co - Cg
|
||||
return clamp(vec3(
|
||||
return vec3(
|
||||
ycocg.x + ycocg.y - ycocg.z,
|
||||
ycocg.x + ycocg.z,
|
||||
ycocg.x - ycocg.y - ycocg.z
|
||||
), vec3(0.0), vec3(1.0));
|
||||
);
|
||||
}
|
||||
|
||||
vec3 color_YCoCgToLinear(vec3 ycocg) {
|
||||
return clamp(color_YCoCgToUnclampedLinear(ycocg), vec3(0.0), vec3(1.0));
|
||||
}
|
||||
|
||||
<@func declareColorWheel()@>
|
||||
|
|
|
@ -222,7 +222,7 @@ const Backend::TransformCamera& Backend::TransformCamera::recomputeDerived(const
|
|||
return *this;
|
||||
}
|
||||
|
||||
Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const StereoState& _stereo, const Transform& xformView) const {
|
||||
Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const StereoState& _stereo, const Transform& xformView, Vec2 normalizedJitter) const {
|
||||
TransformCamera result = *this;
|
||||
Transform offsetTransform = xformView;
|
||||
if (!_stereo._skybox) {
|
||||
|
@ -231,6 +231,9 @@ Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const S
|
|||
// FIXME: If "skybox" the ipd is set to 0 for now, let s try to propose a better solution for this in the future
|
||||
}
|
||||
result._projection = _stereo._eyeProjections[eye];
|
||||
normalizedJitter.x *= 2.0f;
|
||||
result._projection[2][0] += normalizedJitter.x;
|
||||
result._projection[2][1] += normalizedJitter.y;
|
||||
result.recomputeDerived(offsetTransform);
|
||||
|
||||
result._stereoInfo = Vec4(1.0f, (float)eye, 0.0f, 0.0f);
|
||||
|
@ -238,6 +241,14 @@ Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const S
|
|||
return result;
|
||||
}
|
||||
|
||||
Backend::TransformCamera Backend::TransformCamera::getMonoCamera(const Transform& xformView, Vec2 normalizedJitter) const {
|
||||
TransformCamera result = *this;
|
||||
result._projection[2][0] += normalizedJitter.x;
|
||||
result._projection[2][1] += normalizedJitter.y;
|
||||
result.recomputeDerived(xformView);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Counters for Buffer and Texture usage in GPU/Context
|
||||
|
||||
ContextMetricSize Backend::freeGPUMemSize;
|
||||
|
|
|
@ -64,19 +64,16 @@ public:
|
|||
virtual void recycle() const = 0;
|
||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||
|
||||
// UBO class... layout MUST match the layout in Transform.slh
|
||||
class TransformCamera {
|
||||
public:
|
||||
mutable Mat4 _view;
|
||||
mutable Mat4 _viewInverse;
|
||||
mutable Mat4 _projectionViewUntranslated;
|
||||
Mat4 _projection;
|
||||
mutable Mat4 _projectionInverse;
|
||||
Vec4 _viewport; // Public value is int but float in the shader to stay in floats for all the transform computations.
|
||||
mutable Vec4 _stereoInfo;
|
||||
// Shared header between C++ and GLSL
|
||||
#include "TransformCamera_shared.slh"
|
||||
|
||||
class TransformCamera : public _TransformCamera {
|
||||
public:
|
||||
const Backend::TransformCamera& recomputeDerived(const Transform& xformView) const;
|
||||
TransformCamera getEyeCamera(int eye, const StereoState& stereo, const Transform& xformView) const;
|
||||
// Jitter should be divided by framebuffer size
|
||||
TransformCamera getMonoCamera(const Transform& xformView, Vec2 normalizedJitter) const;
|
||||
// Jitter should be divided by framebuffer size
|
||||
TransformCamera getEyeCamera(int eye, const StereoState& stereo, const Transform& xformView, Vec2 normalizedJitter) const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -136,7 +133,6 @@ protected:
|
|||
friend class Context;
|
||||
mutable ContextStats _stats;
|
||||
StereoState _stereo;
|
||||
|
||||
};
|
||||
|
||||
class Context {
|
||||
|
|
|
@ -11,20 +11,14 @@
|
|||
<@def GPU_TRANSFORM_STATE_SLH@>
|
||||
|
||||
<@func declareStandardCameraTransform()@>
|
||||
struct TransformCamera {
|
||||
mat4 _view;
|
||||
mat4 _viewInverse;
|
||||
mat4 _projectionViewUntranslated;
|
||||
mat4 _projection;
|
||||
mat4 _projectionInverse;
|
||||
vec4 _viewport;
|
||||
vec4 _stereoInfo;
|
||||
};
|
||||
<@include gpu/TransformCamera_shared.slh@>
|
||||
|
||||
#define TransformCamera _TransformCamera
|
||||
|
||||
layout(std140) uniform transformCameraBuffer {
|
||||
#ifdef GPU_TRANSFORM_IS_STEREO
|
||||
#ifdef GPU_TRANSFORM_STEREO_CAMERA
|
||||
TransformCamera _camera[2];
|
||||
TransformCamera _camera[2];
|
||||
#else
|
||||
TransformCamera _camera;
|
||||
#endif
|
||||
|
|
26
libraries/gpu/src/gpu/TransformCamera_shared.slh
Normal file
26
libraries/gpu/src/gpu/TransformCamera_shared.slh
Normal file
|
@ -0,0 +1,26 @@
|
|||
// glsl / C++ compatible source as interface for FadeEffect
|
||||
#ifdef __cplusplus
|
||||
# define _MAT4 Mat4
|
||||
# define _VEC4 Vec4
|
||||
# define _MUTABLE mutable
|
||||
#else
|
||||
# define _MAT4 mat4
|
||||
# define _VEC4 vec4
|
||||
# define _MUTABLE
|
||||
#endif
|
||||
|
||||
struct _TransformCamera {
|
||||
_MUTABLE _MAT4 _view;
|
||||
_MUTABLE _MAT4 _viewInverse;
|
||||
_MUTABLE _MAT4 _projectionViewUntranslated;
|
||||
_MAT4 _projection;
|
||||
_MUTABLE _MAT4 _projectionInverse;
|
||||
_VEC4 _viewport; // Public value is int but float in the shader to stay in floats for all the transform computations.
|
||||
_MUTABLE _VEC4 _stereoInfo;
|
||||
};
|
||||
|
||||
// <@if 1@>
|
||||
// Trigger Scribe include
|
||||
// <@endif@> <!def that !>
|
||||
//
|
||||
|
|
@ -187,7 +187,8 @@ const int AntialiasingPass_DepthMapSlot = 3;
|
|||
const int AntialiasingPass_NextMapSlot = 4;
|
||||
|
||||
|
||||
Antialiasing::Antialiasing() {
|
||||
Antialiasing::Antialiasing(bool isSharpenEnabled) :
|
||||
_isSharpenEnabled{ isSharpenEnabled } {
|
||||
_antialiasingBuffers = std::make_shared<gpu::FramebufferSwapChain>(2U);
|
||||
}
|
||||
|
||||
|
@ -282,8 +283,11 @@ const gpu::PipelinePointer& Antialiasing::getDebugBlendPipeline() {
|
|||
}
|
||||
|
||||
void Antialiasing::configure(const Config& config) {
|
||||
_sharpen = config.sharpen;
|
||||
_params.edit().blend = config.blend;
|
||||
_sharpen = config.sharpen * 0.25f;
|
||||
if (!_isSharpenEnabled) {
|
||||
_sharpen = 0.0f;
|
||||
}
|
||||
_params.edit().blend = config.blend * config.blend;
|
||||
_params.edit().covarianceGamma = config.covarianceGamma;
|
||||
|
||||
_params.edit().setConstrainColor(config.constrainColor);
|
||||
|
@ -328,11 +332,11 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
|
|||
|
||||
if (!_antialiasingBuffers->get(0)) {
|
||||
// Link the antialiasing FBO to texture
|
||||
auto format = sourceBuffer->getRenderBuffer(0)->getTexelFormat();
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR, gpu::Sampler::WRAP_CLAMP);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& antiAliasingBuffer = _antialiasingBuffers->edit(i);
|
||||
antiAliasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("antialiasing"));
|
||||
auto format = gpu::Element::COLOR_SRGBA_32; // DependencyManager::get<FramebufferCache>()->getLightingTexture()->getTexelFormat();
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR);
|
||||
_antialiasingTextures[i] = gpu::Texture::createRenderBuffer(format, width, height, gpu::Texture::SINGLE_MIP, defaultSampler);
|
||||
antiAliasingBuffer->setRenderBuffer(0, _antialiasingTextures[i]);
|
||||
}
|
||||
|
@ -380,8 +384,6 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
|
|||
batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, nullptr);
|
||||
batch.setResourceTexture(AntialiasingPass_NextMapSlot, nullptr);
|
||||
});
|
||||
|
||||
args->popViewFrustum();
|
||||
}
|
||||
|
||||
|
||||
|
@ -495,7 +497,7 @@ void JitterSample::configure(const Config& config) {
|
|||
_scale = config.scale;
|
||||
}
|
||||
|
||||
void JitterSample::run(const render::RenderContextPointer& renderContext) {
|
||||
void JitterSample::run(const render::RenderContextPointer& renderContext, Output& jitter) {
|
||||
auto& current = _sampleSequence.currentIndex;
|
||||
if (!_freeze) {
|
||||
if (current >= 0) {
|
||||
|
@ -504,39 +506,7 @@ void JitterSample::run(const render::RenderContextPointer& renderContext) {
|
|||
current = -1;
|
||||
}
|
||||
}
|
||||
auto args = renderContext->args;
|
||||
auto viewFrustum = args->getViewFrustum();
|
||||
|
||||
auto jit = _sampleSequence.offsets[(current < 0 ? SEQUENCE_LENGTH : current)];
|
||||
auto width = (float)args->_viewport.z;
|
||||
auto height = (float)args->_viewport.w;
|
||||
|
||||
auto jx = 2.0f * jit.x / width;
|
||||
auto jy = 2.0f * jit.y / height;
|
||||
|
||||
if (!args->isStereo()) {
|
||||
auto projMat = viewFrustum.getProjection();
|
||||
|
||||
projMat[2][0] += jx;
|
||||
projMat[2][1] += jy;
|
||||
|
||||
viewFrustum.setProjection(projMat);
|
||||
viewFrustum.calculate();
|
||||
args->pushViewFrustum(viewFrustum);
|
||||
} else {
|
||||
mat4 projMats[2];
|
||||
args->_context->getStereoProjections(projMats);
|
||||
|
||||
jx *= 2.0f;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
auto& projMat = projMats[i];
|
||||
projMat[2][0] += jx;
|
||||
projMat[2][1] += jy;
|
||||
}
|
||||
|
||||
args->_context->setStereoProjections(projMats);
|
||||
}
|
||||
jitter = _sampleSequence.offsets[(current < 0 ? SEQUENCE_LENGTH : current)];
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -58,14 +58,15 @@ class JitterSample {
|
|||
public:
|
||||
|
||||
enum {
|
||||
SEQUENCE_LENGTH = 128
|
||||
SEQUENCE_LENGTH = 64
|
||||
};
|
||||
|
||||
using Config = JitterSampleConfig;
|
||||
using JobModel = render::Job::Model<JitterSample, Config>;
|
||||
using Output = glm::vec2;
|
||||
using JobModel = render::Job::ModelO<JitterSample, Output, Config>;
|
||||
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext);
|
||||
void run(const render::RenderContextPointer& renderContext, Output& jitter);
|
||||
|
||||
private:
|
||||
|
||||
|
@ -105,11 +106,11 @@ class AntialiasingConfig : public render::Job::Config {
|
|||
public:
|
||||
AntialiasingConfig() : render::Job::Config(true) {}
|
||||
|
||||
float blend{ 0.05f };
|
||||
float sharpen{ 0.15f };
|
||||
float blend{ 0.25f };
|
||||
float sharpen{ 0.05f };
|
||||
|
||||
bool constrainColor{ true };
|
||||
float covarianceGamma{ 0.9f };
|
||||
float covarianceGamma{ 0.65f };
|
||||
bool feedbackColor{ false };
|
||||
|
||||
float debugX{ 0.0f };
|
||||
|
@ -131,7 +132,7 @@ signals:
|
|||
|
||||
struct TAAParams {
|
||||
float nope{ 0.0f };
|
||||
float blend{ 0.05f };
|
||||
float blend{ 0.15f };
|
||||
float covarianceGamma{ 1.0f };
|
||||
float debugShowVelocityThreshold{ 1.0f };
|
||||
|
||||
|
@ -168,7 +169,7 @@ public:
|
|||
using Config = AntialiasingConfig;
|
||||
using JobModel = render::Job::ModelI<Antialiasing, Inputs, Config>;
|
||||
|
||||
Antialiasing();
|
||||
Antialiasing(bool isSharpenEnabled = true);
|
||||
~Antialiasing();
|
||||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
@ -189,6 +190,7 @@ private:
|
|||
TAAParamsBuffer _params;
|
||||
float _sharpen{ 0.15f };
|
||||
int _sharpenLoc{ -1 };
|
||||
bool _isSharpenEnabled{ true };
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
uniform sampler2D blurMap0;
|
||||
uniform sampler2D blurMap1;
|
||||
uniform sampler2D blurMap2;
|
||||
uniform float intensity;
|
||||
uniform vec3 intensity;
|
||||
|
||||
in vec2 varTexCoord0;
|
||||
out vec4 outFragColor;
|
||||
|
@ -23,5 +23,5 @@ void main(void) {
|
|||
vec4 blur1 = texture(blurMap1, varTexCoord0);
|
||||
vec4 blur2 = texture(blurMap2, varTexCoord0);
|
||||
|
||||
outFragColor = vec4((blur0.rgb+blur1.rgb+blur2.rgb)*intensity, 1.0f);
|
||||
outFragColor = vec4(blur0.rgb*intensity.x + blur1.rgb*intensity.y + blur2.rgb*intensity.z, 1.0f);
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
|
||||
if (!_outputBuffer || _outputBuffer->getSize() != bufferSize) {
|
||||
auto colorTexture = gpu::TexturePointer(gpu::Texture::createRenderBuffer(inputBuffer->getTexelFormat(), bufferSize.x, bufferSize.y,
|
||||
gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT)));
|
||||
gpu::Texture::SINGLE_MIP, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP)));
|
||||
|
||||
_outputBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create("BloomThreshold"));
|
||||
_outputBuffer->setRenderBuffer(0, colorTexture);
|
||||
|
@ -93,12 +93,14 @@ void BloomThreshold::run(const render::RenderContextPointer& renderContext, cons
|
|||
outputs = _outputBuffer;
|
||||
}
|
||||
|
||||
BloomApply::BloomApply() {
|
||||
BloomApply::BloomApply() : _intensities{ 1.0f, 1.0f, 1.0f } {
|
||||
|
||||
}
|
||||
|
||||
void BloomApply::configure(const Config& config) {
|
||||
_intensity = config.intensity;
|
||||
_intensities.x = config.intensity / 3.0f;
|
||||
_intensities.y = _intensities.x;
|
||||
_intensities.z = _intensities.x;
|
||||
}
|
||||
|
||||
void BloomApply::run(const render::RenderContextPointer& renderContext, const Inputs& inputs) {
|
||||
|
@ -106,10 +108,10 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
|
|||
assert(renderContext->args->hasViewFrustum());
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
static auto BLUR0_SLOT = 0;
|
||||
static auto BLUR1_SLOT = 1;
|
||||
static auto BLUR2_SLOT = 2;
|
||||
static auto INTENSITY_SLOT = 3;
|
||||
static const auto BLUR0_SLOT = 0;
|
||||
static const auto BLUR1_SLOT = 1;
|
||||
static const auto BLUR2_SLOT = 2;
|
||||
static const auto INTENSITY_SLOT = 3;
|
||||
|
||||
if (!_pipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS();
|
||||
|
@ -149,7 +151,7 @@ void BloomApply::run(const render::RenderContextPointer& renderContext, const In
|
|||
batch.setResourceTexture(BLUR0_SLOT, blur0FB->getRenderBuffer(0));
|
||||
batch.setResourceTexture(BLUR1_SLOT, blur1FB->getRenderBuffer(0));
|
||||
batch.setResourceTexture(BLUR2_SLOT, blur2FB->getRenderBuffer(0));
|
||||
batch._glUniform1f(INTENSITY_SLOT, _intensity / 3.0f);
|
||||
batch._glUniform3f(INTENSITY_SLOT, _intensities.x, _intensities.y, _intensities.z);
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
});
|
||||
}
|
||||
|
@ -306,19 +308,19 @@ float BloomConfig::getIntensity() const {
|
|||
void BloomConfig::setSize(float value) {
|
||||
std::string blurName{ "BloomBlurN" };
|
||||
auto sigma = 0.5f+value*3.5f;
|
||||
auto task = static_cast<render::Task::TaskConcept*>(_task);
|
||||
|
||||
for (auto i = 0; i < BLOOM_BLUR_LEVEL_COUNT; i++) {
|
||||
blurName.back() = '0' + i;
|
||||
auto task = static_cast<render::Task::TaskConcept*>(_task);
|
||||
auto blurJobIt = task->editJob(blurName);
|
||||
assert(blurJobIt != task->_jobs.end());
|
||||
auto& gaussianBlur = blurJobIt->edit<render::BlurGaussian>();
|
||||
auto gaussianBlurParams = gaussianBlur.getParameters();
|
||||
gaussianBlurParams->setFilterGaussianTaps(5, sigma);
|
||||
// Gaussian blur increases at each level to have a slower rolloff on the edge
|
||||
// of the response
|
||||
sigma *= 1.5f;
|
||||
gaussianBlurParams->setFilterGaussianTaps(9, sigma);
|
||||
}
|
||||
auto blurJobIt = task->getJob("BloomApply");
|
||||
assert(blurJobIt != task->_jobs.end());
|
||||
blurJobIt->getConfiguration()->setProperty("sigma", sigma);
|
||||
}
|
||||
|
||||
Bloom::Bloom() {
|
||||
|
@ -350,7 +352,7 @@ void Bloom::build(JobModel& task, const render::Varying& inputs, render::Varying
|
|||
// Mix all blur levels at quarter resolution
|
||||
const auto applyInput = BloomApply::Inputs(bloomInputBuffer, blurFB0, blurFB1, blurFB2).asVarying();
|
||||
task.addJob<BloomApply>("BloomApply", applyInput);
|
||||
// And them blend result in additive manner on top of final color buffer
|
||||
// And then blend result in additive manner on top of final color buffer
|
||||
const auto drawInput = BloomDraw::Inputs(frameBuffer, bloomInputBuffer).asVarying();
|
||||
task.addJob<BloomDraw>("BloomDraw", drawInput);
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
BloomConfig() : render::Task::Config(false) {}
|
||||
|
||||
float size{ 0.8f };
|
||||
float size{ 0.7f };
|
||||
|
||||
void setIntensity(float value);
|
||||
float getIntensity() const;
|
||||
|
@ -41,7 +41,7 @@ class BloomThresholdConfig : public render::Job::Config {
|
|||
|
||||
public:
|
||||
|
||||
float threshold{ 1.25f };
|
||||
float threshold{ 0.9f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -71,10 +71,12 @@ private:
|
|||
class BloomApplyConfig : public render::Job::Config {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float intensity MEMBER intensity NOTIFY dirty)
|
||||
Q_PROPERTY(float sigma MEMBER sigma NOTIFY dirty)
|
||||
|
||||
public:
|
||||
|
||||
float intensity{ 0.8f };
|
||||
float intensity{ 0.25f };
|
||||
float sigma{ 1.0f };
|
||||
|
||||
signals:
|
||||
void dirty();
|
||||
|
@ -94,7 +96,7 @@ public:
|
|||
private:
|
||||
|
||||
gpu::PipelinePointer _pipeline;
|
||||
float _intensity{ 1.0f };
|
||||
glm::vec3 _intensities;
|
||||
};
|
||||
|
||||
class BloomDraw {
|
||||
|
|
|
@ -18,7 +18,7 @@ DeferredFrameTransform::DeferredFrameTransform() {
|
|||
_frameTransformBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(FrameTransform), (const gpu::Byte*) &frameTransform));
|
||||
}
|
||||
|
||||
void DeferredFrameTransform::update(RenderArgs* args) {
|
||||
void DeferredFrameTransform::update(RenderArgs* args, glm::vec2 jitter) {
|
||||
|
||||
// Update the depth info with near and far (same for stereo)
|
||||
auto nearZ = args->getViewFrustum().getNearClip();
|
||||
|
@ -38,12 +38,23 @@ void DeferredFrameTransform::update(RenderArgs* args) {
|
|||
|
||||
args->getViewFrustum().evalProjectionMatrix(frameTransformBuffer.projectionMono);
|
||||
|
||||
// There may be some sort of mismatch here if the viewport size isn't the same as the frame buffer size as
|
||||
// jitter is normalized by frame buffer size in TransformCamera. But we should be safe.
|
||||
jitter.x /= args->_viewport.z;
|
||||
jitter.y /= args->_viewport.w;
|
||||
|
||||
// Running in stereo ?
|
||||
bool isStereo = args->isStereo();
|
||||
if (!isStereo) {
|
||||
frameTransformBuffer.projection[0] = frameTransformBuffer.projectionMono;
|
||||
frameTransformBuffer.projectionUnjittered[0] = frameTransformBuffer.projectionMono;
|
||||
frameTransformBuffer.invProjectionUnjittered[0] = glm::inverse(frameTransformBuffer.projectionUnjittered[0]);
|
||||
|
||||
frameTransformBuffer.stereoInfo = glm::vec4(0.0f, (float)args->_viewport.z, 0.0f, 0.0f);
|
||||
frameTransformBuffer.invpixelInfo = glm::vec4(1.0f / args->_viewport.z, 1.0f / args->_viewport.w, 0.0f, 0.0f);
|
||||
|
||||
frameTransformBuffer.projection[0] = frameTransformBuffer.projectionUnjittered[0];
|
||||
frameTransformBuffer.projection[0][2][0] += jitter.x;
|
||||
frameTransformBuffer.projection[0][2][1] += jitter.y;
|
||||
frameTransformBuffer.invProjection[0] = glm::inverse(frameTransformBuffer.projection[0]);
|
||||
} else {
|
||||
|
||||
|
@ -52,22 +63,28 @@ void DeferredFrameTransform::update(RenderArgs* args) {
|
|||
args->_context->getStereoProjections(projMats);
|
||||
args->_context->getStereoViews(eyeViews);
|
||||
|
||||
jitter.x *= 2.0f;
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
// Compose the mono Eye space to Stereo clip space Projection Matrix
|
||||
auto sideViewMat = projMats[i] * eyeViews[i];
|
||||
frameTransformBuffer.projection[i] = sideViewMat;
|
||||
frameTransformBuffer.invProjection[i] = glm::inverse(sideViewMat);
|
||||
}
|
||||
frameTransformBuffer.projectionUnjittered[i] = sideViewMat;
|
||||
frameTransformBuffer.invProjectionUnjittered[i] = glm::inverse(sideViewMat);
|
||||
|
||||
frameTransformBuffer.projection[i] = frameTransformBuffer.projectionUnjittered[i];
|
||||
frameTransformBuffer.projection[i][2][0] += jitter.x;
|
||||
frameTransformBuffer.projection[i][2][1] += jitter.y;
|
||||
frameTransformBuffer.invProjection[i] = glm::inverse(frameTransformBuffer.projection[i]);
|
||||
}
|
||||
|
||||
frameTransformBuffer.stereoInfo = glm::vec4(1.0f, (float)(args->_viewport.z >> 1), 0.0f, 1.0f);
|
||||
frameTransformBuffer.invpixelInfo = glm::vec4(1.0f / (float)(args->_viewport.z >> 1), 1.0f / args->_viewport.w, 0.0f, 0.0f);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateDeferredFrameTransform::run(const render::RenderContextPointer& renderContext, DeferredFrameTransformPointer& frameTransform) {
|
||||
void GenerateDeferredFrameTransform::run(const render::RenderContextPointer& renderContext, const Input& jitter, Output& frameTransform) {
|
||||
if (!frameTransform) {
|
||||
frameTransform = std::make_shared<DeferredFrameTransform>();
|
||||
}
|
||||
frameTransform->update(renderContext->args);
|
||||
frameTransform->update(renderContext->args, jitter);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
DeferredFrameTransform();
|
||||
|
||||
void update(RenderArgs* args);
|
||||
void update(RenderArgs* args, glm::vec2 jitter);
|
||||
|
||||
UniformBufferView getFrameTransformBuffer() const { return _frameTransformBuffer; }
|
||||
|
||||
|
@ -43,16 +43,20 @@ protected:
|
|||
glm::vec4 depthInfo;
|
||||
// Stereo info is { isStereoFrame, halfWidth }
|
||||
glm::vec4 stereoInfo{ 0.0 };
|
||||
// Mono proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
|
||||
glm::mat4 projection[2];
|
||||
// Inverse proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
|
||||
glm::mat4 invProjection[2];
|
||||
// THe mono projection for sure
|
||||
// Mono proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
|
||||
glm::mat4 projection[2];
|
||||
// Inverse proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space
|
||||
glm::mat4 invProjection[2];
|
||||
// THe mono projection for sure
|
||||
glm::mat4 projectionMono;
|
||||
// Inv View matrix from eye space (mono) to world space
|
||||
glm::mat4 invView;
|
||||
// View matrix from world space to eye space (mono)
|
||||
glm::mat4 view;
|
||||
// Mono proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space without jittering
|
||||
glm::mat4 projectionUnjittered[2];
|
||||
// Inverse proj matrix or Left and Right proj matrix going from Mono Eye space to side clip space without jittering
|
||||
glm::mat4 invProjectionUnjittered[2];
|
||||
|
||||
FrameTransform() {}
|
||||
};
|
||||
|
@ -68,11 +72,14 @@ using DeferredFrameTransformPointer = std::shared_ptr<DeferredFrameTransform>;
|
|||
|
||||
class GenerateDeferredFrameTransform {
|
||||
public:
|
||||
using JobModel = render::Job::ModelO<GenerateDeferredFrameTransform, DeferredFrameTransformPointer>;
|
||||
|
||||
using Input = glm::vec2;
|
||||
using Output = DeferredFrameTransformPointer;
|
||||
using JobModel = render::Job::ModelIO<GenerateDeferredFrameTransform, Input, Output>;
|
||||
|
||||
GenerateDeferredFrameTransform() {}
|
||||
|
||||
void run(const render::RenderContextPointer& renderContext, DeferredFrameTransformPointer& frameTransform);
|
||||
void run(const render::RenderContextPointer& renderContext, const Input& jitter, Output& frameTransform);
|
||||
|
||||
private:
|
||||
};
|
||||
|
|
|
@ -35,6 +35,8 @@ struct DeferredFrameTransform {
|
|||
mat4 _projectionMono;
|
||||
mat4 _viewInverse;
|
||||
mat4 _view;
|
||||
mat4 _projectionUnJittered[2];
|
||||
mat4 _invProjectionUnJittered[2];
|
||||
};
|
||||
|
||||
uniform deferredFrameTransformBuffer {
|
||||
|
@ -62,6 +64,12 @@ mat4 getProjection(int side) {
|
|||
mat4 getProjectionMono() {
|
||||
return frameTransform._projectionMono;
|
||||
}
|
||||
mat4 getUnjitteredProjection(int side) {
|
||||
return frameTransform._projectionUnJittered[side];
|
||||
}
|
||||
mat4 getUnjitteredInvProjection(int side) {
|
||||
return frameTransform._invProjectionUnJittered[side];
|
||||
}
|
||||
|
||||
// positive near distance of the projection
|
||||
float getProjectionNear() {
|
||||
|
@ -138,6 +146,14 @@ vec3 evalEyePositionFromZdb(int side, float Zdb, vec2 texcoord) {
|
|||
return eyePos.xyz / eyePos.w;
|
||||
}
|
||||
|
||||
vec3 evalUnjitteredEyePositionFromZdb(int side, float Zdb, vec2 texcoord) {
|
||||
// compute the view space position using the depth
|
||||
vec3 clipPos;
|
||||
clipPos.xyz = vec3(texcoord.xy, Zdb) * 2.0 - 1.0;
|
||||
vec4 eyePos = frameTransform._invProjectionUnJittered[side] * vec4(clipPos.xyz, 1.0);
|
||||
return eyePos.xyz / eyePos.w;
|
||||
}
|
||||
|
||||
vec3 evalEyePositionFromZeye(int side, float Zeye, vec2 texcoord) {
|
||||
float Zdb = evalZdbFromZeye(Zeye);
|
||||
return evalEyePositionFromZdb(side, Zdb, texcoord);
|
||||
|
|
|
@ -2207,7 +2207,7 @@ static void buildWebShader(const gpu::ShaderPointer& vertShader, const gpu::Shad
|
|||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
|
||||
PrepareStencil::testMaskDrawShape(*state);
|
||||
PrepareStencil::testMaskDrawShapeNoAA(*state);
|
||||
|
||||
pipelinePointerOut = gpu::Pipeline::create(shaderPointerOut, state);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
<@if not MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
<@def MODEL_MATERIAL_TEXTURES_SLH@>
|
||||
|
||||
|
||||
<@func declareMaterialTexMapArrayBuffer()@>
|
||||
|
||||
const int MAX_TEXCOORDS = 2;
|
||||
|
@ -48,6 +47,8 @@ TexMapArray getTexMapArray() {
|
|||
|
||||
<@func declareMaterialTextures(withAlbedo, withRoughness, withNormal, withMetallic, withEmissive, withOcclusion, withScattering)@>
|
||||
|
||||
#define TAA_TEXTURE_LOD_BIAS -1.0
|
||||
|
||||
<@include gpu/TextureTable.slh@>
|
||||
|
||||
#ifdef GPU_TEXTURE_TABLE_BINDLESS
|
||||
|
@ -66,6 +67,7 @@ TextureTable(0, matTex);
|
|||
<@if withAlbedo@>
|
||||
#define albedoMap 0
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, albedoMap, uv);
|
||||
}
|
||||
<@endif@>
|
||||
|
@ -73,6 +75,7 @@ vec4 fetchAlbedoMap(vec2 uv) {
|
|||
<@if withRoughness@>
|
||||
#define roughnessMap 4
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, roughnessMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
@ -80,6 +83,7 @@ float fetchRoughnessMap(vec2 uv) {
|
|||
<@if withNormal@>
|
||||
#define normalMap 1
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, normalMap, uv).xyz;
|
||||
}
|
||||
<@endif@>
|
||||
|
@ -87,6 +91,7 @@ vec3 fetchNormalMap(vec2 uv) {
|
|||
<@if withMetallic@>
|
||||
#define metallicMap 2
|
||||
float fetchMetallicMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, metallicMap, uv).r;
|
||||
}
|
||||
<@endif@>
|
||||
|
@ -94,6 +99,7 @@ float fetchMetallicMap(vec2 uv) {
|
|||
<@if withEmissive@>
|
||||
#define emissiveMap 3
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
// Should take into account TAA_TEXTURE_LOD_BIAS?
|
||||
return tableTexValue(matTex, emissiveMap, uv).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
@ -119,14 +125,14 @@ float fetchScatteringMap(vec2 uv) {
|
|||
<@if withAlbedo@>
|
||||
uniform sampler2D albedoMap;
|
||||
vec4 fetchAlbedoMap(vec2 uv) {
|
||||
return texture(albedoMap, uv);
|
||||
return texture(albedoMap, uv, TAA_TEXTURE_LOD_BIAS);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withRoughness@>
|
||||
uniform sampler2D roughnessMap;
|
||||
float fetchRoughnessMap(vec2 uv) {
|
||||
return (texture(roughnessMap, uv).r);
|
||||
return (texture(roughnessMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
|
@ -134,7 +140,7 @@ float fetchRoughnessMap(vec2 uv) {
|
|||
uniform sampler2D normalMap;
|
||||
vec3 fetchNormalMap(vec2 uv) {
|
||||
// unpack normal, swizzle to get into hifi tangent space with Y axis pointing out
|
||||
vec2 t = 2.0 * (texture(normalMap, uv).rg - vec2(0.5, 0.5));
|
||||
vec2 t = 2.0 * (texture(normalMap, uv, TAA_TEXTURE_LOD_BIAS).rg - vec2(0.5, 0.5));
|
||||
vec2 t2 = t*t;
|
||||
return vec3(t.x, sqrt(1.0 - t2.x - t2.y), t.y);
|
||||
}
|
||||
|
@ -143,14 +149,14 @@ vec3 fetchNormalMap(vec2 uv) {
|
|||
<@if withMetallic@>
|
||||
uniform sampler2D metallicMap;
|
||||
float fetchMetallicMap(vec2 uv) {
|
||||
return (texture(metallicMap, uv).r);
|
||||
return (texture(metallicMap, uv, TAA_TEXTURE_LOD_BIAS).r);
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
<@if withEmissive@>
|
||||
uniform sampler2D emissiveMap;
|
||||
vec3 fetchEmissiveMap(vec2 uv) {
|
||||
return texture(emissiveMap, uv).rgb;
|
||||
return texture(emissiveMap, uv, TAA_TEXTURE_LOD_BIAS).rgb;
|
||||
}
|
||||
<@endif@>
|
||||
|
||||
|
@ -164,7 +170,7 @@ float fetchOcclusionMap(vec2 uv) {
|
|||
<@if withScattering@>
|
||||
uniform sampler2D scatteringMap;
|
||||
float fetchScatteringMap(vec2 uv) {
|
||||
float scattering = texture(scatteringMap, uv).r; // boolean scattering for now
|
||||
float scattering = texture(scatteringMap, uv, TAA_TEXTURE_LOD_BIAS).r; // boolean scattering for now
|
||||
return max(((scattering - 0.1) / 0.9), 0.0);
|
||||
return texture(scatteringMap, uv).r; // boolean scattering for now
|
||||
}
|
||||
|
@ -234,8 +240,8 @@ vec3 fetchLightmapMap(vec2 uv) {
|
|||
vec3 normalizedTangent = normalize(<$interpolatedTangent$>.xyz);
|
||||
vec3 normalizedBitangent = cross(normalizedNormal, normalizedTangent);
|
||||
// attenuate the normal map divergence from the mesh normal based on distance
|
||||
// The attenuation range [20,100] meters from the eye is arbitrary for now
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(20.0, 100.0, (-<$fragPosES$>).z));
|
||||
// The attenuation range [30,100] meters from the eye is arbitrary for now
|
||||
vec3 localNormal = mix(<$fetchedNormal$>, vec3(0.0, 1.0, 0.0), smoothstep(30.0, 100.0, (-<$fragPosES$>).z));
|
||||
<$normal$> = vec3(normalizedBitangent * localNormal.x + normalizedNormal * localNormal.y + normalizedTangent * localNormal.z);
|
||||
}
|
||||
<@endfunc@>
|
||||
|
|
|
@ -46,6 +46,7 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
|
||||
const auto& inItems = inputs.get0();
|
||||
const auto& lightingModel = inputs.get1();
|
||||
const auto jitter = inputs.get2();
|
||||
|
||||
config->setNumDrawn((int)inItems.size());
|
||||
emit config->numDrawnChanged();
|
||||
|
@ -75,7 +76,8 @@ void DrawOverlay3D::run(const RenderContextPointer& renderContext, const Inputs&
|
|||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
batch.setProjectionJitter(jitter.x, jitter.y);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
// Setup lighting model for all items;
|
||||
batch.setUniformBuffer(render::ShapePipeline::Slot::LIGHTING_MODEL, lightingModel->getParametersBuffer());
|
||||
|
|
|
@ -60,7 +60,7 @@ protected:
|
|||
|
||||
class DrawOverlay3D {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2 <render::ItemBounds, LightingModelPointer>;
|
||||
using Inputs = render::VaryingSet3<render::ItemBounds, LightingModelPointer, glm::vec2>;
|
||||
|
||||
using Config = DrawOverlay3DConfig;
|
||||
using JobModel = render::Job::ModelI<DrawOverlay3D, Inputs, Config>;
|
||||
|
|
|
@ -95,10 +95,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
fadeEffect->build(task, opaques);
|
||||
|
||||
task.addJob<JitterSample>("JitterCam");
|
||||
const auto jitter = task.addJob<JitterSample>("JitterCam");
|
||||
|
||||
// Prepare deferred, generate the shared Deferred Frame Transform
|
||||
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform");
|
||||
const auto deferredFrameTransform = task.addJob<GenerateDeferredFrameTransform>("DeferredFrameTransform", jitter);
|
||||
const auto lightingModel = task.addJob<MakeLightingModel>("LightingModel");
|
||||
|
||||
|
||||
|
@ -116,12 +116,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<PrepareStencil>("PrepareStencil", primaryFramebuffer);
|
||||
|
||||
// Render opaque objects in DeferredBuffer
|
||||
const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel).asVarying();
|
||||
const auto opaqueInputs = DrawStateSortDeferred::Inputs(opaques, lightingModel, jitter).asVarying();
|
||||
task.addJob<DrawStateSortDeferred>("DrawOpaqueDeferred", opaqueInputs, shapePlumber);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("OpaqueRangeTimer", opaqueRangeTimer);
|
||||
|
||||
|
||||
// Opaque all rendered
|
||||
|
||||
// Linear Depth Pass
|
||||
|
@ -188,8 +187,37 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DebugLightClusters>("DebugLightClusters", debugLightClustersInputs);
|
||||
}
|
||||
|
||||
const auto outlineRangeTimer = task.addJob<BeginGPURangeTimer>("BeginHighlightRangeTimer", "Highlight");
|
||||
// Select items that need to be outlined
|
||||
const auto selectionBaseName = "contextOverlayHighlightList";
|
||||
const auto selectedItems = addSelectItemJobs(task, selectionBaseName, metas, opaques, transparents);
|
||||
|
||||
const auto outlineInputs = DrawHighlightTask::Inputs(items.get0(), deferredFramebuffer, lightingFramebuffer, deferredFrameTransform).asVarying();
|
||||
task.addJob<DrawHighlightTask>("DrawHighlight", outlineInputs);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("HighlightRangeTimer", outlineRangeTimer);
|
||||
|
||||
const auto overlaysInFrontRangeTimer = task.addJob<BeginGPURangeTimer>("BeginOverlaysInFrontRangeTimer", "BeginOverlaysInFrontRangeTimer");
|
||||
|
||||
// Layered Overlays
|
||||
const auto filteredOverlaysOpaque = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT);
|
||||
const auto filteredOverlaysTransparent = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT);
|
||||
const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN<FilterLayeredItems::Outputs>(0);
|
||||
const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN<FilterLayeredItems::Outputs>(0);
|
||||
|
||||
const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel, jitter).asVarying();
|
||||
const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel, jitter).asVarying();
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true);
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("OverlaysInFrontRangeTimer", overlaysInFrontRangeTimer);
|
||||
|
||||
const auto toneAndPostRangeTimer = task.addJob<BeginGPURangeTimer>("BeginToneAndPostRangeTimer", "PostToneOverlaysAntialiasing");
|
||||
|
||||
// AA job before bloom to limit flickering
|
||||
const auto antialiasingInputs = Antialiasing::Inputs(deferredFrameTransform, lightingFramebuffer, linearDepthTarget, velocityBuffer).asVarying();
|
||||
task.addJob<Antialiasing>("Antialiasing", antialiasingInputs);
|
||||
|
||||
// Add bloom
|
||||
const auto bloomInputs = Bloom::Inputs(deferredFrameTransform, lightingFramebuffer).asVarying();
|
||||
task.addJob<Bloom>("Bloom", bloomInputs);
|
||||
|
@ -198,16 +226,6 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
const auto toneMappingInputs = ToneMappingDeferred::Inputs(lightingFramebuffer, primaryFramebuffer).asVarying();
|
||||
task.addJob<ToneMappingDeferred>("ToneMapping", toneMappingInputs);
|
||||
|
||||
const auto outlineRangeTimer = task.addJob<BeginGPURangeTimer>("BeginHighlightRangeTimer", "Highlight");
|
||||
// Select items that need to be outlined
|
||||
const auto selectionBaseName = "contextOverlayHighlightList";
|
||||
const auto selectedItems = addSelectItemJobs(task, selectionBaseName, metas, opaques, transparents);
|
||||
|
||||
const auto outlineInputs = DrawHighlightTask::Inputs(items.get0(), deferredFramebuffer, primaryFramebuffer, deferredFrameTransform).asVarying();
|
||||
task.addJob<DrawHighlightTask>("DrawHighlight", outlineInputs);
|
||||
|
||||
task.addJob<EndGPURangeTimer>("HighlightRangeTimer", outlineRangeTimer);
|
||||
|
||||
{ // Debug the bounds of the rendered items, still look at the zbuffer
|
||||
task.addJob<DrawBounds>("DrawMetaBounds", metas);
|
||||
task.addJob<DrawBounds>("DrawOpaqueBounds", opaques);
|
||||
|
@ -230,26 +248,11 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
task.addJob<DrawBounds>("DrawSelectionBounds", selectedItems);
|
||||
}
|
||||
|
||||
// Layered Overlays
|
||||
const auto filteredOverlaysOpaque = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredOpaque", overlayOpaques, Item::LAYER_3D_FRONT);
|
||||
const auto filteredOverlaysTransparent = task.addJob<FilterLayeredItems>("FilterOverlaysLayeredTransparent", overlayTransparents, Item::LAYER_3D_FRONT);
|
||||
const auto overlaysInFrontOpaque = filteredOverlaysOpaque.getN<FilterLayeredItems::Outputs>(0);
|
||||
const auto overlaysInFrontTransparent = filteredOverlaysTransparent.getN<FilterLayeredItems::Outputs>(0);
|
||||
|
||||
const auto overlayInFrontOpaquesInputs = DrawOverlay3D::Inputs(overlaysInFrontOpaque, lightingModel).asVarying();
|
||||
const auto overlayInFrontTransparentsInputs = DrawOverlay3D::Inputs(overlaysInFrontTransparent, lightingModel).asVarying();
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayInFrontOpaque", overlayInFrontOpaquesInputs, true);
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayInFrontTransparent", overlayInFrontTransparentsInputs, false);
|
||||
|
||||
{ // Debug the bounds of the rendered Overlay items that are marked drawInFront, still look at the zbuffer
|
||||
task.addJob<DrawBounds>("DrawOverlayInFrontOpaqueBounds", overlaysInFrontOpaque);
|
||||
task.addJob<DrawBounds>("DrawOverlayInFrontTransparentBounds", overlaysInFrontTransparent);
|
||||
}
|
||||
|
||||
// AA job
|
||||
const auto antialiasingInputs = Antialiasing::Inputs(deferredFrameTransform, primaryFramebuffer, linearDepthTarget, velocityBuffer).asVarying();
|
||||
task.addJob<Antialiasing>("Antialiasing", antialiasingInputs);
|
||||
|
||||
// Debugging stages
|
||||
{
|
||||
// Debugging Deferred buffer job
|
||||
|
@ -285,9 +288,10 @@ void RenderDeferredTask::build(JobModel& task, const render::Varying& input, ren
|
|||
|
||||
const auto overlaysHUDOpaque = filteredOverlaysOpaque.getN<FilterLayeredItems::Outputs>(1);
|
||||
const auto overlaysHUDTransparent = filteredOverlaysTransparent.getN<FilterLayeredItems::Outputs>(1);
|
||||
const auto nullJitter = Varying(glm::vec2(0.0f, 0.0f));
|
||||
|
||||
const auto overlayHUDOpaquesInputs = DrawOverlay3D::Inputs(overlaysHUDOpaque, lightingModel).asVarying();
|
||||
const auto overlayHUDTransparentsInputs = DrawOverlay3D::Inputs(overlaysHUDTransparent, lightingModel).asVarying();
|
||||
const auto overlayHUDOpaquesInputs = DrawOverlay3D::Inputs(overlaysHUDOpaque, lightingModel, nullJitter).asVarying();
|
||||
const auto overlayHUDTransparentsInputs = DrawOverlay3D::Inputs(overlaysHUDTransparent, lightingModel, nullJitter).asVarying();
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayHUDOpaque", overlayHUDOpaquesInputs, true);
|
||||
task.addJob<DrawOverlay3D>("DrawOverlayHUDTransparent", overlayHUDTransparentsInputs, false);
|
||||
|
||||
|
@ -379,6 +383,7 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const
|
|||
|
||||
const auto& inItems = inputs.get0();
|
||||
const auto& lightingModel = inputs.get1();
|
||||
const auto jitter = inputs.get2();
|
||||
|
||||
RenderArgs* args = renderContext->args;
|
||||
|
||||
|
@ -395,6 +400,7 @@ void DrawStateSortDeferred::run(const RenderContextPointer& renderContext, const
|
|||
args->getViewFrustum().evalViewTransform(viewMat);
|
||||
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setProjectionJitter(jitter.x, jitter.y);
|
||||
batch.setViewTransform(viewMat);
|
||||
|
||||
// Setup lighting model for all items;
|
||||
|
|
|
@ -81,7 +81,7 @@ protected:
|
|||
|
||||
class DrawStateSortDeferred {
|
||||
public:
|
||||
using Inputs = render::VaryingSet2<render::ItemBounds, LightingModelPointer>;
|
||||
using Inputs = render::VaryingSet3<render::ItemBounds, LightingModelPointer, glm::vec2>;
|
||||
|
||||
using Config = DrawStateSortConfig;
|
||||
using JobModel = render::Job::ModelI<DrawStateSortDeferred, Inputs, Config>;
|
||||
|
|
|
@ -35,6 +35,9 @@ void main(void) {
|
|||
pixels[7] = texelFetch(colorTexture, ivec2(gl_FragCoord.xy)+ivec2(0,1), 0);
|
||||
pixels[8] = texelFetch(colorTexture, ivec2(gl_FragCoord.xy)+ivec2(1,1), 0);
|
||||
|
||||
sharpenedPixel = pixels[4]*7.8 - (pixels[1]+pixels[3]+pixels[5]+pixels[7]) - (pixels[0]+pixels[2]+pixels[6]+pixels[8])*0.7;
|
||||
outFragColor = mix(pixels[4], sharpenedPixel, sharpenIntensity);
|
||||
sharpenedPixel = pixels[4]*6.8 - (pixels[1]+pixels[3]+pixels[5]+pixels[7]) - (pixels[0]+pixels[2]+pixels[6]+pixels[8])*0.7;
|
||||
|
||||
vec4 minColor = max(vec4(0), pixels[4]-vec4(0.5));
|
||||
vec4 maxColor = pixels[4]+vec4(0.5);
|
||||
outFragColor = clamp(pixels[4] + sharpenedPixel * sharpenIntensity, minColor, maxColor);
|
||||
}
|
||||
|
|
|
@ -20,14 +20,15 @@ uniform vec4 Color;
|
|||
in vec3 _normalWS;
|
||||
in vec2 _texCoord0;
|
||||
|
||||
const float gamma = 2.2;
|
||||
const float smoothing = 32.0;
|
||||
#define TAA_TEXTURE_LOD_BIAS -3.0
|
||||
|
||||
const float interiorCutoff = 0.8;
|
||||
const float outlineExpansion = 0.2;
|
||||
const float taaBias = pow(2.0, TAA_TEXTURE_LOD_BIAS);
|
||||
|
||||
void main() {
|
||||
float evalSDF(vec2 texCoord) {
|
||||
// retrieve signed distance
|
||||
float sdf = texture(Font, _texCoord0).g;
|
||||
float sdf = textureLod(Font, texCoord, TAA_TEXTURE_LOD_BIAS).g;
|
||||
if (Outline) {
|
||||
if (sdf > interiorCutoff) {
|
||||
sdf = 1.0 - sdf;
|
||||
|
@ -35,12 +36,22 @@ void main() {
|
|||
sdf += outlineExpansion;
|
||||
}
|
||||
}
|
||||
// perform adaptive anti-aliasing of the edges
|
||||
// The larger we're rendering, the less anti-aliasing we need
|
||||
float s = smoothing * length(fwidth(_texCoord0));
|
||||
float w = clamp(s, 0.0, 0.5);
|
||||
float a = smoothstep(0.5 - w, 0.5 + w, sdf);
|
||||
|
||||
// Rely on TAA for anti-aliasing
|
||||
return step(0.5, sdf);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 dxTexCoord = dFdx(_texCoord0) * 0.5 * taaBias;
|
||||
vec2 dyTexCoord = dFdy(_texCoord0) * 0.5 * taaBias;
|
||||
|
||||
// Perform 4x supersampling for anisotropic filtering
|
||||
float a;
|
||||
a = evalSDF(_texCoord0);
|
||||
a += evalSDF(_texCoord0+dxTexCoord);
|
||||
a += evalSDF(_texCoord0+dyTexCoord);
|
||||
a += evalSDF(_texCoord0+dxTexCoord+dyTexCoord);
|
||||
a *= 0.25;
|
||||
|
||||
// discard if invisible
|
||||
if (a < 0.01) {
|
||||
discard;
|
||||
|
|
|
@ -76,47 +76,39 @@ vec2 taa_getRegionFXAA() {
|
|||
#define USE_YCOCG 1
|
||||
|
||||
vec4 taa_fetchColor(sampler2D map, vec2 uv) {
|
||||
vec4 c = texture(map, uv);
|
||||
// Apply rapid pseudo tonemapping as TAA is applied to a tonemapped image, using luminance as weight, as proposed in
|
||||
// https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf
|
||||
float lum = dot(vec3(0.3,0.5,0.2),c.rgb);
|
||||
c.rgb = c.rgb / (1.0+lum);
|
||||
#if USE_YCOCG
|
||||
vec4 c = texture(map, uv);
|
||||
return vec4(color_LinearToYCoCg(c.rgb), c.a);
|
||||
return vec4(color_LinearToYCoCg(c.rgb), c.a);
|
||||
#else
|
||||
return texture(map, uv);
|
||||
return c;
|
||||
#endif
|
||||
}
|
||||
|
||||
vec3 taa_resolveColor(vec3 color) {
|
||||
#if USE_YCOCG
|
||||
return color_YCoCgToLinear(color);
|
||||
#else
|
||||
return color;
|
||||
color = max(vec3(0), color_YCoCgToUnclampedLinear(color));
|
||||
#endif
|
||||
// Apply rapid inverse tonemapping, using luminance as weight, as proposed in
|
||||
// https://de45xmedrsdbp.cloudfront.net/Resources/files/TemporalAA_small-59732822.pdf
|
||||
float lum = dot(vec3(0.3,0.5,0.2),color.rgb);
|
||||
color = color / (1.0-lum);
|
||||
return color;
|
||||
}
|
||||
|
||||
vec4 taa_fetchSourceMap(vec2 uv) {
|
||||
#if USE_YCOCG
|
||||
vec4 c = texture(sourceMap, uv);
|
||||
return vec4(color_LinearToYCoCg(c.rgb), c.a);
|
||||
#else
|
||||
return texture(sourceMap, uv);
|
||||
#endif
|
||||
return taa_fetchColor(sourceMap, uv);
|
||||
}
|
||||
|
||||
vec4 taa_fetchHistoryMap(vec2 uv) {
|
||||
#if USE_YCOCG
|
||||
vec4 c = texture(historyMap, uv);
|
||||
return vec4(color_LinearToYCoCg(c.rgb), c.a);
|
||||
#else
|
||||
return texture(historyMap, uv);
|
||||
#endif
|
||||
return taa_fetchColor(historyMap, uv);
|
||||
}
|
||||
|
||||
vec4 taa_fetchNextMap(vec2 uv) {
|
||||
#if USE_YCOCG
|
||||
vec4 c = texture(nextMap, uv);
|
||||
return vec4(color_LinearToYCoCg(c.rgb), c.a);
|
||||
#else
|
||||
return texture(nextMap, uv);
|
||||
#endif
|
||||
return taa_fetchColor(nextMap, uv);
|
||||
}
|
||||
|
||||
vec2 taa_fetchVelocityMap(vec2 uv) {
|
||||
|
|
|
@ -28,11 +28,11 @@ void main(void) {
|
|||
float Zdb = texelFetch(depthMap, ivec2(gl_FragCoord.xy), 0).x;
|
||||
|
||||
// The position of the pixel fragment in Eye space then in world space
|
||||
vec3 eyePos = evalEyePositionFromZdb(stereoSide.x, Zdb, texcoordPos);
|
||||
vec3 eyePos = evalUnjitteredEyePositionFromZdb(stereoSide.x, Zdb, texcoordPos);
|
||||
vec3 worldPos = (getViewInverse() * vec4(eyePos, 1.0)).xyz;
|
||||
|
||||
vec3 prevEyePos = (getPreviousView() * vec4(worldPos, 1.0)).xyz;
|
||||
vec4 prevClipPos = (frameTransform._projection[stereoSide.x] * vec4(prevEyePos, 1.0));
|
||||
vec4 prevClipPos = (getUnjitteredProjection(stereoSide.x) * vec4(prevEyePos, 1.0));
|
||||
vec2 prevUV = 0.5 * (prevClipPos.xy / prevClipPos.w) + vec2(0.5);
|
||||
|
||||
//vec2 imageSize = getWidthHeight(0);
|
||||
|
|
|
@ -163,7 +163,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
|
|||
//if (sourceFramebuffer->hasDepthStencil()) {
|
||||
// _blurredFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
//}
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT);
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP);
|
||||
auto blurringTarget = gpu::Texture::createRenderBuffer(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), blurBufferSize.x, blurBufferSize.y, gpu::Texture::SINGLE_MIP, blurringSampler);
|
||||
_blurredFramebuffer->setRenderBuffer(0, blurringTarget);
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ bool BlurInOutResource::updateResources(const gpu::FramebufferPointer& sourceFra
|
|||
/* if (sourceFramebuffer->hasDepthStencil()) {
|
||||
_outputFramebuffer->setDepthStencilBuffer(sourceFramebuffer->getDepthStencilBuffer(), sourceFramebuffer->getDepthStencilBufferFormat());
|
||||
}*/
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT);
|
||||
auto blurringSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_LINEAR_MIP_POINT, gpu::Sampler::WRAP_CLAMP);
|
||||
auto blurringTarget = gpu::Texture::createRenderBuffer(sourceFramebuffer->getRenderBuffer(0)->getTexelFormat(), blurBufferSize.x, blurBufferSize.y, gpu::Texture::SINGLE_MIP, blurringSampler);
|
||||
_outputFramebuffer->setRenderBuffer(0, blurringTarget);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ Rectangle {
|
|||
property: "covarianceGamma"
|
||||
max: 1.5
|
||||
min: 0.5
|
||||
height: 38
|
||||
}
|
||||
Separator {}
|
||||
HifiControls.CheckBox {
|
||||
|
@ -114,6 +115,7 @@ Rectangle {
|
|||
property: "blend"
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
height: 38
|
||||
}
|
||||
|
||||
ConfigSlider {
|
||||
|
@ -162,6 +164,7 @@ Rectangle {
|
|||
property: "debugShowVelocityThreshold"
|
||||
max: 50
|
||||
min: 0.0
|
||||
height: 38
|
||||
}
|
||||
ConfigSlider {
|
||||
label: qsTr("Debug Orb Zoom")
|
||||
|
@ -170,6 +173,7 @@ Rectangle {
|
|||
property: "debugOrbZoom"
|
||||
max: 32.0
|
||||
min: 1.0
|
||||
height: 38
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,9 +93,10 @@ Item {
|
|||
integral: false
|
||||
config: root.config
|
||||
property: "intensity"
|
||||
max: 5.0
|
||||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
height:38
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Size"
|
||||
|
@ -105,6 +106,7 @@ Item {
|
|||
max: 1.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
height:38
|
||||
}
|
||||
ConfigSlider {
|
||||
label: "Threshold"
|
||||
|
@ -114,6 +116,7 @@ Item {
|
|||
max: 2.0
|
||||
min: 0.0
|
||||
width: 280
|
||||
height:38
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ var window = new OverlayWindow({
|
|||
title: 'Bloom',
|
||||
source: qml,
|
||||
width: 285,
|
||||
height: 170,
|
||||
height: 210,
|
||||
});
|
||||
window.closed.connect(function() { Script.stop(); });
|
|
@ -98,7 +98,7 @@ void TestWindow::beginFrame() {
|
|||
_preparePrimaryFramebuffer.run(_renderContext, primaryFramebuffer);
|
||||
|
||||
DeferredFrameTransformPointer frameTransform;
|
||||
_generateDeferredFrameTransform.run(_renderContext, frameTransform);
|
||||
_generateDeferredFrameTransform.run(_renderContext, glm::vec2(0.0f, 0.0f), frameTransform);
|
||||
|
||||
LightingModelPointer lightingModel;
|
||||
_generateLightingModel.run(_renderContext, lightingModel);
|
||||
|
|
Loading…
Reference in a new issue