Merge pull request #8525 from hyperlogic/bug-fix/web-entity-rendering

Improved web entity rendering
This commit is contained in:
Brad Hefta-Gaub 2016-08-25 16:49:00 -07:00 committed by GitHub
commit 10c465f591
7 changed files with 112 additions and 36 deletions

View file

@ -28,6 +28,7 @@
static const float DPI = 30.47f; static const float DPI = 30.47f;
static const float INCHES_TO_METERS = 1.0f / 39.3701f; static const float INCHES_TO_METERS = 1.0f / 39.3701f;
static float OPAQUE_ALPHA_THRESHOLD = 0.99f;
QString const Web3DOverlay::TYPE = "web3d"; QString const Web3DOverlay::TYPE = "web3d";
@ -106,7 +107,11 @@ void Web3DOverlay::render(RenderArgs* args) {
batch.setModelTransform(transform); batch.setModelTransform(transform);
auto geometryCache = DependencyManager::get<GeometryCache>(); auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch); if (color.a < OPAQUE_ALPHA_THRESHOLD) {
geometryCache->bindTransparentWebBrowserProgram(batch);
} else {
geometryCache->bindOpaqueWebBrowserProgram(batch);
}
geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color); geometryCache->renderQuad(batch, halfSize * -1.0f, halfSize, vec2(0), vec2(1), color);
batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me batch.setResourceTexture(0, args->_whiteTexture); // restore default white color after me
} }

View file

@ -35,6 +35,7 @@ static const uint32_t MAX_CONCURRENT_WEB_VIEWS = 100;
static uint64_t MAX_NO_RENDER_INTERVAL = 30 * USECS_PER_SECOND; static uint64_t MAX_NO_RENDER_INTERVAL = 30 * USECS_PER_SECOND;
static int MAX_WINDOW_SIZE = 4096; static int MAX_WINDOW_SIZE = 4096;
static float OPAQUE_ALPHA_THRESHOLD = 0.99f;
EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
EntityItemPointer entity{ new RenderableWebEntityItem(entityID) }; EntityItemPointer entity{ new RenderableWebEntityItem(entityID) };
@ -164,9 +165,14 @@ void RenderableWebEntityItem::render(RenderArgs* args) {
} }
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio); batch._glColor4f(1.0f, 1.0f, 1.0f, fadeRatio);
DependencyManager::get<GeometryCache>()->bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(batch); if (fadeRatio < OPAQUE_ALPHA_THRESHOLD) {
DependencyManager::get<GeometryCache>()->bindTransparentWebBrowserProgram(batch);
} else {
DependencyManager::get<GeometryCache>()->bindOpaqueWebBrowserProgram(batch);
}
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio)); DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texMin, texMax, glm::vec4(1.0f, 1.0f, 1.0f, fadeRatio));
} }
@ -291,3 +297,9 @@ void RenderableWebEntityItem::update(const quint64& now) {
destroyWebSurface(); destroyWebSurface();
} }
} }
bool RenderableWebEntityItem::isTransparent() {
float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f;
return fadeRatio < OPAQUE_ALPHA_THRESHOLD;
}

View file

@ -44,6 +44,8 @@ public:
SIMPLE_RENDERABLE(); SIMPLE_RENDERABLE();
virtual bool isTransparent() override;
private: private:
bool buildWebSurface(EntityTreeRenderer* renderer); bool buildWebSurface(EntityTreeRenderer* renderer);
void destroyWebSurface(); void destroyWebSurface();

View file

@ -35,7 +35,8 @@
#include "simple_vert.h" #include "simple_vert.h"
#include "simple_textured_frag.h" #include "simple_textured_frag.h"
#include "simple_textured_unlit_frag.h" #include "simple_textured_unlit_frag.h"
#include "simple_srgb_textured_unlit_no_tex_alpha_frag.h" #include "simple_opaque_web_browser_frag.h"
#include "simple_transparent_web_browser_frag.h"
#include "glowLine_vert.h" #include "glowLine_vert.h"
#include "glowLine_geom.h" #include "glowLine_geom.h"
#include "glowLine_frag.h" #include "glowLine_frag.h"
@ -1763,25 +1764,55 @@ inline bool operator==(const SimpleProgramKey& a, const SimpleProgramKey& b) {
return a.getRaw() == b.getRaw(); return a.getRaw() == b.getRaw();
} }
void GeometryCache::bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch) { void GeometryCache::bindOpaqueWebBrowserProgram(gpu::Batch& batch) {
batch.setPipeline(getSimpleSRGBTexturedUnlitNoTexAlphaPipeline()); batch.setPipeline(getOpaqueWebBrowserProgram());
// Set a default normal map // Set a default normal map
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING, batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture()); DependencyManager::get<TextureCache>()->getNormalFittingTexture());
} }
gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline() { gpu::PipelinePointer GeometryCache::getOpaqueWebBrowserProgram() {
// Compile the shaders, once
static std::once_flag once; static std::once_flag once;
std::call_once(once, [&]() { std::call_once(once, [&]() {
auto VS = gpu::Shader::createVertex(std::string(simple_vert)); auto VS = gpu::Shader::createVertex(std::string(simple_vert));
auto PS = gpu::Shader::createPixel(std::string(simple_srgb_textured_unlit_no_tex_alpha_frag)); auto PS = gpu::Shader::createPixel(std::string(simple_opaque_web_browser_frag));
_simpleSRGBTexturedUnlitNoTexAlphaShader = gpu::Shader::createProgram(VS, PS); _simpleOpaqueWebBrowserShader = gpu::Shader::createProgram(VS, PS);
gpu::Shader::BindingSet slotBindings; gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING)); slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
gpu::Shader::makeProgram(*_simpleSRGBTexturedUnlitNoTexAlphaShader, slotBindings); gpu::Shader::makeProgram(*_simpleOpaqueWebBrowserShader, slotBindings);
auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_NONE);
state->setDepthTest(true, true, gpu::LESS_EQUAL);
state->setBlendFunction(false,
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);
_simpleOpaqueWebBrowserPipeline = gpu::Pipeline::create(_simpleOpaqueWebBrowserShader, state);
});
return _simpleOpaqueWebBrowserPipeline;
}
void GeometryCache::bindTransparentWebBrowserProgram(gpu::Batch& batch) {
batch.setPipeline(getTransparentWebBrowserProgram());
// Set a default normal map
batch.setResourceTexture(render::ShapePipeline::Slot::MAP::NORMAL_FITTING,
DependencyManager::get<TextureCache>()->getNormalFittingTexture());
}
gpu::PipelinePointer GeometryCache::getTransparentWebBrowserProgram() {
static std::once_flag once;
std::call_once(once, [&]() {
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
auto PS = gpu::Shader::createPixel(std::string(simple_transparent_web_browser_frag));
_simpleTransparentWebBrowserShader = gpu::Shader::createProgram(VS, PS);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("normalFittingMap"), render::ShapePipeline::Slot::MAP::NORMAL_FITTING));
gpu::Shader::makeProgram(*_simpleTransparentWebBrowserShader, slotBindings);
auto state = std::make_shared<gpu::State>(); auto state = std::make_shared<gpu::State>();
state->setCullMode(gpu::State::CULL_NONE); state->setCullMode(gpu::State::CULL_NONE);
state->setDepthTest(true, true, gpu::LESS_EQUAL); state->setDepthTest(true, true, gpu::LESS_EQUAL);
@ -1789,10 +1820,10 @@ gpu::PipelinePointer GeometryCache::getSimpleSRGBTexturedUnlitNoTexAlphaPipeline
gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, 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); gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE);
_simpleSRGBTexturedUnlitNoTexAlphaPipeline = gpu::Pipeline::create(_simpleSRGBTexturedUnlitNoTexAlphaShader, state); _simpleTransparentWebBrowserPipeline = gpu::Pipeline::create(_simpleTransparentWebBrowserShader, state);
}); });
return _simpleSRGBTexturedUnlitNoTexAlphaPipeline; return _simpleTransparentWebBrowserPipeline;
} }
void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) { void GeometryCache::bindSimpleProgram(gpu::Batch& batch, bool textured, bool transparent, bool culled, bool unlit, bool depthBiased) {

View file

@ -150,7 +150,6 @@ public:
int allocateID() { return _nextID++; } int allocateID() { return _nextID++; }
static const int UNKNOWN_ID; static const int UNKNOWN_ID;
// Bind the pipeline and get the state to render static geometry // Bind the pipeline and get the state to render static geometry
void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true, void bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool transparent = false, bool culled = true,
bool unlit = false, bool depthBias = false); bool unlit = false, bool depthBias = false);
@ -158,8 +157,11 @@ public:
gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true, gpu::PipelinePointer getSimplePipeline(bool textured = false, bool transparent = false, bool culled = true,
bool unlit = false, bool depthBias = false); bool unlit = false, bool depthBias = false);
void bindSimpleSRGBTexturedUnlitNoTexAlphaProgram(gpu::Batch& batch); void bindOpaqueWebBrowserProgram(gpu::Batch& batch);
gpu::PipelinePointer getSimpleSRGBTexturedUnlitNoTexAlphaPipeline(); gpu::PipelinePointer getOpaqueWebBrowserProgram();
void bindTransparentWebBrowserProgram(gpu::Batch& batch);
gpu::PipelinePointer getTransparentWebBrowserProgram();
render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; } render::ShapePipelinePointer getOpaqueShapePipeline() { return GeometryCache::_simpleOpaquePipeline; }
render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; } render::ShapePipelinePointer getTransparentShapePipeline() { return GeometryCache::_simpleTransparentPipeline; }
@ -423,9 +425,11 @@ private:
gpu::PipelinePointer _glowLinePipeline; gpu::PipelinePointer _glowLinePipeline;
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms; QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
gpu::ShaderPointer _simpleSRGBTexturedUnlitNoTexAlphaShader; gpu::ShaderPointer _simpleOpaqueWebBrowserShader;
gpu::PipelinePointer _simpleSRGBTexturedUnlitNoTexAlphaPipeline; gpu::PipelinePointer _simpleOpaqueWebBrowserPipeline;
gpu::ShaderPointer _simpleTransparentWebBrowserShader;
gpu::PipelinePointer _simpleTransparentWebBrowserPipeline;
}; };
#endif // hifi_GeometryCache_h #endif // hifi_GeometryCache_h

View file

@ -0,0 +1,30 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// simple_opaque_web_browser.frag
// fragment shader
//
// Created by Anthony Thibault on 7/25/16.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
<@include gpu/Color.slh@>
<@include DeferredBufferWrite.slh@>
// the albedo texture
uniform sampler2D originalTexture;
// the interpolated normal
in vec3 _normal;
in vec4 _color;
in vec2 _texCoord0;
void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st);
texel = colorToLinearRGBA(texel);
packDeferredFragmentUnlit(normalize(_normal), 1.0, _color.rgb * texel.rgb);
}

View file

@ -2,7 +2,7 @@
<$VERSION_HEADER$> <$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$> // Generated on <$_SCRIBE_DATE$>
// //
// simple_srgb_texture_unlit_no_tex_alpha.frag // simple_transparent_web_browser.frag
// fragment shader // fragment shader
// //
// Created by Anthony Thibault on 7/25/16. // Created by Anthony Thibault on 7/25/16.
@ -26,19 +26,11 @@ in vec2 _texCoord0;
void main(void) { void main(void) {
vec4 texel = texture(originalTexture, _texCoord0.st); vec4 texel = texture(originalTexture, _texCoord0.st);
texel = colorToLinearRGBA(texel); texel = colorToLinearRGBA(texel);
packDeferredFragmentTranslucent(
const float ALPHA_THRESHOLD = 0.999; normalize(_normal),
if (_color.a < ALPHA_THRESHOLD) { _color.a,
packDeferredFragmentTranslucent( _color.rgb * texel.rgb,
normalize(_normal), DEFAULT_FRESNEL,
_color.a, DEFAULT_ROUGHNESS);
_color.rgb * texel.rgb,
DEFAULT_FRESNEL,
DEFAULT_ROUGHNESS);
} else {
packDeferredFragmentUnlit(
normalize(_normal),
1.0,
_color.rgb * texel.rgb);
}
} }