mirror of
https://github.com/overte-org/overte.git
synced 2025-08-05 19:39:43 +02:00
Merge pull request #5684 from rabedik/fxaa
Post-process anti-aliasing effect
This commit is contained in:
commit
20bd14c8db
11 changed files with 370 additions and 0 deletions
|
@ -3553,6 +3553,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect();
|
renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect();
|
||||||
|
|
||||||
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
||||||
|
renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
|
||||||
|
|
||||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||||
|
|
||||||
|
|
|
@ -317,6 +317,7 @@ Menu::Menu() {
|
||||||
0, // QML Qt::SHIFT | Qt::Key_A,
|
0, // QML Qt::SHIFT | Qt::Key_A,
|
||||||
true);
|
true);
|
||||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion);
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion);
|
||||||
|
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Antialiasing);
|
||||||
|
|
||||||
MenuWrapper* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight);
|
MenuWrapper* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight);
|
||||||
QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu);
|
QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu);
|
||||||
|
|
|
@ -132,6 +132,7 @@ namespace MenuOption {
|
||||||
const QString AddRemoveFriends = "Add/Remove Friends...";
|
const QString AddRemoveFriends = "Add/Remove Friends...";
|
||||||
const QString AddressBar = "Show Address Bar";
|
const QString AddressBar = "Show Address Bar";
|
||||||
const QString Animations = "Animations...";
|
const QString Animations = "Animations...";
|
||||||
|
const QString Antialiasing = "Antialiasing";
|
||||||
const QString Atmosphere = "Atmosphere";
|
const QString Atmosphere = "Atmosphere";
|
||||||
const QString Attachments = "Attachments...";
|
const QString Attachments = "Attachments...";
|
||||||
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
const QString AudioNoiseReduction = "Audio Noise Reduction";
|
||||||
|
|
165
libraries/render-utils/src/AntialiasingEffect.cpp
Normal file
165
libraries/render-utils/src/AntialiasingEffect.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
//
|
||||||
|
// AntialiasingEffect.cpp
|
||||||
|
// libraries/render-utils/src/
|
||||||
|
//
|
||||||
|
// Created by Raffi Bedikian on 8/30/15
|
||||||
|
// Copyright 2015 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 <glm/gtc/random.hpp>
|
||||||
|
|
||||||
|
#include <PathUtils.h>
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
#include <gpu/Context.h>
|
||||||
|
|
||||||
|
#include "gpu/StandardShaderLib.h"
|
||||||
|
#include "AntialiasingEffect.h"
|
||||||
|
#include "TextureCache.h"
|
||||||
|
#include "FramebufferCache.h"
|
||||||
|
#include "DependencyManager.h"
|
||||||
|
#include "ViewFrustum.h"
|
||||||
|
#include "GeometryCache.h"
|
||||||
|
|
||||||
|
#include "fxaa_vert.h"
|
||||||
|
#include "fxaa_frag.h"
|
||||||
|
#include "fxaa_blend_frag.h"
|
||||||
|
|
||||||
|
|
||||||
|
Antialiasing::Antialiasing() {
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
||||||
|
if (!_antialiasingPipeline) {
|
||||||
|
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(fxaa_vert)));
|
||||||
|
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fxaa_frag)));
|
||||||
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||||
|
|
||||||
|
gpu::Shader::BindingSet slotBindings;
|
||||||
|
slotBindings.insert(gpu::Shader::Binding(std::string("colorTexture"), 0));
|
||||||
|
|
||||||
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
_texcoordOffsetLoc = program->getUniforms().findLocation("texcoordOffset");
|
||||||
|
|
||||||
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
|
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||||
|
|
||||||
|
// Link the antialiasing FBO to texture
|
||||||
|
_antialiasingBuffer = gpu::FramebufferPointer(gpu::Framebuffer::create(gpu::Element::COLOR_RGBA_32,
|
||||||
|
DependencyManager::get<FramebufferCache>()->getFrameBufferSize().width(), DependencyManager::get<FramebufferCache>()->getFrameBufferSize().height()));
|
||||||
|
auto format = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
|
||||||
|
auto width = _antialiasingBuffer->getWidth();
|
||||||
|
auto height = _antialiasingBuffer->getHeight();
|
||||||
|
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||||
|
_antialiasingTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
|
||||||
|
|
||||||
|
// Good to go add the brand new pipeline
|
||||||
|
_antialiasingPipeline.reset(gpu::Pipeline::create(program, state));
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = DependencyManager::get<FramebufferCache>()->getFrameBufferSize().width();
|
||||||
|
int h = DependencyManager::get<FramebufferCache>()->getFrameBufferSize().height();
|
||||||
|
if (w != _antialiasingBuffer->getWidth() || h != _antialiasingBuffer->getHeight()) {
|
||||||
|
_antialiasingBuffer->resize(w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
return _antialiasingPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& Antialiasing::getBlendPipeline() {
|
||||||
|
if (!_blendPipeline) {
|
||||||
|
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(fxaa_vert)));
|
||||||
|
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(fxaa_blend_frag)));
|
||||||
|
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||||
|
|
||||||
|
gpu::Shader::BindingSet slotBindings;
|
||||||
|
slotBindings.insert(gpu::Shader::Binding(std::string("colorTexture"), 0));
|
||||||
|
|
||||||
|
gpu::Shader::makeProgram(*program, slotBindings);
|
||||||
|
|
||||||
|
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||||
|
|
||||||
|
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||||
|
|
||||||
|
// Good to go add the brand new pipeline
|
||||||
|
_blendPipeline.reset(gpu::Pipeline::create(program, state));
|
||||||
|
}
|
||||||
|
return _blendPipeline;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Antialiasing::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||||
|
assert(renderContext->args);
|
||||||
|
assert(renderContext->args->_viewFrustum);
|
||||||
|
|
||||||
|
if (renderContext->args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpu::Batch batch;
|
||||||
|
|
||||||
|
batch.enableStereo(false);
|
||||||
|
|
||||||
|
RenderArgs* args = renderContext->args;
|
||||||
|
|
||||||
|
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||||
|
QSize framebufferSize = framebufferCache->getFrameBufferSize();
|
||||||
|
float fbWidth = framebufferSize.width();
|
||||||
|
float fbHeight = framebufferSize.height();
|
||||||
|
float sMin = args->_viewport.x / fbWidth;
|
||||||
|
float sWidth = args->_viewport.z / fbWidth;
|
||||||
|
float tMin = args->_viewport.y / fbHeight;
|
||||||
|
float tHeight = args->_viewport.w / fbHeight;
|
||||||
|
|
||||||
|
glm::mat4 projMat;
|
||||||
|
Transform viewMat;
|
||||||
|
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||||
|
args->_viewFrustum->evalViewTransform(viewMat);
|
||||||
|
batch.setProjectionTransform(projMat);
|
||||||
|
batch.setViewTransform(viewMat);
|
||||||
|
batch.setModelTransform(Transform());
|
||||||
|
|
||||||
|
// FXAA step
|
||||||
|
getAntialiasingPipeline();
|
||||||
|
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
|
||||||
|
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
|
||||||
|
batch.setFramebuffer(_antialiasingBuffer);
|
||||||
|
batch.setPipeline(getAntialiasingPipeline());
|
||||||
|
|
||||||
|
// initialize the view-space unpacking uniforms using frustum data
|
||||||
|
float left, right, bottom, top, nearVal, farVal;
|
||||||
|
glm::vec4 nearClipPlane, farClipPlane;
|
||||||
|
|
||||||
|
args->_viewFrustum->computeOffAxisFrustum(left, right, bottom, top, nearVal, farVal, nearClipPlane, farClipPlane);
|
||||||
|
|
||||||
|
float depthScale = (farVal - nearVal) / farVal;
|
||||||
|
float nearScale = -1.0f / nearVal;
|
||||||
|
float depthTexCoordScaleS = (right - left) * nearScale / sWidth;
|
||||||
|
float depthTexCoordScaleT = (top - bottom) * nearScale / tHeight;
|
||||||
|
float depthTexCoordOffsetS = left * nearScale - sMin * depthTexCoordScaleS;
|
||||||
|
float depthTexCoordOffsetT = bottom * nearScale - tMin * depthTexCoordScaleT;
|
||||||
|
|
||||||
|
batch._glUniform2f(_texcoordOffsetLoc, 1.0 / fbWidth, 1.0 / fbHeight);
|
||||||
|
|
||||||
|
glm::vec4 color(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
glm::vec2 bottomLeft(-1.0f, -1.0f);
|
||||||
|
glm::vec2 topRight(1.0f, 1.0f);
|
||||||
|
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
|
||||||
|
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
|
// Blend step
|
||||||
|
getBlendPipeline();
|
||||||
|
batch.setResourceTexture(0, _antialiasingTexture);
|
||||||
|
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
|
||||||
|
batch.setPipeline(getBlendPipeline());
|
||||||
|
|
||||||
|
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||||
|
|
||||||
|
// Ready to render
|
||||||
|
args->_context->render((batch));
|
||||||
|
}
|
44
libraries/render-utils/src/AntialiasingEffect.h
Normal file
44
libraries/render-utils/src/AntialiasingEffect.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
//
|
||||||
|
// AntialiasingEffect.h
|
||||||
|
// libraries/render-utils/src/
|
||||||
|
//
|
||||||
|
// Created by Raffi Bedikian on 8/30/15
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef hifi_AntialiasingEffect_h
|
||||||
|
#define hifi_AntialiasingEffect_h
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
#include "render/DrawTask.h"
|
||||||
|
|
||||||
|
class Antialiasing {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Antialiasing();
|
||||||
|
|
||||||
|
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||||
|
typedef render::Job::Model<Antialiasing> JobModel;
|
||||||
|
|
||||||
|
const gpu::PipelinePointer& getAntialiasingPipeline();
|
||||||
|
const gpu::PipelinePointer& getBlendPipeline();
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Uniforms for AA
|
||||||
|
gpu::int32 _texcoordOffsetLoc;
|
||||||
|
|
||||||
|
gpu::FramebufferPointer _antialiasingBuffer;
|
||||||
|
|
||||||
|
gpu::TexturePointer _antialiasingTexture;
|
||||||
|
|
||||||
|
gpu::PipelinePointer _antialiasingPipeline;
|
||||||
|
gpu::PipelinePointer _blendPipeline;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_AntialiasingEffect_h
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#include "render/DrawStatus.h"
|
#include "render/DrawStatus.h"
|
||||||
#include "AmbientOcclusionEffect.h"
|
#include "AmbientOcclusionEffect.h"
|
||||||
|
#include "AntialiasingEffect.h"
|
||||||
|
|
||||||
#include "overlay3D_vert.h"
|
#include "overlay3D_vert.h"
|
||||||
#include "overlay3D_frag.h"
|
#include "overlay3D_frag.h"
|
||||||
|
@ -88,6 +89,11 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
_jobs.back().setEnabled(false);
|
_jobs.back().setEnabled(false);
|
||||||
_occlusionJobIndex = _jobs.size() - 1;
|
_occlusionJobIndex = _jobs.size() - 1;
|
||||||
|
|
||||||
|
_jobs.push_back(Job(new Antialiasing::JobModel("Antialiasing")));
|
||||||
|
|
||||||
|
_jobs.back().setEnabled(false);
|
||||||
|
_antialiasingJobIndex = _jobs.size() - 1;
|
||||||
|
|
||||||
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
|
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
|
||||||
FetchItems(
|
FetchItems(
|
||||||
ItemFilter::Builder::transparentShape().withoutLayered(),
|
ItemFilter::Builder::transparentShape().withoutLayered(),
|
||||||
|
@ -146,6 +152,8 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
// TODO: turn on/off AO through menu item
|
// TODO: turn on/off AO through menu item
|
||||||
setOcclusionStatus(renderContext->_occlusionStatus);
|
setOcclusionStatus(renderContext->_occlusionStatus);
|
||||||
|
|
||||||
|
setAntialiasingStatus(renderContext->_fxaaStatus);
|
||||||
|
|
||||||
renderContext->args->_context->syncCache();
|
renderContext->args->_context->syncCache();
|
||||||
|
|
||||||
for (auto job : _jobs) {
|
for (auto job : _jobs) {
|
||||||
|
|
|
@ -91,6 +91,11 @@ public:
|
||||||
void setOcclusionStatus(bool draw) { if (_occlusionJobIndex >= 0) { _jobs[_occlusionJobIndex].setEnabled(draw); } }
|
void setOcclusionStatus(bool draw) { if (_occlusionJobIndex >= 0) { _jobs[_occlusionJobIndex].setEnabled(draw); } }
|
||||||
bool doOcclusionStatus() const { if (_occlusionJobIndex >= 0) { return _jobs[_occlusionJobIndex].isEnabled(); } else { return false; } }
|
bool doOcclusionStatus() const { if (_occlusionJobIndex >= 0) { return _jobs[_occlusionJobIndex].isEnabled(); } else { return false; } }
|
||||||
|
|
||||||
|
int _antialiasingJobIndex = -1;
|
||||||
|
|
||||||
|
void setAntialiasingStatus(bool draw) { if (_antialiasingJobIndex >= 0) { _jobs[_antialiasingJobIndex].setEnabled(draw); } }
|
||||||
|
bool doAntialiasingStatus() const { if (_antialiasingJobIndex >= 0) { return _jobs[_antialiasingJobIndex].isEnabled(); } else { return false; } }
|
||||||
|
|
||||||
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
94
libraries/render-utils/src/fxaa.slf
Normal file
94
libraries/render-utils/src/fxaa.slf
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// fxaa.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Raffi Bedikian on 8/30/15
|
||||||
|
// Copyright 2015 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
|
||||||
|
//
|
||||||
|
|
||||||
|
// FXAA shader, GLSL code adapted from:
|
||||||
|
// http://horde3d.org/wiki/index.php5?title=Shading_Technique_-_FXAA
|
||||||
|
// Whitepaper describing the technique:
|
||||||
|
// http://developer.download.nvidia.com/assets/gamedev/files/sdk/11/FXAA_WhitePaper.pdf
|
||||||
|
|
||||||
|
#ifdef GL_ES
|
||||||
|
precision mediump float;
|
||||||
|
precision mediump int;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform sampler2D colorTexture;
|
||||||
|
uniform vec2 texcoordOffset;
|
||||||
|
|
||||||
|
in vec2 varTexcoord;
|
||||||
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// filter width limit for dependent "two-tap" texture samples
|
||||||
|
float FXAA_SPAN_MAX = 8.0;
|
||||||
|
|
||||||
|
// local contrast multiplier for performing AA
|
||||||
|
// higher = sharper, but setting this value too high will cause near-vertical and near-horizontal edges to fail
|
||||||
|
// see "fxaaQualityEdgeThreshold"
|
||||||
|
float FXAA_REDUCE_MUL = 1.0 / 8.0;
|
||||||
|
|
||||||
|
// luminance threshold for processing dark colors
|
||||||
|
// see "fxaaQualityEdgeThresholdMin"
|
||||||
|
float FXAA_REDUCE_MIN = 1.0 / 128.0;
|
||||||
|
|
||||||
|
// fetch raw RGB values for nearby locations
|
||||||
|
// sampling pattern is "five on a die" (each diagonal direction and the center)
|
||||||
|
// computing the coordinates for these texture reads could be moved to the vertex shader for speed if needed
|
||||||
|
vec3 rgbNW = texture2D(colorTexture, varTexcoord + (vec2(-1.0, -1.0) * texcoordOffset)).xyz;
|
||||||
|
vec3 rgbNE = texture2D(colorTexture, varTexcoord + (vec2(+1.0, -1.0) * texcoordOffset)).xyz;
|
||||||
|
vec3 rgbSW = texture2D(colorTexture, varTexcoord + (vec2(-1.0, +1.0) * texcoordOffset)).xyz;
|
||||||
|
vec3 rgbSE = texture2D(colorTexture, varTexcoord + (vec2(+1.0, +1.0) * texcoordOffset)).xyz;
|
||||||
|
vec3 rgbM = texture2D(colorTexture, varTexcoord).xyz;
|
||||||
|
|
||||||
|
// convert RGB values to luminance
|
||||||
|
vec3 luma = vec3(0.299, 0.587, 0.114);
|
||||||
|
float lumaNW = dot(rgbNW, luma);
|
||||||
|
float lumaNE = dot(rgbNE, luma);
|
||||||
|
float lumaSW = dot(rgbSW, luma);
|
||||||
|
float lumaSE = dot(rgbSE, luma);
|
||||||
|
float lumaM = dot( rgbM, luma);
|
||||||
|
|
||||||
|
// luma range of local neighborhood
|
||||||
|
float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
|
||||||
|
float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
|
||||||
|
|
||||||
|
// direction perpendicular to local luma gradient
|
||||||
|
vec2 dir;
|
||||||
|
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
||||||
|
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
||||||
|
|
||||||
|
// compute clamped direction offset for additional "two-tap" samples
|
||||||
|
// longer vector = blurry, shorter vector = sharp
|
||||||
|
float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
||||||
|
float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
|
||||||
|
dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
|
||||||
|
max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX), dir * rcpDirMin)) * texcoordOffset;
|
||||||
|
|
||||||
|
// perform additional texture sampling perpendicular to gradient
|
||||||
|
vec3 rgbA = (1.0 / 2.0) * (
|
||||||
|
texture2D(colorTexture, varTexcoord + dir * (1.0 / 3.0 - 0.5)).xyz +
|
||||||
|
texture2D(colorTexture, varTexcoord + dir * (2.0 / 3.0 - 0.5)).xyz);
|
||||||
|
vec3 rgbB = rgbA * (1.0 / 2.0) + (1.0 / 4.0) * (
|
||||||
|
texture2D(colorTexture, varTexcoord + dir * (0.0 / 3.0 - 0.5)).xyz +
|
||||||
|
texture2D(colorTexture, varTexcoord + dir * (3.0 / 3.0 - 0.5)).xyz);
|
||||||
|
float lumaB = dot(rgbB, luma);
|
||||||
|
|
||||||
|
// compare luma of new samples to the luma range of the original neighborhood
|
||||||
|
// if the new samples exceed this range, just use the first two samples instead of all four
|
||||||
|
if (lumaB < lumaMin || lumaB > lumaMax) {
|
||||||
|
outFragColor.xyz=rgbA;
|
||||||
|
} else {
|
||||||
|
outFragColor.xyz=rgbB;
|
||||||
|
}
|
||||||
|
outFragColor.a = 1.0;
|
||||||
|
}
|
26
libraries/render-utils/src/fxaa.slv
Normal file
26
libraries/render-utils/src/fxaa.slv
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// fxaa.vert
|
||||||
|
// vertex shader
|
||||||
|
//
|
||||||
|
// Created by Raffi Bedikian on 8/30/15
|
||||||
|
// Copyright 2015 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 gpu/Inputs.slh@>
|
||||||
|
|
||||||
|
<@include gpu/Transform.slh@>
|
||||||
|
|
||||||
|
<$declareStandardTransform()$>
|
||||||
|
|
||||||
|
out vec2 varTexcoord;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
varTexcoord = inTexCoord0.xy;
|
||||||
|
gl_Position = inPosition;
|
||||||
|
}
|
24
libraries/render-utils/src/fxaa_blend.slf
Normal file
24
libraries/render-utils/src/fxaa_blend.slf
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
<@include gpu/Config.slh@>
|
||||||
|
<$VERSION_HEADER$>
|
||||||
|
// Generated on <$_SCRIBE_DATE$>
|
||||||
|
//
|
||||||
|
// fxaa_blend.frag
|
||||||
|
// fragment shader
|
||||||
|
//
|
||||||
|
// Created by Raffi Bedikian on 8/30/15
|
||||||
|
// Copyright 2015 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 DeferredBufferWrite.slh@>
|
||||||
|
|
||||||
|
in vec2 varTexcoord;
|
||||||
|
out vec4 outFragColor;
|
||||||
|
|
||||||
|
uniform sampler2D colorTexture;
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
outFragColor = texture(colorTexture, varTexcoord);
|
||||||
|
}
|
|
@ -53,6 +53,7 @@ public:
|
||||||
bool _drawHitEffect = false;
|
bool _drawHitEffect = false;
|
||||||
|
|
||||||
bool _occlusionStatus = false;
|
bool _occlusionStatus = false;
|
||||||
|
bool _fxaaStatus = false;
|
||||||
|
|
||||||
RenderContext() {}
|
RenderContext() {}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue