mirror of
https://github.com/lubosz/overte.git
synced 2025-04-14 14:46:55 +02:00
Merge pull request #5376 from venkatn93/avatar
New ambient occlusion effect in render pipeline
This commit is contained in:
commit
43eec08514
15 changed files with 626 additions and 3 deletions
|
@ -3265,6 +3265,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
|
||||
renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
|
||||
|
||||
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
||||
|
||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||
|
||||
renderContext.args = renderArgs;
|
||||
|
|
|
@ -330,7 +330,7 @@ Menu::Menu() {
|
|||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::Atmosphere,
|
||||
0, // QML Qt::SHIFT | Qt::Key_A,
|
||||
true);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::AmbientOcclusion);
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::DebugAmbientOcclusion);
|
||||
|
||||
MenuWrapper* ambientLightMenu = renderOptionsMenu->addMenu(MenuOption::RenderAmbientLight);
|
||||
QActionGroup* ambientLightGroup = new QActionGroup(ambientLightMenu);
|
||||
|
|
|
@ -134,7 +134,6 @@ namespace MenuOption {
|
|||
const QString AddressBar = "Show Address Bar";
|
||||
const QString AlignForearmsWithWrists = "Align Forearms with Wrists";
|
||||
const QString AlternateIK = "Alternate IK";
|
||||
const QString AmbientOcclusion = "Ambient Occlusion";
|
||||
const QString Animations = "Animations...";
|
||||
const QString Atmosphere = "Atmosphere";
|
||||
const QString Attachments = "Attachments...";
|
||||
|
@ -165,6 +164,7 @@ namespace MenuOption {
|
|||
const QString ControlWithSpeech = "Control With Speech";
|
||||
const QString CopyAddress = "Copy Address to Clipboard";
|
||||
const QString CopyPath = "Copy Path to Clipboard";
|
||||
const QString DebugAmbientOcclusion = "Debug Ambient Occlusion";
|
||||
const QString DecreaseAvatarSize = "Decrease Avatar Size";
|
||||
const QString DeleteBookmark = "Delete Bookmark...";
|
||||
const QString DisableActivityLogger = "Disable Activity Logger";
|
||||
|
|
255
libraries/render-utils/src/AmbientOcclusionEffect.cpp
Normal file
255
libraries/render-utils/src/AmbientOcclusionEffect.cpp
Normal file
|
@ -0,0 +1,255 @@
|
|||
//
|
||||
// AmbientOcclusionEffect.cpp
|
||||
// libraries/render-utils/src/
|
||||
//
|
||||
// Created by Niraj Venkat on 7/15/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 this before QOpenGLFramebufferObject, which includes an earlier version of OpenGL
|
||||
#include <gpu/GPUConfig.h>
|
||||
|
||||
#include <gpu/GLBackend.h>
|
||||
|
||||
#include <glm/gtc/random.hpp>
|
||||
|
||||
#include <PathUtils.h>
|
||||
#include <SharedUtil.h>
|
||||
|
||||
#include "gpu/StandardShaderLib.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
#include "TextureCache.h"
|
||||
#include "FramebufferCache.h"
|
||||
#include "DependencyManager.h"
|
||||
#include "ViewFrustum.h"
|
||||
#include "GeometryCache.h"
|
||||
|
||||
#include "ambient_occlusion_vert.h"
|
||||
#include "ambient_occlusion_frag.h"
|
||||
#include "gaussian_blur_vertical_vert.h"
|
||||
#include "gaussian_blur_horizontal_vert.h"
|
||||
#include "gaussian_blur_frag.h"
|
||||
#include "occlusion_blend_frag.h"
|
||||
|
||||
|
||||
AmbientOcclusion::AmbientOcclusion() {
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusion::getOcclusionPipeline() {
|
||||
if (!_occlusionPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(ambient_occlusion_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(ambient_occlusion_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthTexture"), 0));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalTexture"), 1));
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
_gScaleLoc = program->getUniforms().findLocation("g_scale");
|
||||
_gBiasLoc = program->getUniforms().findLocation("g_bias");
|
||||
_gSampleRadiusLoc = program->getUniforms().findLocation("g_sample_rad");
|
||||
_gIntensityLoc = program->getUniforms().findLocation("g_intensity");
|
||||
_bufferWidthLoc = program->getUniforms().findLocation("bufferWidth");
|
||||
_bufferHeightLoc = program->getUniforms().findLocation("bufferHeight");
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(false,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
|
||||
|
||||
// Link the occlusion FBO to texture
|
||||
_occlusionBuffer = 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 = _occlusionBuffer->getWidth();
|
||||
auto height = _occlusionBuffer->getHeight();
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
_occlusionTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_occlusionPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
return _occlusionPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusion::getVBlurPipeline() {
|
||||
if (!_vBlurPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(gaussian_blur_vertical_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(gaussian_blur_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(false,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
|
||||
|
||||
// Link the horizontal blur FBO to texture
|
||||
_vBlurBuffer = 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 = _vBlurBuffer->getWidth();
|
||||
auto height = _vBlurBuffer->getHeight();
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
_vBlurTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_vBlurPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
return _vBlurPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusion::getHBlurPipeline() {
|
||||
if (!_hBlurPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(gaussian_blur_horizontal_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(gaussian_blur_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(false,
|
||||
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA,
|
||||
gpu::State::DEST_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ZERO);
|
||||
|
||||
// Link the horizontal blur FBO to texture
|
||||
_hBlurBuffer = 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 = _hBlurBuffer->getWidth();
|
||||
auto height = _hBlurBuffer->getHeight();
|
||||
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
|
||||
_hBlurTexture = gpu::TexturePointer(gpu::Texture::create2D(format, width, height, defaultSampler));
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_hBlurPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
return _hBlurPipeline;
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& AmbientOcclusion::getBlendPipeline() {
|
||||
if (!_blendPipeline) {
|
||||
auto vs = gpu::ShaderPointer(gpu::Shader::createVertex(std::string(ambient_occlusion_vert)));
|
||||
auto ps = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(occlusion_blend_frag)));
|
||||
gpu::ShaderPointer program = gpu::ShaderPointer(gpu::Shader::createProgram(vs, ps));
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("blurredOcclusionTexture"), 0));
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
state->setDepthTest(false, false, gpu::LESS_EQUAL);
|
||||
|
||||
// Blend on transparent
|
||||
state->setBlendFunction(true,
|
||||
gpu::State::SRC_COLOR, gpu::State::BLEND_OP_ADD, gpu::State::DEST_COLOR);
|
||||
|
||||
// Good to go add the brand new pipeline
|
||||
_blendPipeline.reset(gpu::Pipeline::create(program, state));
|
||||
}
|
||||
return _blendPipeline;
|
||||
}
|
||||
|
||||
void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
|
||||
assert(renderContext->args);
|
||||
assert(renderContext->args->_viewFrustum);
|
||||
RenderArgs* args = renderContext->args;
|
||||
auto& scene = sceneContext->_scene;
|
||||
|
||||
gpu::Batch batch;
|
||||
|
||||
glm::mat4 projMat;
|
||||
Transform viewMat;
|
||||
args->_viewFrustum->evalProjectionMatrix(projMat);
|
||||
args->_viewFrustum->evalViewTransform(viewMat);
|
||||
batch.setProjectionTransform(projMat);
|
||||
batch.setViewTransform(viewMat);
|
||||
batch.setModelTransform(Transform());
|
||||
|
||||
// Occlusion step
|
||||
getOcclusionPipeline();
|
||||
batch.setResourceTexture(0, DependencyManager::get<FramebufferCache>()->getPrimaryDepthTexture());
|
||||
batch.setResourceTexture(1, DependencyManager::get<FramebufferCache>()->getPrimaryNormalTexture());
|
||||
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
|
||||
batch.setFramebuffer(_occlusionBuffer);
|
||||
|
||||
// Occlusion uniforms
|
||||
g_scale = 1.0f;
|
||||
g_bias = 1.0f;
|
||||
g_sample_rad = 1.0f;
|
||||
g_intensity = 1.0f;
|
||||
|
||||
// Bind the first gpu::Pipeline we need - for calculating occlusion buffer
|
||||
batch.setPipeline(getOcclusionPipeline());
|
||||
batch._glUniform1f(_gScaleLoc, g_scale);
|
||||
batch._glUniform1f(_gBiasLoc, g_bias);
|
||||
batch._glUniform1f(_gSampleRadiusLoc, g_sample_rad);
|
||||
batch._glUniform1f(_gIntensityLoc, g_intensity);
|
||||
batch._glUniform1f(_bufferWidthLoc, DependencyManager::get<FramebufferCache>()->getFrameBufferSize().width());
|
||||
batch._glUniform1f(_bufferHeightLoc, DependencyManager::get<FramebufferCache>()->getFrameBufferSize().height());
|
||||
|
||||
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);
|
||||
|
||||
// Vertical blur step
|
||||
getVBlurPipeline();
|
||||
batch.setResourceTexture(0, _occlusionTexture);
|
||||
_vBlurBuffer->setRenderBuffer(0, _vBlurTexture);
|
||||
batch.setFramebuffer(_vBlurBuffer);
|
||||
|
||||
// Bind the second gpu::Pipeline we need - for calculating blur buffer
|
||||
batch.setPipeline(getVBlurPipeline());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||
|
||||
// Horizontal blur step
|
||||
getHBlurPipeline();
|
||||
batch.setResourceTexture(0, _vBlurTexture);
|
||||
_hBlurBuffer->setRenderBuffer(0, _hBlurTexture);
|
||||
batch.setFramebuffer(_hBlurBuffer);
|
||||
|
||||
// Bind the third gpu::Pipeline we need - for calculating blur buffer
|
||||
batch.setPipeline(getHBlurPipeline());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||
|
||||
// Blend step
|
||||
getBlendPipeline();
|
||||
batch.setResourceTexture(0, _hBlurTexture);
|
||||
batch.setFramebuffer(DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer());
|
||||
|
||||
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
|
||||
batch.setPipeline(getBlendPipeline());
|
||||
|
||||
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
|
||||
|
||||
// Ready to render
|
||||
args->_context->syncCache();
|
||||
args->_context->render((batch));
|
||||
}
|
61
libraries/render-utils/src/AmbientOcclusionEffect.h
Normal file
61
libraries/render-utils/src/AmbientOcclusionEffect.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// AmbientOcclusionEffect.h
|
||||
// libraries/render-utils/src/
|
||||
//
|
||||
// Created by Niraj Venkat on 7/15/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_AmbientOcclusionEffect_h
|
||||
#define hifi_AmbientOcclusionEffect_h
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
#include "render/DrawTask.h"
|
||||
|
||||
class AmbientOcclusion {
|
||||
public:
|
||||
|
||||
AmbientOcclusion();
|
||||
|
||||
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
typedef render::Job::Model<AmbientOcclusion> JobModel;
|
||||
|
||||
const gpu::PipelinePointer& getOcclusionPipeline();
|
||||
const gpu::PipelinePointer& getHBlurPipeline();
|
||||
const gpu::PipelinePointer& getVBlurPipeline();
|
||||
const gpu::PipelinePointer& getBlendPipeline();
|
||||
|
||||
private:
|
||||
|
||||
// Uniforms for AO
|
||||
gpu::int32 _gScaleLoc;
|
||||
gpu::int32 _gBiasLoc;
|
||||
gpu::int32 _gSampleRadiusLoc;
|
||||
gpu::int32 _gIntensityLoc;
|
||||
gpu::int32 _bufferWidthLoc;
|
||||
gpu::int32 _bufferHeightLoc;
|
||||
float g_scale;
|
||||
float g_bias;
|
||||
float g_sample_rad;
|
||||
float g_intensity;
|
||||
|
||||
gpu::PipelinePointer _occlusionPipeline;
|
||||
gpu::PipelinePointer _hBlurPipeline;
|
||||
gpu::PipelinePointer _vBlurPipeline;
|
||||
gpu::PipelinePointer _blendPipeline;
|
||||
|
||||
gpu::FramebufferPointer _occlusionBuffer;
|
||||
gpu::FramebufferPointer _hBlurBuffer;
|
||||
gpu::FramebufferPointer _vBlurBuffer;
|
||||
|
||||
gpu::TexturePointer _occlusionTexture;
|
||||
gpu::TexturePointer _hBlurTexture;
|
||||
gpu::TexturePointer _vBlurTexture;
|
||||
|
||||
};
|
||||
|
||||
#endif // hifi_AmbientOcclusionEffect_h
|
|
@ -22,6 +22,7 @@
|
|||
#include "TextureCache.h"
|
||||
|
||||
#include "render/DrawStatus.h"
|
||||
#include "AmbientOcclusionEffect.h"
|
||||
|
||||
#include "overlay3D_vert.h"
|
||||
#include "overlay3D_frag.h"
|
||||
|
@ -80,6 +81,11 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_jobs.push_back(Job(new DrawLight::JobModel("DrawLight")));
|
||||
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
|
||||
_jobs.push_back(Job(new ResolveDeferred::JobModel("ResolveDeferred")));
|
||||
_jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion")));
|
||||
|
||||
_jobs.back().setEnabled(false);
|
||||
_occlusionJobIndex = _jobs.size() - 1;
|
||||
|
||||
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
|
||||
FetchItems(
|
||||
ItemFilter::Builder::transparentShape().withoutLayered(),
|
||||
|
@ -93,10 +99,13 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
|||
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput())));
|
||||
|
||||
_jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques)));
|
||||
|
||||
|
||||
_jobs.back().setEnabled(false);
|
||||
_drawStatusJobIndex = _jobs.size() - 1;
|
||||
|
||||
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
|
||||
|
||||
_jobs.push_back(Job(new ResetGLState::JobModel()));
|
||||
|
||||
// Give ourselves 3 frmaes of timer queries
|
||||
|
@ -125,6 +134,9 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
// Make sure we turn the displayItemStatus on/off
|
||||
setDrawItemStatus(renderContext->_drawItemStatus);
|
||||
|
||||
// TODO: turn on/off AO through menu item
|
||||
setOcclusionStatus(renderContext->_occlusionStatus);
|
||||
|
||||
renderContext->args->_context->syncCache();
|
||||
|
||||
for (auto job : _jobs) {
|
||||
|
|
|
@ -82,6 +82,11 @@ public:
|
|||
void setDrawItemStatus(bool draw) { if (_drawStatusJobIndex >= 0) { _jobs[_drawStatusJobIndex].setEnabled(draw); } }
|
||||
bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } }
|
||||
|
||||
int _occlusionJobIndex = -1;
|
||||
|
||||
void setOcclusionStatus(bool draw) { if (_occlusionJobIndex >= 0) { _jobs[_occlusionJobIndex].setEnabled(draw); } }
|
||||
bool doOcclusionStatus() const { if (_occlusionJobIndex >= 0) { return _jobs[_occlusionJobIndex].isEnabled(); } else { return false; } }
|
||||
|
||||
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||
|
||||
|
||||
|
|
109
libraries/render-utils/src/ambient_occlusion.slf
Normal file
109
libraries/render-utils/src/ambient_occlusion.slf
Normal file
|
@ -0,0 +1,109 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// ambient_occlusion.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/15/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@>
|
||||
|
||||
<@include gpu/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
|
||||
uniform sampler2D depthTexture;
|
||||
uniform sampler2D normalTexture;
|
||||
|
||||
uniform float g_scale;
|
||||
uniform float g_bias;
|
||||
uniform float g_sample_rad;
|
||||
uniform float g_intensity;
|
||||
uniform float bufferWidth;
|
||||
uniform float bufferHeight;
|
||||
|
||||
#define SAMPLE_COUNT 4
|
||||
|
||||
float getRandom(vec2 uv) {
|
||||
return fract(sin(dot(uv.xy ,vec2(12.9898,78.233))) * 43758.5453);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
vec3 sampleKernel[4] = { vec3(0.2, 0.0, 0.0),
|
||||
vec3(0.0, 0.2, 0.0),
|
||||
vec3(0.0, 0.0, 0.2),
|
||||
vec3(0.2, 0.2, 0.2) };
|
||||
|
||||
TransformCamera cam = getTransformCamera();
|
||||
TransformObject obj = getTransformObject();
|
||||
|
||||
vec3 eyeDir = vec3(0.0, 0.0, -3.0);
|
||||
vec3 cameraPositionWorldSpace;
|
||||
<$transformEyeToWorldDir(cam, eyeDir, cameraPositionWorldSpace)$>
|
||||
|
||||
vec4 depthColor = texture2D(depthTexture, varTexcoord);
|
||||
|
||||
// z in non linear range [0,1]
|
||||
float depthVal = depthColor.r;
|
||||
// conversion into NDC [-1,1]
|
||||
float zNDC = depthVal * 2.0 - 1.0;
|
||||
float n = 1.0; // the near plane
|
||||
float f = 30.0; // the far plane
|
||||
float l = -1.0; // left
|
||||
float r = 1.0; // right
|
||||
float b = -1.0; // bottom
|
||||
float t = 1.0; // top
|
||||
|
||||
// conversion into eye space
|
||||
float zEye = 2*f*n / (zNDC*(f-n)-(f+n));
|
||||
// Converting from pixel coordinates to NDC
|
||||
float xNDC = gl_FragCoord.x/bufferWidth * 2.0 - 1.0;
|
||||
float yNDC = gl_FragCoord.y/bufferHeight * 2.0 - 1.0;
|
||||
// Unprojecting X and Y from NDC to eye space
|
||||
float xEye = -zEye*(xNDC*(r-l)+(r+l))/(2.0*n);
|
||||
float yEye = -zEye*(yNDC*(t-b)+(t+b))/(2.0*n);
|
||||
vec3 currentFragEyeSpace = vec3(xEye, yEye, zEye);
|
||||
vec3 currentFragWorldSpace;
|
||||
<$transformEyeToWorldDir(cam, currentFragEyeSpace, currentFragWorldSpace)$>
|
||||
|
||||
vec3 cameraToPositionRay = normalize(currentFragWorldSpace - cameraPositionWorldSpace);
|
||||
vec3 origin = cameraToPositionRay * depthVal + cameraPositionWorldSpace;
|
||||
|
||||
vec3 normal = normalize(texture2D(normalTexture, varTexcoord).xyz);
|
||||
//normal = normalize(normal * normalMatrix);
|
||||
|
||||
vec3 rvec = vec3(getRandom(varTexcoord.xy), getRandom(varTexcoord.yx), getRandom(varTexcoord.xx)) * 2.0 - 1.0;
|
||||
vec3 tangent = normalize(rvec - normal * dot(rvec, normal));
|
||||
vec3 bitangent = cross(normal, tangent);
|
||||
mat3 tbn = mat3(tangent, bitangent, normal);
|
||||
|
||||
float occlusion = 0.0;
|
||||
|
||||
for (int i = 0; i < SAMPLE_COUNT; ++i) {
|
||||
vec3 samplePos = origin + (tbn * sampleKernel[i]) * g_sample_rad;
|
||||
vec4 offset = cam._projectionViewUntranslated * vec4(samplePos, 1.0);
|
||||
|
||||
offset.xy = (offset.xy / offset.w) * 0.5 + 0.5;
|
||||
float depth = length(samplePos - cameraPositionWorldSpace);
|
||||
|
||||
float sampleDepthVal = texture2D(depthTexture, offset.xy).r;
|
||||
|
||||
float rangeDelta = abs(depthVal - sampleDepthVal);
|
||||
float rangeCheck = smoothstep(0.0, 1.0, g_sample_rad / rangeDelta);
|
||||
|
||||
occlusion += rangeCheck * step(sampleDepthVal, depth);
|
||||
}
|
||||
|
||||
occlusion = 1.0 - occlusion / float(SAMPLE_COUNT);
|
||||
occlusion = clamp(pow(occlusion, g_intensity), 0.0, 1.0);
|
||||
gl_FragColor = vec4(vec3(occlusion), 1.0);
|
||||
}
|
||||
|
24
libraries/render-utils/src/ambient_occlusion.slv
Normal file
24
libraries/render-utils/src/ambient_occlusion.slv
Normal file
|
@ -0,0 +1,24 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// ambient_occlusion.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/15/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/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
|
||||
void main(void) {
|
||||
varTexcoord = gl_MultiTexCoord0.xy;
|
||||
gl_Position = gl_Vertex;
|
||||
}
|
42
libraries/render-utils/src/gaussian_blur.slf
Normal file
42
libraries/render-utils/src/gaussian_blur.slf
Normal file
|
@ -0,0 +1,42 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// gaussian_blur.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/17/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@>
|
||||
|
||||
// the interpolated normal
|
||||
//varying vec4 interpolatedNormal;
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
varying vec2 varBlurTexcoords[14];
|
||||
|
||||
uniform sampler2D occlusionTexture;
|
||||
|
||||
void main(void) {
|
||||
gl_FragColor = vec4(0.0);
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[0])*0.0044299121055113265;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[1])*0.00895781211794;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[2])*0.0215963866053;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[3])*0.0443683338718;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[4])*0.0776744219933;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[5])*0.115876621105;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[6])*0.147308056121;
|
||||
gl_FragColor += texture2D(occlusionTexture, varTexcoord)*0.159576912161;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[7])*0.147308056121;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[8])*0.115876621105;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[9])*0.0776744219933;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[10])*0.0443683338718;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[11])*0.0215963866053;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[12])*0.00895781211794;
|
||||
gl_FragColor += texture2D(occlusionTexture, varBlurTexcoords[13])*0.0044299121055113265;
|
||||
}
|
41
libraries/render-utils/src/gaussian_blur_horizontal.slv
Normal file
41
libraries/render-utils/src/gaussian_blur_horizontal.slv
Normal file
|
@ -0,0 +1,41 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// guassian_blur_horizontal.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/17/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/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
varying vec2 varBlurTexcoords[14];
|
||||
|
||||
void main(void) {
|
||||
varTexcoord = gl_MultiTexCoord0.xy;
|
||||
gl_Position = gl_Vertex;
|
||||
|
||||
varBlurTexcoords[0] = varTexcoord + vec2(-0.028, 0.0);
|
||||
varBlurTexcoords[1] = varTexcoord + vec2(-0.024, 0.0);
|
||||
varBlurTexcoords[2] = varTexcoord + vec2(-0.020, 0.0);
|
||||
varBlurTexcoords[3] = varTexcoord + vec2(-0.016, 0.0);
|
||||
varBlurTexcoords[4] = varTexcoord + vec2(-0.012, 0.0);
|
||||
varBlurTexcoords[5] = varTexcoord + vec2(-0.008, 0.0);
|
||||
varBlurTexcoords[6] = varTexcoord + vec2(-0.004, 0.0);
|
||||
varBlurTexcoords[7] = varTexcoord + vec2(0.004, 0.0);
|
||||
varBlurTexcoords[8] = varTexcoord + vec2(0.008, 0.0);
|
||||
varBlurTexcoords[9] = varTexcoord + vec2(0.012, 0.0);
|
||||
varBlurTexcoords[10] = varTexcoord + vec2(0.016, 0.0);
|
||||
varBlurTexcoords[11] = varTexcoord + vec2(0.020, 0.0);
|
||||
varBlurTexcoords[12] = varTexcoord + vec2(0.024, 0.0);
|
||||
varBlurTexcoords[13] = varTexcoord + vec2(0.028, 0.0);
|
||||
}
|
||||
|
41
libraries/render-utils/src/gaussian_blur_vertical.slv
Normal file
41
libraries/render-utils/src/gaussian_blur_vertical.slv
Normal file
|
@ -0,0 +1,41 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// guassian_blur_vertical.vert
|
||||
// vertex shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/17/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/Transform.slh@>
|
||||
|
||||
<$declareStandardTransform()$>
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
varying vec2 varBlurTexcoords[14];
|
||||
|
||||
void main(void) {
|
||||
varTexcoord = gl_MultiTexCoord0.xy;
|
||||
gl_Position = gl_Vertex;
|
||||
|
||||
varBlurTexcoords[0] = varTexcoord + vec2(0.0, -0.028);
|
||||
varBlurTexcoords[1] = varTexcoord + vec2(0.0, -0.024);
|
||||
varBlurTexcoords[2] = varTexcoord + vec2(0.0, -0.020);
|
||||
varBlurTexcoords[3] = varTexcoord + vec2(0.0, -0.016);
|
||||
varBlurTexcoords[4] = varTexcoord + vec2(0.0, -0.012);
|
||||
varBlurTexcoords[5] = varTexcoord + vec2(0.0, -0.008);
|
||||
varBlurTexcoords[6] = varTexcoord + vec2(0.0, -0.004);
|
||||
varBlurTexcoords[7] = varTexcoord + vec2(0.0, 0.004);
|
||||
varBlurTexcoords[8] = varTexcoord + vec2(0.0, 0.008);
|
||||
varBlurTexcoords[9] = varTexcoord + vec2(0.0, 0.012);
|
||||
varBlurTexcoords[10] = varTexcoord + vec2(0.0, 0.016);
|
||||
varBlurTexcoords[11] = varTexcoord + vec2(0.0, 0.020);
|
||||
varBlurTexcoords[12] = varTexcoord + vec2(0.0, 0.024);
|
||||
varBlurTexcoords[13] = varTexcoord + vec2(0.0, 0.028);
|
||||
}
|
||||
|
29
libraries/render-utils/src/occlusion_blend.slf
Normal file
29
libraries/render-utils/src/occlusion_blend.slf
Normal file
|
@ -0,0 +1,29 @@
|
|||
<@include gpu/Config.slh@>
|
||||
<$VERSION_HEADER$>
|
||||
// Generated on <$_SCRIBE_DATE$>
|
||||
//
|
||||
// occlusion_blend.frag
|
||||
// fragment shader
|
||||
//
|
||||
// Created by Niraj Venkat on 7/20/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@>
|
||||
|
||||
varying vec2 varTexcoord;
|
||||
|
||||
uniform sampler2D blurredOcclusionTexture;
|
||||
|
||||
void main(void) {
|
||||
vec4 occlusionColor = texture2D(blurredOcclusionTexture, varTexcoord);
|
||||
|
||||
if(occlusionColor.r > 0.8 && occlusionColor.r <= 1.0) {
|
||||
gl_FragColor = vec4(vec3(0.0), 0.0);
|
||||
} else {
|
||||
gl_FragColor = vec4(vec3(occlusionColor.r), 1.0);
|
||||
}
|
||||
}
|
|
@ -51,6 +51,8 @@ public:
|
|||
|
||||
bool _drawItemStatus = false;
|
||||
|
||||
bool _occlusionStatus = false;
|
||||
|
||||
RenderContext() {}
|
||||
};
|
||||
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
||||
|
|
|
@ -86,7 +86,6 @@ public:
|
|||
AddressBar,
|
||||
AlignForearmsWithWrists,
|
||||
AlternateIK,
|
||||
AmbientOcclusion,
|
||||
Animations,
|
||||
Atmosphere,
|
||||
Attachments,
|
||||
|
@ -111,6 +110,7 @@ public:
|
|||
ControlWithSpeech,
|
||||
CopyAddress,
|
||||
CopyPath,
|
||||
DebugAmbientOcclusion,
|
||||
DecreaseAvatarSize,
|
||||
DeleteBookmark,
|
||||
DisableActivityLogger,
|
||||
|
|
Loading…
Reference in a new issue