From d615e2e83b68e59c9d538fa31ff9f78c030096e9 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 1 Mar 2016 17:46:53 -0800 Subject: [PATCH 01/10] Avoid redundant zone updates --- .../entities-renderer/src/EntityTreeRenderer.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 44c3146b41..dc59d40e82 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -158,6 +158,8 @@ void EntityTreeRenderer::update() { } bool EntityTreeRenderer::checkEnterLeaveEntities() { + bool didUpdate = false; + if (_tree && !_shuttingDown) { glm::vec3 avatarPosition = _viewState->getAvatarPosition(); @@ -172,6 +174,7 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { std::static_pointer_cast(_tree)->findEntities(avatarPosition, radius, foundEntities); // Whenever you're in an intersection between zones, we will always choose the smallest zone. + auto oldBestZone = _bestZone; _bestZone = nullptr; // NOTE: Is this what we want? _bestZoneVolume = std::numeric_limits::max(); @@ -204,7 +207,10 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { } } - applyZonePropertiesToScene(_bestZone); + if (_bestZone != oldBestZone) { + applyZonePropertiesToScene(_bestZone); + didUpdate = true; + } }); // Note: at this point we don't need to worry about the tree being locked, because we only deal with @@ -228,11 +234,9 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { } _currentEntitiesInside = entitiesContainingAvatar; _lastAvatarPosition = avatarPosition; - - return true; } } - return false; + return didUpdate; } void EntityTreeRenderer::leaveAllEntities() { From 1e925d7bd87b3cea6faa155cb2c1c9b4b55cbd7d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 1 Mar 2016 18:53:46 -0800 Subject: [PATCH 02/10] Fetch unspecified textures on a delay This fixes an abort caused by the assertion in ResourceCache::getResource: assert(delayLoad). --- .../model-networking/src/model-networking/TextureCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/model-networking/src/model-networking/TextureCache.cpp b/libraries/model-networking/src/model-networking/TextureCache.cpp index a2cd3284ef..58a82d5f11 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.cpp +++ b/libraries/model-networking/src/model-networking/TextureCache.cpp @@ -146,7 +146,7 @@ public: NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type, const QByteArray& content) { TextureExtra extra = { type, content }; - return ResourceCache::getResource(url, QUrl(), false, &extra).staticCast(); + return ResourceCache::getResource(url, QUrl(), content.isEmpty(), &extra).staticCast(); } /// Returns a texture version of an image file From d7d351fc636830135d92d17d80c550b7798c2a8d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 12:50:52 -0800 Subject: [PATCH 03/10] Guard against unloaded env cubemaps --- .../src/EntityTreeRenderer.cpp | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index dc59d40e82..28a89162ba 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -140,8 +140,8 @@ void EntityTreeRenderer::update() { // If we haven't already updated and previously attempted to load a texture, // check if the texture loaded and apply it if (!updated && ( - (_pendingSkyboxTexture && _skyboxTexture && _skyboxTexture->isLoaded()) || - (_pendingAmbientTexture && _ambientTexture && _ambientTexture->isLoaded()))) { + (_pendingSkyboxTexture && (!_skyboxTexture || _skyboxTexture->isLoaded())) || + (_pendingAmbientTexture && (!_ambientTexture && _ambientTexture->isLoaded())))) { applyZonePropertiesToScene(_bestZone); } @@ -326,15 +326,19 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetTexture(zone->getKeyLightProperties().getAmbientURL(), CUBE_TEXTURE); - if (_ambientTexture && _ambientTexture->isLoaded() && _ambientTexture->getGPUTexture()) { + _pendingAmbientTexture = true; + + if (_ambientTexture && _ambientTexture->isLoaded()) { _pendingAmbientTexture = false; - if (_ambientTexture->getGPUTexture()->getIrradiance()) { - sceneKeyLight->setAmbientSphere(_ambientTexture->getGPUTexture()->getIrradiance()); - sceneKeyLight->setAmbientMap(_ambientTexture->getGPUTexture()); + + auto texture = _ambientTexture->getGPUTexture(); + if (texture) { + sceneKeyLight->setAmbientSphere(texture->getIrradiance()); + sceneKeyLight->setAmbientMap(texture); isAmbientTextureSet = true; + } else { + qCDebug(entitiesrenderer) << "Failed to load ambient texture:" << zone->getKeyLightProperties().getAmbientURL(); } - } else { - _pendingAmbientTexture = true; } } @@ -353,24 +357,27 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptrgetSkyboxProperties().getURL().isEmpty()) { - skybox->setCubemap(gpu::TexturePointer()); + skybox->setCubemap(nullptr); _pendingSkyboxTexture = false; _skyboxTexture.clear(); } else { // Update the Texture of the Skybox with the one pointed by this zone _skyboxTexture = textureCache->getTexture(zone->getSkyboxProperties().getURL(), CUBE_TEXTURE); + _pendingSkyboxTexture = true; + + if (_skyboxTexture && _skyboxTexture->isLoaded()) { + _pendingSkyboxTexture = false; - if (_skyboxTexture && _skyboxTexture->isLoaded() && _skyboxTexture->getGPUTexture()) { auto texture = _skyboxTexture->getGPUTexture(); skybox->setCubemap(texture); - _pendingSkyboxTexture = false; - if (!isAmbientTextureSet && texture->getIrradiance()) { + if (!isAmbientTextureSet) { sceneKeyLight->setAmbientSphere(texture->getIrradiance()); sceneKeyLight->setAmbientMap(texture); isAmbientTextureSet = true; } } else { - _pendingSkyboxTexture = true; + skybox->setCubemap(nullptr); + qCDebug(entitiesrenderer) << "Failed to load skybox:" << zone->getSkyboxProperties().getURL(); } } From b627a17ce911974bcb72ebeb7c24fc5c10abbf5a Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 12:58:49 -0800 Subject: [PATCH 04/10] Allow px/color skybox without tex --- interface/src/Application.cpp | 9 ++-- .../src/model-networking/TextureCache.h | 2 - libraries/model/src/model/Skybox.cpp | 49 +++++++------------ libraries/model/src/model/Skybox.h | 13 +++-- libraries/model/src/model/Skybox.slf | 36 ++++---------- .../src/procedural/ProceduralSkybox.cpp | 17 ++----- 6 files changed, 42 insertions(+), 84 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ae63f817a..5dae5fc4c6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3757,19 +3757,19 @@ namespace render { switch (backgroundMode) { case model::SunSkyStage::SKY_BOX: { auto skybox = skyStage->getSkybox(); - if (skybox && skybox->getCubemap() && skybox->getCubemap()->isDefined()) { + if (skybox) { PerformanceTimer perfTimer("skybox"); skybox->render(batch, *(args->_viewFrustum)); break; } - // If no skybox texture is available, render the SKY_DOME while it loads } - // fall through to next case + + // Fall through: if no skybox is available, render the SKY_DOME case model::SunSkyStage::SKY_DOME: { if (Menu::getInstance()->isOptionChecked(MenuOption::Stars)) { PerformanceTimer perfTimer("stars"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::payloadRender() ... stars..."); + "Application::payloadRender() ... My god, it's full of stars..."); // should be the first rendering pass - w/o depth buffer / lighting static const float alpha = 1.0f; @@ -3777,6 +3777,7 @@ namespace render { } } break; + case model::SunSkyStage::NO_BACKGROUND: default: // this line intentionally left blank diff --git a/libraries/model-networking/src/model-networking/TextureCache.h b/libraries/model-networking/src/model-networking/TextureCache.h index 72a09a8b3f..6fb0cc3177 100644 --- a/libraries/model-networking/src/model-networking/TextureCache.h +++ b/libraries/model-networking/src/model-networking/TextureCache.h @@ -101,8 +101,6 @@ private: /// A simple object wrapper for an OpenGL texture. class Texture { public: - friend class TextureCache; - gpu::TexturePointer getGPUTexture() const { return _textureSource->getGPUTexture(); } gpu::TextureSourcePointer _textureSource; }; diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 476ac2fa08..0f9d3ca4de 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -21,54 +21,39 @@ using namespace model; Skybox::Skybox() { - Data data; - _dataBuffer = gpu::BufferView(std::make_shared(sizeof(Data), (const gpu::Byte*) &data)); - -/* // PLease create a default engineer skybox - _cubemap.reset( gpu::Texture::createCube(gpu::Element::COLOR_RGBA_32, 1)); - unsigned char texels[] = { - 255, 0, 0, 255, - 0, 255, 255, 255, - 0, 0, 255, 255, - 255, 255, 0, 255, - 0, 255, 0, 255, - 255, 0, 255, 255, - }; - _cubemap->assignStoredMip(0, gpu::Element::COLOR_RGBA_32, sizeof(texels), texels);*/ + Schema schema; + _schemaBuffer = gpu::BufferView(std::make_shared(sizeof(Schema), (const gpu::Byte*) &schema)); } void Skybox::setColor(const Color& color) { - _dataBuffer.edit()._color = color; + _schemaBuffer.edit()._color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { _cubemap = cubemap; } - -void Skybox::updateDataBuffer() const { +void Skybox::updateSchemaBuffer() const { auto blend = 0.0f; if (getCubemap() && getCubemap()->isDefined()) { - blend = 1.0f; + blend = 0.5f; + // If pitch black neutralize the color if (glm::all(glm::equal(getColor(), glm::vec3(0.0f)))) { - blend = 2.0f; + blend = 1.0f; } } - if (blend != _dataBuffer.get()._blend) { - _dataBuffer.edit()._blend = blend; + if (blend != _schemaBuffer.get()._blend) { + _schemaBuffer.edit()._blend = blend; } } - - void Skybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { - updateDataBuffer(); + updateSchemaBuffer(); Skybox::render(batch, frustum, (*this)); } - void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Skybox& skybox) { // Create the static shared elements used to render the skybox static gpu::BufferPointer theConstants; @@ -98,10 +83,6 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky // Render - gpu::TexturePointer skymap = skybox.getCubemap(); - // FIXME: skymap->isDefined may not be threadsafe - assert(skymap && skymap->isDefined()); - glm::mat4 projMat; viewFrustum.evalProjectionMatrix(projMat); @@ -112,11 +93,15 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setModelTransform(Transform()); // only for Mac batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._dataBuffer); - batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); + batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._schemaBuffer); + + gpu::TexturePointer skymap = skybox.getCubemap(); + // FIXME: skymap->isDefined may not be threadsafe + if (skymap && skymap->isDefined()) { + batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); + } batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); } - diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index 14ba9fa005..7382ffabdd 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -30,28 +30,27 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color getColor() const { return _dataBuffer.get()._color; } + const Color getColor() const { return _schemaBuffer.get()._color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; - static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); protected: gpu::TexturePointer _cubemap; - class Data { + class Schema { public: - glm::vec3 _color{ 1.0f, 1.0f, 1.0f }; - float _blend = 1.0f; + glm::vec3 _color { 1.0f, 1.0f, 1.0f }; + float _blend { 0.0f }; }; - mutable gpu::BufferView _dataBuffer; + mutable gpu::BufferView _schemaBuffer; - void updateDataBuffer() const; + void updateSchemaBuffer() const; }; typedef std::shared_ptr< Skybox > SkyboxPointer; diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf index f8a568bcf9..93f68e3406 100755 --- a/libraries/model/src/model/Skybox.slf +++ b/libraries/model/src/model/Skybox.slf @@ -14,7 +14,8 @@ uniform samplerCube cubeMap; struct Skybox { - vec4 _color; + vec3 _color; + float _blend; }; uniform skyboxBuffer { @@ -24,36 +25,17 @@ uniform skyboxBuffer { in vec3 _normal; out vec4 _fragColor; -//PROCEDURAL_COMMON_BLOCK - -#line 1001 -//PROCEDURAL_BLOCK - -#line 2033 void main(void) { - -#ifdef PROCEDURAL - - vec3 color = getSkyboxColor(); - _fragColor = vec4(color, 0.0); - -#else - vec3 coord = normalize(_normal); + vec3 color = _skybox._color; - // Skybox color or blend with skymap - vec3 color = _skybox._color.rgb; - if (_skybox._color.a > 0.0) { - vec3 texel = texture(cubeMap, coord).rgb; - if (_skybox._color.a < 2.0) { - color *= texel; - } else { - color = texel; + // blend is only set if there is a cubemap + if (_skybox._blend > 0.0) { + color = texture(cubeMap, coord).rgb; + if (_skybox._blend < 1.0) { + color *= _skybox._color; } - } + } _fragColor = vec4(color, 0.0); - -#endif - } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 167d49cbaf..95deaa4dc5 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -38,20 +38,15 @@ void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) { } void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& frustum) const { - ProceduralSkybox::render(batch, frustum, (*this)); + if (_procedural) { + ProceduralSkybox::render(batch, frustum, (*this)); + } else { + Skybox::render(batch, frustum); + } } void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const ProceduralSkybox& skybox) { - if (!(skybox._procedural)) { - skybox.updateDataBuffer(); - Skybox::render(batch, viewFrustum, skybox); - } - if (skybox._procedural && skybox._procedural->_enabled && skybox._procedural->ready()) { - gpu::TexturePointer skymap = skybox.getCubemap(); - // FIXME: skymap->isDefined may not be threadsafe - assert(skymap && skymap->isDefined()); - glm::mat4 projMat; viewFrustum.evalProjectionMatrix(projMat); @@ -60,10 +55,8 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, batch.setProjectionTransform(projMat); batch.setViewTransform(viewTransform); batch.setModelTransform(Transform()); // only for Mac - batch.setResourceTexture(0, skybox.getCubemap()); skybox._procedural->prepare(batch, glm::vec3(0), glm::vec3(1)); batch.draw(gpu::TRIANGLE_STRIP, 4); } } - From 4eca43027a1d935354a2075be5ca78a26a556516 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 21:05:36 -0800 Subject: [PATCH 05/10] Add texture, color to px skybox --- libraries/model/src/model/Skybox.cpp | 35 ++++++++-------- libraries/model/src/model/Skybox.h | 12 ++++-- libraries/model/src/model/Skybox.slf | 41 ------------------- .../src/model/skybox.slf} | 16 +++++--- .../src/model/{Skybox.slv => skybox.slv} | 0 .../procedural/src/procedural/Procedural.h | 1 + .../src/procedural/ProceduralSkybox.cpp | 14 ++++--- .../src/procedural/ProceduralSkybox.slv | 39 ------------------ 8 files changed, 47 insertions(+), 111 deletions(-) delete mode 100755 libraries/model/src/model/Skybox.slf rename libraries/{procedural/src/procedural/ProceduralSkybox.slf => model/src/model/skybox.slf} (76%) mode change 100644 => 100755 rename libraries/model/src/model/{Skybox.slv => skybox.slv} (100%) delete mode 100644 libraries/procedural/src/procedural/ProceduralSkybox.slv diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index 0f9d3ca4de..aff4361338 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -15,8 +15,8 @@ #include #include -#include "Skybox_vert.h" -#include "Skybox_frag.h" +#include "skybox_vert.h" +#include "skybox_frag.h" using namespace model; @@ -26,7 +26,7 @@ Skybox::Skybox() { } void Skybox::setColor(const Color& color) { - _schemaBuffer.edit()._color = color; + _schemaBuffer.edit().color = color; } void Skybox::setCubemap(const gpu::TexturePointer& cubemap) { @@ -44,8 +44,18 @@ void Skybox::updateSchemaBuffer() const { } } - if (blend != _schemaBuffer.get()._blend) { - _schemaBuffer.edit()._blend = blend; + if (blend != _schemaBuffer.get().blend) { + _schemaBuffer.edit().blend = blend; + } +} + +void Skybox::prepare(gpu::Batch& batch, int textureSlot, int bufferSlot) const { + batch.setUniformBuffer(bufferSlot, _schemaBuffer); + + gpu::TexturePointer skymap = getCubemap(); + // FIXME: skymap->isDefined may not be threadsafe + if (skymap && skymap->isDefined()) { + batch.setResourceTexture(textureSlot, skymap); } } @@ -58,13 +68,11 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky // Create the static shared elements used to render the skybox static gpu::BufferPointer theConstants; static gpu::PipelinePointer thePipeline; - const int SKYBOX_SKYMAP_SLOT = 0; - const int SKYBOX_CONSTANTS_SLOT = 0; static std::once_flag once; std::call_once(once, [&] { { - auto skyVS = gpu::Shader::createVertex(std::string(Skybox_vert)); - auto skyFS = gpu::Shader::createPixel(std::string(Skybox_frag)); + auto skyVS = gpu::Shader::createVertex(std::string(skybox_vert)); + auto skyFS = gpu::Shader::createPixel(std::string(skybox_frag)); auto skyShader = gpu::Shader::createProgram(skyVS, skyFS); gpu::Shader::BindingSet bindings; @@ -93,14 +101,7 @@ void Skybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, const Sky batch.setModelTransform(Transform()); // only for Mac batch.setPipeline(thePipeline); - batch.setUniformBuffer(SKYBOX_CONSTANTS_SLOT, skybox._schemaBuffer); - - gpu::TexturePointer skymap = skybox.getCubemap(); - // FIXME: skymap->isDefined may not be threadsafe - if (skymap && skymap->isDefined()) { - batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, skymap); - } - + skybox.prepare(batch); batch.draw(gpu::TRIANGLE_STRIP, 4); batch.setResourceTexture(SKYBOX_SKYMAP_SLOT, nullptr); diff --git a/libraries/model/src/model/Skybox.h b/libraries/model/src/model/Skybox.h index 7382ffabdd..e9e7ee8b26 100755 --- a/libraries/model/src/model/Skybox.h +++ b/libraries/model/src/model/Skybox.h @@ -30,29 +30,33 @@ public: virtual ~Skybox() {}; void setColor(const Color& color); - const Color getColor() const { return _schemaBuffer.get()._color; } + const Color getColor() const { return _schemaBuffer.get().color; } void setCubemap(const gpu::TexturePointer& cubemap); const gpu::TexturePointer& getCubemap() const { return _cubemap; } + void prepare(gpu::Batch& batch, int textureSlot = SKYBOX_SKYMAP_SLOT, int bufferSlot = SKYBOX_CONSTANTS_SLOT) const; virtual void render(gpu::Batch& batch, const ViewFrustum& frustum) const; static void render(gpu::Batch& batch, const ViewFrustum& frustum, const Skybox& skybox); protected: + static const int SKYBOX_SKYMAP_SLOT { 0 }; + static const int SKYBOX_CONSTANTS_SLOT { 0 }; + gpu::TexturePointer _cubemap; class Schema { public: - glm::vec3 _color { 1.0f, 1.0f, 1.0f }; - float _blend { 0.0f }; + glm::vec3 color { 1.0f, 1.0f, 1.0f }; + float blend { 0.0f }; }; mutable gpu::BufferView _schemaBuffer; void updateSchemaBuffer() const; }; -typedef std::shared_ptr< Skybox > SkyboxPointer; +typedef std::shared_ptr SkyboxPointer; }; diff --git a/libraries/model/src/model/Skybox.slf b/libraries/model/src/model/Skybox.slf deleted file mode 100755 index 93f68e3406..0000000000 --- a/libraries/model/src/model/Skybox.slf +++ /dev/null @@ -1,41 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// skybox.frag -// fragment shader -// -// Created by Sam Gateau on 5/5/2015. -// 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 -// - -uniform samplerCube cubeMap; - -struct Skybox { - vec3 _color; - float _blend; -}; - -uniform skyboxBuffer { - Skybox _skybox; -}; - -in vec3 _normal; -out vec4 _fragColor; - -void main(void) { - vec3 coord = normalize(_normal); - vec3 color = _skybox._color; - - // blend is only set if there is a cubemap - if (_skybox._blend > 0.0) { - color = texture(cubeMap, coord).rgb; - if (_skybox._blend < 1.0) { - color *= _skybox._color; - } - } - - _fragColor = vec4(color, 0.0); -} diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.slf b/libraries/model/src/model/skybox.slf old mode 100644 new mode 100755 similarity index 76% rename from libraries/procedural/src/procedural/ProceduralSkybox.slf rename to libraries/model/src/model/skybox.slf index 7ad6f6b5a1..6eb3cf3963 --- a/libraries/procedural/src/procedural/ProceduralSkybox.slf +++ b/libraries/model/src/model/skybox.slf @@ -14,11 +14,11 @@ uniform samplerCube cubeMap; struct Skybox { - vec4 _color; + vec4 color; }; uniform skyboxBuffer { - Skybox _skybox; + Skybox skybox; }; in vec3 _normal; @@ -40,10 +40,16 @@ void main(void) { _fragColor = vec4(color, 0.0); #else - vec3 coord = normalize(_normal); - vec3 texel = texture(cubeMap, coord).rgb; - vec3 color = texel * _skybox._color.rgb; + vec3 color = skybox.color.rgb; + + // blend is only set if there is a cubemap + if (skybox.color.a > 0.0) { + color = texture(cubeMap, coord).rgb; + if (skybox.color.a < 1.0) { + color *= skybox.color.rgb; + } + } _fragColor = vec4(color, 0.0); #endif diff --git a/libraries/model/src/model/Skybox.slv b/libraries/model/src/model/skybox.slv similarity index 100% rename from libraries/model/src/model/Skybox.slv rename to libraries/model/src/model/skybox.slv diff --git a/libraries/procedural/src/procedural/Procedural.h b/libraries/procedural/src/procedural/Procedural.h index 1b02fbd435..0d3ab63773 100644 --- a/libraries/procedural/src/procedural/Procedural.h +++ b/libraries/procedural/src/procedural/Procedural.h @@ -35,6 +35,7 @@ struct Procedural { void parse(const QJsonObject&); bool ready(); void prepare(gpu::Batch& batch, const glm::vec3& position, const glm::vec3& size); + const gpu::ShaderPointer& getShader() const { return _shader; } void setupUniforms(); glm::vec4 getColor(const glm::vec4& entityColor); diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.cpp b/libraries/procedural/src/procedural/ProceduralSkybox.cpp index 95deaa4dc5..cf57dbb574 100644 --- a/libraries/procedural/src/procedural/ProceduralSkybox.cpp +++ b/libraries/procedural/src/procedural/ProceduralSkybox.cpp @@ -15,8 +15,8 @@ #include #include -#include "ProceduralSkybox_vert.h" -#include "ProceduralSkybox_frag.h" +#include +#include ProceduralSkybox::ProceduralSkybox() : model::Skybox() { } @@ -30,8 +30,8 @@ ProceduralSkybox::ProceduralSkybox(const ProceduralSkybox& skybox) : void ProceduralSkybox::setProcedural(const ProceduralPointer& procedural) { _procedural = procedural; if (_procedural) { - _procedural->_vertexSource = ProceduralSkybox_vert; - _procedural->_fragmentSource = ProceduralSkybox_frag; + _procedural->_vertexSource = skybox_vert; + _procedural->_fragmentSource = skybox_frag; // Adjust the pipeline state for background using the stencil test _procedural->_state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP)); } @@ -56,7 +56,11 @@ void ProceduralSkybox::render(gpu::Batch& batch, const ViewFrustum& viewFrustum, batch.setViewTransform(viewTransform); batch.setModelTransform(Transform()); // only for Mac - skybox._procedural->prepare(batch, glm::vec3(0), glm::vec3(1)); + const auto& procedural = skybox._procedural; + procedural->prepare(batch, glm::vec3(0), glm::vec3(1)); + auto textureSlot = procedural->getShader()->getTextures().findLocation("cubeMap"); + auto bufferSlot = procedural->getShader()->getBuffers().findLocation("skyboxBuffer"); + skybox.prepare(batch, textureSlot, bufferSlot); batch.draw(gpu::TRIANGLE_STRIP, 4); } } diff --git a/libraries/procedural/src/procedural/ProceduralSkybox.slv b/libraries/procedural/src/procedural/ProceduralSkybox.slv deleted file mode 100644 index 810afb1033..0000000000 --- a/libraries/procedural/src/procedural/ProceduralSkybox.slv +++ /dev/null @@ -1,39 +0,0 @@ -<@include gpu/Config.slh@> -<$VERSION_HEADER$> -// Generated on <$_SCRIBE_DATE$> -// skybox.vert -// vertex shader -// -// Created by Sam Gateau on 5/5/2015. -// 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()$> - -out vec3 _normal; - -void main(void) { - const float depth = 0.0; - const vec4 UNIT_QUAD[4] = vec4[4]( - vec4(-1.0, -1.0, depth, 1.0), - vec4(1.0, -1.0, depth, 1.0), - vec4(-1.0, 1.0, depth, 1.0), - vec4(1.0, 1.0, depth, 1.0) - ); - vec4 inPosition = UNIT_QUAD[gl_VertexID]; - - // standard transform - TransformCamera cam = getTransformCamera(); - vec3 clipDir = vec3(inPosition.xy, 0.0); - vec3 eyeDir; - <$transformClipToEyeDir(cam, clipDir, eyeDir)$> - <$transformEyeToWorldDir(cam, eyeDir, _normal)$> - - // Position is supposed to come in clip space - gl_Position = vec4(inPosition.xy, 0.0, 1.0); -} \ No newline at end of file From 25607709a5e829cad234e79d71b2314f70c4438e Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 21:44:43 -0800 Subject: [PATCH 06/10] Add test for skybox --- examples/tests/skybox/px.fs | 18 ++++++ examples/tests/skybox/px_rgba.fs | 20 +++++++ examples/tests/skybox/px_tex.fs | 22 ++++++++ examples/tests/skybox/px_tex_rgba.fs | 24 ++++++++ examples/tests/skybox/skyboxTest.js | 83 ++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+) create mode 100644 examples/tests/skybox/px.fs create mode 100644 examples/tests/skybox/px_rgba.fs create mode 100644 examples/tests/skybox/px_tex.fs create mode 100644 examples/tests/skybox/px_tex_rgba.fs create mode 100644 examples/tests/skybox/skyboxTest.js diff --git a/examples/tests/skybox/px.fs b/examples/tests/skybox/px.fs new file mode 100644 index 0000000000..8b6bdc0e5c --- /dev/null +++ b/examples/tests/skybox/px.fs @@ -0,0 +1,18 @@ +// +// px.fs +// examples/tests/skybox +// +// Created by Zach Pomerantz on 3/10/2016 +// 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 + + +vec3 getSkyboxColor() { + float red = (cos(iGlobalTime) + 1) / 2; + vec3 color = vec3(red, 1.0, 1.0); + + return color; +} + diff --git a/examples/tests/skybox/px_rgba.fs b/examples/tests/skybox/px_rgba.fs new file mode 100644 index 0000000000..59bac7d963 --- /dev/null +++ b/examples/tests/skybox/px_rgba.fs @@ -0,0 +1,20 @@ +// +// px_rgba.fs +// examples/tests/skybox +// +// Created by Zach Pomerantz on 3/10/2016 +// 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 + + +vec3 getSkyboxColor() { + float red = (cos(iGlobalTime) + 1) / 2; + vec3 color = vec3(red, 1.0, 1.0); + + color *= skybox.color.rgb; + + return color; +} + diff --git a/examples/tests/skybox/px_tex.fs b/examples/tests/skybox/px_tex.fs new file mode 100644 index 0000000000..9d9da7ba10 --- /dev/null +++ b/examples/tests/skybox/px_tex.fs @@ -0,0 +1,22 @@ +// +// px_rgba.fs +// examples/tests/skybox +// +// Created by Zach Pomerantz on 3/10/2016 +// 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 + + +vec3 getSkyboxColor() { + float red = (cos(iGlobalTime) + 1) / 2; + vec3 color = vec3(red, 1.0, 1.0); + + vec3 coord = normalize(_normal); + vec3 texel = texture(cubeMap, coord).rgb; + color *= texel; + + return color; +} + diff --git a/examples/tests/skybox/px_tex_rgba.fs b/examples/tests/skybox/px_tex_rgba.fs new file mode 100644 index 0000000000..d44a32e33e --- /dev/null +++ b/examples/tests/skybox/px_tex_rgba.fs @@ -0,0 +1,24 @@ +// +// px_rgba.fs +// examples/tests/skybox +// +// Created by Zach Pomerantz on 3/10/2016 +// 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 + + +vec3 getSkyboxColor() { + float red = (cos(iGlobalTime) + 1) / 2; + vec3 color = vec3(red, 1.0, 1.0); + + vec3 coord = normalize(_normal); + vec3 texel = texture(cubeMap, coord).rgb; + color *= texel; + + color *= skybox.color.rgb; + + return color; +} + diff --git a/examples/tests/skybox/skyboxTest.js b/examples/tests/skybox/skyboxTest.js new file mode 100644 index 0000000000..76d80ab153 --- /dev/null +++ b/examples/tests/skybox/skyboxTest.js @@ -0,0 +1,83 @@ +// skyboxTest.js +// examples/tests/skybox +// +// Created by Zach Pomerantz on 3/10/2016. +// Copyright 2016 High Fidelity, Inc. +// +// This test cycles through different variations on the skybox with a mouseclick. +// For the test to pass, you should observe the following cycle: +// - Procedural skybox (no texture, no color) +// - Procedural skybox (no texture, with color) +// - Procedural skybox (with texture, no color) +// - Procedural skybox (with texture, with color) +// - Color skybox (no texture) +// - Color skybox (with texture) +// - Texture skybox (no color) +// +// As you run the test, descriptions of the expected rendered skybox will appear as overlays. +// +// NOTE: This does not test uniforms/textures applied to a procedural shader through userData. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +var PX_URL = Script.resolvePath('px.fs'); +var PX_RGBA_URL = Script.resolvePath('px_rgba.fs'); +var PX_TEX_URL = Script.resolvePath('px_tex.fs'); +var PX_TEX_RGBA_URL = Script.resolvePath('px_tex_rgba.fs'); + +var TEX_URL = 'https://hifi-public.s3.amazonaws.com/alan/Playa/Skies/Test-Sky_out.png'; +var NO_TEX = ''; + +var COLOR = { red: 255, green: 0, blue: 255 }; +var NO_COLOR = { red: 0, green: 0, blue: 0 }; + +var data = { ProceduralEntity: { shaderUrl: PX_URL } }; + +var zone = Entities.addEntity({ + type: 'Zone', + dimensions: { x: 50, y: 50, z: 50 }, + position: MyAvatar.position, + backgroundMode: 'skybox' +}); +var text = Overlays.addOverlay('text', { + text: 'Click this box to advance tests; note that red value cycling means white->light blue', + x: Window.innerWidth / 2 - 250, y: Window.innerHeight / 2 - 25, + width: 500, height: 50 +}); + +print('Zone:', zone); +print('Text:', text); + +var edits = [ + ['Red value should cycle', getEdit(PX_URL, NO_TEX, NO_COLOR)], + ['Red value should cycle, no green', getEdit(PX_RGBA_URL, NO_TEX, COLOR)], + ['Red value should cycle, each face tinted differently', getEdit(PX_TEX_URL, TEX_URL, NO_COLOR)], + ['Red value should cycle, each face tinted differently, no green', getEdit(PX_TEX_RGBA_URL, TEX_URL, COLOR)], + ['No green', getEdit(null, NO_TEX, COLOR)], + ['Each face colored differently, no green', getEdit(null, TEX_URL, COLOR)], + ['Each face colored differently', getEdit(null, TEX_URL, NO_COLOR)], +]; + +Controller.mousePressEvent.connect(function(e) { if (Overlays.getOverlayAtPoint(e) === text) next(); }); + +Script.scriptEnding.connect(function() { + Overlays.deleteOverlay(text); + Entities.deleteEntity(zone); +}); + +var i = 0; +function next() { + var edit = edits[i]; + Overlays.editOverlay(text, { text: edit[0] }); + Entities.editEntity(zone, edit[1]); + i++; + i %= edits.length; +} + +function getEdit(px, url, color) { + return { userData: px ? getUserData(px) : '', backgroundMode: 'skybox', skybox: { url: url, color: color } } +} +function getUserData(px) { return JSON.stringify({ ProceduralEntity: { shaderUrl: px } }); } + From 4dad797e2044304208fff625179118ab04621b7e Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 22:52:44 -0800 Subject: [PATCH 07/10] Only add buffer/tex to skymap if asked for --- libraries/model/src/model/Skybox.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libraries/model/src/model/Skybox.cpp b/libraries/model/src/model/Skybox.cpp index aff4361338..cb3fb43630 100755 --- a/libraries/model/src/model/Skybox.cpp +++ b/libraries/model/src/model/Skybox.cpp @@ -50,12 +50,16 @@ void Skybox::updateSchemaBuffer() const { } void Skybox::prepare(gpu::Batch& batch, int textureSlot, int bufferSlot) const { - batch.setUniformBuffer(bufferSlot, _schemaBuffer); + if (bufferSlot > -1) { + batch.setUniformBuffer(bufferSlot, _schemaBuffer); + } - gpu::TexturePointer skymap = getCubemap(); - // FIXME: skymap->isDefined may not be threadsafe - if (skymap && skymap->isDefined()) { - batch.setResourceTexture(textureSlot, skymap); + if (textureSlot > -1) { + gpu::TexturePointer skymap = getCubemap(); + // FIXME: skymap->isDefined may not be threadsafe + if (skymap && skymap->isDefined()) { + batch.setResourceTexture(textureSlot, skymap); + } } } From 27884b26e9091c6ac9b1c14312aab9e4b47633a9 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 22:53:07 -0800 Subject: [PATCH 08/10] Mark px shaders dirty on change --- libraries/procedural/src/procedural/Procedural.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/procedural/src/procedural/Procedural.cpp b/libraries/procedural/src/procedural/Procedural.cpp index 11df332c5c..922d466d42 100644 --- a/libraries/procedural/src/procedural/Procedural.cpp +++ b/libraries/procedural/src/procedural/Procedural.cpp @@ -101,6 +101,7 @@ bool Procedural::parseUrl(const QUrl& shaderUrl) { } _shaderUrl = shaderUrl; + _shaderDirty = true; if (_shaderUrl.isLocalFile()) { _shaderPath = _shaderUrl.toLocalFile(); @@ -230,7 +231,10 @@ void Procedural::prepare(gpu::Batch& batch, const glm::vec3& position, const glm if (replaceIndex != std::string::npos) { fragmentShaderSource.replace(replaceIndex, PROCEDURAL_BLOCK.size(), _shaderSource.toLocal8Bit().data()); } - //qDebug() << "FragmentShader:\n" << fragmentShaderSource.c_str(); + + // Leave this here for debugging + // qDebug() << "FragmentShader:\n" << fragmentShaderSource.c_str(); + _fragmentShader = gpu::Shader::createPixel(fragmentShaderSource); _shader = gpu::Shader::createProgram(_vertexShader, _fragmentShader); From 2508b1412680aedffa7b0deb17d8e34ebe4e2fed Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 22:53:21 -0800 Subject: [PATCH 09/10] Workaround for scribe not scrubbing #else --- libraries/model/src/model/skybox.slf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/model/src/model/skybox.slf b/libraries/model/src/model/skybox.slf index 6eb3cf3963..7b25e36af7 100755 --- a/libraries/model/src/model/skybox.slf +++ b/libraries/model/src/model/skybox.slf @@ -39,6 +39,9 @@ void main(void) { color = pow(color, vec3(2.2)); _fragColor = vec4(color, 0.0); + // FIXME: scribe does not yet scrub out else statements + return; + #else vec3 coord = normalize(_normal); vec3 color = skybox.color.rgb; From 755efd1840ddac2b516706f6fd3943c9951537d1 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Thu, 10 Mar 2016 23:03:03 -0800 Subject: [PATCH 10/10] Update test shaders --- tests/shaders/src/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/tests/shaders/src/main.cpp b/tests/shaders/src/main.cpp index 82c5583f53..2bc957b2d1 100644 --- a/tests/shaders/src/main.cpp +++ b/tests/shaders/src/main.cpp @@ -72,8 +72,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -157,7 +157,7 @@ void QTestWindow::draw() { testShaderBuild(DrawTransformUnitQuad_vert, DrawTextureOpaque_frag); testShaderBuild(DrawTransformUnitQuad_vert, DrawColoredTexture_frag); - testShaderBuild(Skybox_vert, Skybox_frag); + testShaderBuild(skybox_vert, skybox_frag); testShaderBuild(simple_vert, simple_frag); testShaderBuild(simple_vert, simple_textured_frag); testShaderBuild(simple_vert, simple_textured_emisive_frag); @@ -203,8 +203,6 @@ void QTestWindow::draw() { testShaderBuild(overlay3D_vert, overlay3D_frag); - testShaderBuild(Skybox_vert, Skybox_frag); - testShaderBuild(paintStroke_vert,paintStroke_frag); testShaderBuild(polyvox_vert, polyvox_frag);