Merge pull request #6701 from highfidelity/graphics

Graphics merge into Master: Adding Gamma correction, Tone Mapping and Debugging tool
This commit is contained in:
Brad Hefta-Gaub 2015-12-21 13:54:50 -08:00
commit 111a8caa3c
90 changed files with 1685 additions and 1015 deletions

View file

@ -384,10 +384,10 @@ var CHECK_MARK_COLOR = {
y: newY
});
Overlays.editOverlay(this.checkMark, {
y: newY
y: newY + (0.25 * this.thumbSize)
});
Overlays.editOverlay(this.unCheckMark, {
y: newY
y: newY + (0.25 * this.thumbSize)
});
};
@ -399,10 +399,10 @@ var CHECK_MARK_COLOR = {
y: this.y
});
Overlays.editOverlay(this.checkMark, {
y: this.y
y: this.y + (0.25 * this.thumbSize)
});
Overlays.editOverlay(this.unCheckMark, {
y: this.y
y: this.y+ (0.25 * this.thumbSize)
});
};

View file

@ -1,6 +1,7 @@
//
// SunLightExample.js
// examples
// renderEngineDebug.js
// examples/utilities/tools
//
// Sam Gateau
// Copyright 2015 High Fidelity, Inc.
//
@ -10,6 +11,14 @@
Script.include("cookies.js");
var MENU = "Developer>Render>Debug Deferred Buffer";
var ACTIONS = ["Off", "Diffuse", "Alpha", "Specular", "Roughness", "Normal", "Depth", "Lighting", "Custom"];
var SETTINGS_KEY = "EngineDebugScript.DebugMode";
Number.prototype.clamp = function(min, max) {
return Math.min(Math.max(this, min), max);
};
var panel = new Panel(10, 100);
function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, capGetter) {
@ -41,47 +50,74 @@ function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, cap
};
var opaquesCounter = new CounterWidget(panel, "Opaques",
function () { return Scene.getEngineNumFeedOpaqueItems(); },
function () { return Scene.getEngineNumDrawnOpaqueItems(); },
function(value) { Scene.setEngineMaxDrawnOpaqueItems(value); },
function () { return Scene.getEngineMaxDrawnOpaqueItems(); }
function () { return Render.getEngineNumFeedOpaqueItems(); },
function () { return Render.getEngineNumDrawnOpaqueItems(); },
function(value) { Render.setEngineMaxDrawnOpaqueItems(value); },
function () { return Render.getEngineMaxDrawnOpaqueItems(); }
);
var transparentsCounter = new CounterWidget(panel, "Transparents",
function () { return Scene.getEngineNumFeedTransparentItems(); },
function () { return Scene.getEngineNumDrawnTransparentItems(); },
function(value) { Scene.setEngineMaxDrawnTransparentItems(value); },
function () { return Scene.getEngineMaxDrawnTransparentItems(); }
function () { return Render.getEngineNumFeedTransparentItems(); },
function () { return Render.getEngineNumDrawnTransparentItems(); },
function(value) { Render.setEngineMaxDrawnTransparentItems(value); },
function () { return Render.getEngineMaxDrawnTransparentItems(); }
);
var overlaysCounter = new CounterWidget(panel, "Overlays",
function () { return Scene.getEngineNumFeedOverlay3DItems(); },
function () { return Scene.getEngineNumDrawnOverlay3DItems(); },
function(value) { Scene.setEngineMaxDrawnOverlay3DItems(value); },
function () { return Scene.getEngineMaxDrawnOverlay3DItems(); }
function () { return Render.getEngineNumFeedOverlay3DItems(); },
function () { return Render.getEngineNumDrawnOverlay3DItems(); },
function(value) { Render.setEngineMaxDrawnOverlay3DItems(value); },
function () { return Render.getEngineMaxDrawnOverlay3DItems(); }
);
var resizing = false;
var previousMode = Settings.getValue(SETTINGS_KEY, -1);
Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]);
Render.setEngineDeferredDebugMode(previousMode);
Render.setEngineDeferredDebugSize({ x: 0.0, y: -1.0, z: 1.0, w: 1.0 }); // Reset to default size
function setEngineDeferredDebugSize(eventX) {
var scaledX = (2.0 * (eventX / Window.innerWidth) - 1.0).clamp(-1.0, 1.0);
Render.setEngineDeferredDebugSize({ x: scaledX, y: -1.0, z: 1.0, w: 1.0 });
}
function shouldStartResizing(eventX) {
var x = Math.abs(eventX - Window.innerWidth * (1.0 + Render.getEngineDeferredDebugSize().x) / 2.0);
var mode = Render.getEngineDeferredDebugMode();
return mode !== -1 && x < 20;
}
function menuItemEvent(menuItem) {
var index = ACTIONS.indexOf(menuItem);
if (index >= 0) {
Render.setEngineDeferredDebugMode(index - 1);
}
}
// see libraries/render/src/render/Engine.h
var showDisplayStatusFlag = 1;
var showNetworkStatusFlag = 2;
panel.newCheckbox("Display status",
function(value) { Scene.setEngineDisplayItemStatus(value ?
Scene.doEngineDisplayItemStatus() | showDisplayStatusFlag :
Scene.doEngineDisplayItemStatus() & ~showDisplayStatusFlag); },
function() { return (Scene.doEngineDisplayItemStatus() & showDisplayStatusFlag) > 0; },
function(value) { Render.setEngineDisplayItemStatus(value ?
Render.doEngineDisplayItemStatus() | showDisplayStatusFlag :
Render.doEngineDisplayItemStatus() & ~showDisplayStatusFlag); },
function() { return (Render.doEngineDisplayItemStatus() & showDisplayStatusFlag) > 0; },
function(value) { return (value & showDisplayStatusFlag) > 0; }
);
panel.newCheckbox("Network/Physics status",
function(value) { Scene.setEngineDisplayItemStatus(value ?
Scene.doEngineDisplayItemStatus() | showNetworkStatusFlag :
Scene.doEngineDisplayItemStatus() & ~showNetworkStatusFlag); },
function() { return (Scene.doEngineDisplayItemStatus() & showNetworkStatusFlag) > 0; },
function(value) { Render.setEngineDisplayItemStatus(value ?
Render.doEngineDisplayItemStatus() | showNetworkStatusFlag :
Render.doEngineDisplayItemStatus() & ~showNetworkStatusFlag); },
function() { return (Render.doEngineDisplayItemStatus() & showNetworkStatusFlag) > 0; },
function(value) { return (value & showNetworkStatusFlag) > 0; }
);
panel.newSlider("Tone Mapping Exposure", -10, 10,
function (value) { Render.setEngineToneMappingExposure(value); },
function() { return Render.getEngineToneMappingExposure(); },
function (value) { return (value); });
var tickTackPeriod = 500;
function updateCounters() {
@ -91,11 +127,47 @@ function updateCounters() {
}
Script.setInterval(updateCounters, tickTackPeriod);
Controller.mouseMoveEvent.connect(function panelMouseMoveEvent(event) { return panel.mouseMoveEvent(event); });
Controller.mousePressEvent.connect( function panelMousePressEvent(event) { return panel.mousePressEvent(event); });
Controller.mouseReleaseEvent.connect(function(event) { return panel.mouseReleaseEvent(event); });
function mouseMoveEvent(event) {
if (resizing) {
setEngineDeferredDebugSize(event.x);
} else {
panel.mouseMoveEvent(event);
}
}
function mousePressEvent(event) {
if (shouldStartResizing(event.x)) {
resizing = true;
} else {
panel.mousePressEvent(event);
}
}
function mouseReleaseEvent(event) {
if (resizing) {
resizing = false;
} else {
panel.mouseReleaseEvent(event);
}
}
Controller.mouseMoveEvent.connect(mouseMoveEvent);
Controller.mousePressEvent.connect(mousePressEvent);
Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
Menu.menuItemEvent.connect(menuItemEvent);
function scriptEnding() {
panel.destroy();
Menu.removeActionGroup(MENU);
Settings.setValue(SETTINGS_KEY, Render.getEngineDeferredDebugMode());
Render.setEngineDeferredDebugMode(-1);
Render.setEngineDeferredDebugSize({ x: 0.0, y: -1.0, z: 1.0, w: 1.0 }); // Reset to default size
}
Script.scriptEnding.connect(scriptEnding);
// Collapse items
panel.mousePressEvent({ x: panel.x, y: panel.items["Overlays"].y});
panel.mousePressEvent({ x: panel.x, y: panel.items["Transparents"].y});
panel.mousePressEvent({ x: panel.x, y: panel.items["Opaques"].y});

View file

@ -89,6 +89,7 @@
#include <RenderableWebEntityItem.h>
#include <RenderDeferredTask.h>
#include <ResourceCache.h>
#include <RenderScriptingInterface.h>
#include <SceneScriptingInterface.h>
#include <RecordingScriptingInterface.h>
#include <ScriptCache.h>
@ -342,6 +343,7 @@ bool setupEssentials(int& argc, char** argv) {
#endif
DependencyManager::set<DiscoverabilityManager>();
DependencyManager::set<SceneScriptingInterface>();
DependencyManager::set<RenderScriptingInterface>();
DependencyManager::set<OffscreenUi>();
DependencyManager::set<AutoUpdater>();
DependencyManager::set<PathUtils>();
@ -747,9 +749,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
_applicationStateDevice->addInputVariant(QString("ComfortMode"), controller::StateController::ReadLambda([]() -> float {
return (float)Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode);
}));
_applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float {
return (float)qApp->getMyAvatar()->getCharacterController()->onGround();
}));
_applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float {
return (float)qApp->getMyAvatar()->getCharacterController()->onGround();
}));
userInputMapper->registerDevice(_applicationStateDevice);
@ -1202,7 +1204,7 @@ void Application::paintGL() {
if (Menu::getInstance()->isOptionChecked(MenuOption::Mirror)) {
PerformanceTimer perfTimer("Mirror");
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE;
renderRearViewMirror(&renderArgs, _mirrorViewRect);
@ -1458,7 +1460,9 @@ void Application::paintGL() {
{
PROFILE_RANGE(__FUNCTION__ "/compositor");
PerformanceTimer perfTimer("compositor");
auto primaryFbo = finalFramebuffer;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, gpu::GLBackend::getFramebufferID(primaryFbo));
if (displayPlugin->isStereo()) {
QRect currentViewport(QPoint(0, 0), QSize(size.width() / 2, size.height()));
@ -1483,7 +1487,9 @@ void Application::paintGL() {
{
PROFILE_RANGE(__FUNCTION__ "/pluginOutput");
PerformanceTimer perfTimer("pluginOutput");
auto finalTexturePointer = finalFramebuffer->getRenderBuffer(0);
GLuint finalTexture = gpu::GLBackend::getTextureID(finalTexturePointer);
Q_ASSERT(0 != finalTexture);
@ -2611,7 +2617,7 @@ void Application::init() {
_environment.init();
DependencyManager::get<DeferredLightingEffect>()->init(this);
DependencyManager::get<DeferredLightingEffect>()->init();
DependencyManager::get<AvatarManager>()->init();
_myCamera.setMode(CAMERA_MODE_FIRST_PERSON);
@ -3444,7 +3450,7 @@ QImage Application::renderAvatarBillboard(RenderArgs* renderArgs) {
renderArgs->_renderMode = RenderArgs::DEFAULT_RENDER_MODE;
renderRearViewMirror(renderArgs, QRect(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), true);
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
QImage image(BILLBOARD_SIZE, BILLBOARD_SIZE, QImage::Format_ARGB32);
renderArgs->_context->downloadFramebuffer(primaryFbo, glm::ivec4(0, 0, BILLBOARD_SIZE, BILLBOARD_SIZE), image);
@ -3714,34 +3720,22 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
// For now every frame pass the renderContext
{
PerformanceTimer perfTimer("EngineRun");
render::RenderContext renderContext;
auto sceneInterface = DependencyManager::get<SceneScriptingInterface>();
renderContext._cullOpaque = sceneInterface->doEngineCullOpaque();
renderContext._sortOpaque = sceneInterface->doEngineSortOpaque();
renderContext._renderOpaque = sceneInterface->doEngineRenderOpaque();
renderContext._cullTransparent = sceneInterface->doEngineCullTransparent();
renderContext._sortTransparent = sceneInterface->doEngineSortTransparent();
renderContext._renderTransparent = sceneInterface->doEngineRenderTransparent();
renderContext._maxDrawnOpaqueItems = sceneInterface->getEngineMaxDrawnOpaqueItems();
renderContext._maxDrawnTransparentItems = sceneInterface->getEngineMaxDrawnTransparentItems();
renderContext._maxDrawnOverlay3DItems = sceneInterface->getEngineMaxDrawnOverlay3DItems();
renderContext._drawItemStatus = sceneInterface->doEngineDisplayItemStatus();
if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned)) {
renderContext._drawItemStatus |= render::showNetworkStatusFlag;
}
renderContext._drawHitEffect = sceneInterface->doEngineDisplayHitEffect();
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
renderArgs->_shouldRender = LODManager::shouldRender;
renderContext.args = renderArgs;
renderArgs->_viewFrustum = getDisplayViewFrustum();
auto renderInterface = DependencyManager::get<RenderScriptingInterface>();
auto renderItemsConfig = renderInterface->getItemsConfig();
auto renderTone = renderInterface->getTone();
int drawStatus = renderInterface->getDrawStatus();
bool drawHitEffect = renderInterface->getDrawHitEffect();
bool occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
bool antialiasingStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
bool showOwnedStatus = Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned);
render::RenderContext renderContext{renderArgs, renderItemsConfig, renderTone};
renderContext.setOptions(drawStatus, drawHitEffect, occlusionStatus, antialiasingStatus, showOwnedStatus);
_renderEngine->setRenderContext(renderContext);
// Before the deferred pass, let's try to use the render engine
@ -3749,15 +3743,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
_renderEngine->run();
myAvatar->endRenderRun();
auto engineRC = _renderEngine->getRenderContext();
sceneInterface->setEngineFeedOpaqueItems(engineRC->_numFeedOpaqueItems);
sceneInterface->setEngineDrawnOpaqueItems(engineRC->_numDrawnOpaqueItems);
sceneInterface->setEngineFeedTransparentItems(engineRC->_numFeedTransparentItems);
sceneInterface->setEngineDrawnTransparentItems(engineRC->_numDrawnTransparentItems);
sceneInterface->setEngineFeedOverlay3DItems(engineRC->_numFeedOverlay3DItems);
sceneInterface->setEngineDrawnOverlay3DItems(engineRC->_numDrawnOverlay3DItems);
auto engineContext = _renderEngine->getRenderContext();
renderInterface->setItemCounts(engineContext->getItemsConfig());
}
activeRenderingThread = nullptr;
@ -4212,6 +4199,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerFunction("HMD", "getHUDLookAtPosition3D", HMDScriptingInterface::getHUDLookAtPosition3D, 0);
scriptEngine->registerGlobalObject("Scene", DependencyManager::get<SceneScriptingInterface>().data());
scriptEngine->registerGlobalObject("Render", DependencyManager::get<RenderScriptingInterface>().data());
scriptEngine->registerGlobalObject("ScriptDiscoveryService", this->getRunningScriptsWidget());
}

View file

@ -1085,6 +1085,26 @@ void Menu::setGroupingIsVisible(const QString& grouping, bool isVisible) {
QMenuBar::repaint();
}
void Menu::addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected) {
auto menu = addMenu(groupName);
QActionGroup* actionGroup = new QActionGroup(menu);
actionGroup->setExclusive(true);
auto menuScriptingInterface = MenuScriptingInterface::getInstance();
for (auto action : actionList) {
auto item = addCheckableActionToQMenuAndActionHash(menu, action, 0, action == selected,
menuScriptingInterface,
SLOT(menuItemTriggered()));
actionGroup->addAction(item);
}
QMenuBar::repaint();
}
void Menu::removeActionGroup(const QString& groupName) {
removeMenu(groupName);
}
MenuWrapper::MenuWrapper(QMenu* menu) : _realMenu(menu) {
VrMenu::executeOrQueue([=](VrMenu* vrMenu) {

View file

@ -105,6 +105,8 @@ public slots:
void addMenuItem(const MenuItemProperties& properties);
void removeMenuItem(const QString& menuName, const QString& menuitem);
bool menuItemExists(const QString& menuName, const QString& menuitem);
void addActionGroup(const QString& groupName, const QStringList& actionList, const QString& selected = QString());
void removeActionGroup(const QString& groupName);
bool isOptionChecked(const QString& menuOption) const;
void setIsOptionChecked(const QString& menuOption, bool isChecked);

View file

@ -84,6 +84,19 @@ bool MenuScriptingInterface::menuItemExists(const QString& menu, const QString&
return result;
}
void MenuScriptingInterface::addActionGroup(const QString& groupName, const QStringList& actionList,
const QString& selected) {
QMetaObject::invokeMethod(Menu::getInstance(), "addActionGroup",
Q_ARG(const QString&, groupName),
Q_ARG(const QStringList&, actionList),
Q_ARG(const QString&, selected));
}
void MenuScriptingInterface::removeActionGroup(const QString& groupName) {
QMetaObject::invokeMethod(Menu::getInstance(), "removeActionGroup",
Q_ARG(const QString&, groupName));
}
bool MenuScriptingInterface::isOptionChecked(const QString& menuOption) {
bool result;
QMetaObject::invokeMethod(Menu::getInstance(), "isOptionChecked", Qt::BlockingQueuedConnection,

View file

@ -42,6 +42,10 @@ public slots:
void removeMenuItem(const QString& menuName, const QString& menuitem);
bool menuItemExists(const QString& menuName, const QString& menuitem);
void addActionGroup(const QString& groupName, const QStringList& actionList,
const QString& selected = QString());
void removeActionGroup(const QString& groupName);
bool isOptionChecked(const QString& menuOption);
void setIsOptionChecked(const QString& menuOption, bool isChecked);

View file

@ -223,10 +223,10 @@ void RenderableParticleEffectEntityItem::updateRenderItem() {
particleUniforms.radius.middle = getParticleRadius();
particleUniforms.radius.finish = getRadiusFinish();
particleUniforms.radius.spread = getRadiusSpread();
particleUniforms.color.start = toGlm(getColorStart(), getAlphaStart());
particleUniforms.color.middle = toGlm(getXColor(), getAlpha());
particleUniforms.color.finish = toGlm(getColorFinish(), getAlphaFinish());
particleUniforms.color.spread = toGlm(getColorSpread(), getAlphaSpread());
particleUniforms.color.start = glm::vec4(getColorStartRGB(), getAlphaStart());
particleUniforms.color.middle = glm::vec4(getColorRGB(), getAlpha());
particleUniforms.color.finish = glm::vec4(getColorFinishRGB(), getAlphaFinish());
particleUniforms.color.spread = glm::vec4(getColorSpreadRGB(), getAlphaSpread());
particleUniforms.lifespan = getLifespan();
// Build particle primitives

View file

@ -13,8 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
// the interpolated normal
@ -30,7 +30,7 @@ void main(void) {
varTexcoord = inTexCoord0.st;
// pass along the diffuse color
varColor = inColor;
varColor = colorToLinearRGBA(inColor);
// standard transform
TransformCamera cam = getTransformCamera();

View file

@ -9,16 +9,15 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
out vec4 _color;
void main(void) {
// pass along the diffuse color
_color = inColor;
_color = colorToLinearRGBA(inColor);
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();

View file

@ -15,6 +15,8 @@
#include "EntityItem.h"
#include "ColorUtils.h"
class ParticleEffectEntityItem : public EntityItem {
public:
ALLOW_INSTANTIATION // This class can be instantiated
@ -47,6 +49,7 @@ public:
const rgbColor& getColor() const { return _color; }
xColor getXColor() const { xColor color = { _color[RED_INDEX], _color[GREEN_INDEX], _color[BLUE_INDEX] }; return color; }
glm::vec3 getColorRGB() const { return ColorUtils::toLinearVec3(toGlm(getXColor())); }
static const xColor DEFAULT_COLOR;
void setColor(const rgbColor& value) { memcpy(_color, value, sizeof(_color)); }
@ -59,14 +62,17 @@ public:
bool _isColorStartInitialized = false;
void setColorStart(const xColor& colorStart) { _colorStart = colorStart; _isColorStartInitialized = true; }
xColor getColorStart() const { return _isColorStartInitialized ? _colorStart : getXColor(); }
glm::vec3 getColorStartRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorStart)) : getColorRGB(); }
bool _isColorFinishInitialized = false;
void setColorFinish(const xColor& colorFinish) { _colorFinish = colorFinish; _isColorFinishInitialized = true; }
xColor getColorFinish() const { return _isColorFinishInitialized ? _colorFinish : getXColor(); }
glm::vec3 getColorFinishRGB() const { return _isColorStartInitialized ? ColorUtils::toLinearVec3(toGlm(_colorFinish)) : getColorRGB(); }
static const xColor DEFAULT_COLOR_SPREAD;
void setColorSpread(const xColor& colorSpread) { _colorSpread = colorSpread; }
xColor getColorSpread() const { return _colorSpread; }
glm::vec3 getColorSpreadRGB() const { return ColorUtils::toLinearVec3(toGlm(_colorSpread)); }
static const float MAXIMUM_ALPHA;
static const float MINIMUM_ALPHA;

View file

@ -311,6 +311,12 @@ void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport,
_params.push_back(dstViewport.w);
}
void Batch::generateTextureMips(const TexturePointer& texture) {
ADD_COMMAND(generateTextureMips);
_params.push_back(_textures.cache(texture));
}
void Batch::beginQuery(const QueryPointer& query) {
ADD_COMMAND(beginQuery);

View file

@ -211,6 +211,9 @@ public:
// with xy and zw the bounding corners of the rect region.
void blit(const FramebufferPointer& src, const Vec4i& srcRect, const FramebufferPointer& dst, const Vec4i& dstRect);
// Generate the mips for a texture
void generateTextureMips(const TexturePointer& texture);
// Query Section
void beginQuery(const QueryPointer& query);
void endQuery(const QueryPointer& query);
@ -292,6 +295,7 @@ public:
COMMAND_setFramebuffer,
COMMAND_clearFramebuffer,
COMMAND_blit,
COMMAND_generateTextureMips,
COMMAND_beginQuery,
COMMAND_endQuery,

View file

@ -0,0 +1,52 @@
<!
// Color.slh
// libraries/gpu/src
//
// Created by Sam Gateau on 2015/12/18.
// 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
!>
<@if not GPU_COLOR_SLH@>
<@def GPU_COLOR_SLH@>
<!
float colorComponentToLinear(float cs) {
// sRGB to linear conversion
// { cs / 12.92, cs <= 0.04045
// cl = {
// { ((cs + 0.055)/1.055)^2.4, cs > 0.04045
// constants:
// T = 0.04045
// A = 1 / 1.055 = 0.94786729857
// B = 0.055 * A = 0.05213270142
// C = 1 / 12.92 = 0.0773993808
// G = 2.4
const float T = 0.04045;
const float A = 0.947867;
const float B = 0.052132;
const float C = 0.077399;
const float G = 2.4;
if (cs > T) {
return pow((cs * A + B), G);
} else {
return cs * C;
}
}
vec3 colorToLinear(vec3 srgb) {
return vec3(colorComponentToLinear(srgb.x), colorComponentToLinear(srgb.y), colorComponentToLinear(srgb.z));
}
!>
vec3 colorToLinearRGB(vec3 srgb) {
const float GAMMA_22 = 2.2;
return pow(srgb, vec3(GAMMA_22));
}
vec4 colorToLinearRGBA(vec4 srgba) {
return vec4(colorToLinearRGB(srgba.xyz), srgba.w);
}
<@endif@>

View file

@ -160,6 +160,7 @@ enum Semantic {
RGB,
RGBA,
BGRA,
XY,
XYZ,
XYZW,
@ -176,6 +177,8 @@ enum Semantic {
SRGBA,
SBGRA,
R11G11B10,
UNIFORM,
UNIFORM_BUFFER,
SAMPLER,

View file

@ -52,6 +52,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
(&::gpu::GLBackend::do_setFramebuffer),
(&::gpu::GLBackend::do_clearFramebuffer),
(&::gpu::GLBackend::do_blit),
(&::gpu::GLBackend::do_generateTextureMips),
(&::gpu::GLBackend::do_beginQuery),
(&::gpu::GLBackend::do_endQuery),

View file

@ -376,12 +376,16 @@ protected:
// Resource Stage
void do_setResourceTexture(Batch& batch, size_t paramOffset);
// update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s
void releaseResourceTexture(uint32_t slot);
void resetResourceStage();
struct ResourceStageState {
Textures _textures;
int findEmptyTextureSlot() const;
ResourceStageState():
_textures(MAX_NUM_RESOURCE_TEXTURES, nullptr)
{}
@ -432,6 +436,7 @@ protected:
void do_setFramebuffer(Batch& batch, size_t paramOffset);
void do_clearFramebuffer(Batch& batch, size_t paramOffset);
void do_blit(Batch& batch, size_t paramOffset);
void do_generateTextureMips(Batch& batch, size_t paramOffset);
// Synchronize the state cache of this Backend with the actual real state of the GL Context
void syncOutputStateCache();

View file

@ -361,4 +361,4 @@ void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, co
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
(void) CHECK_GL_ERROR();
}
}

View file

@ -231,6 +231,7 @@ void GLBackend::releaseResourceTexture(uint32_t slot) {
}
}
void GLBackend::resetResourceStage() {
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
releaseResourceTexture(i);
@ -268,3 +269,13 @@ void GLBackend::do_setResourceTexture(Batch& batch, size_t paramOffset) {
}
}
int GLBackend::ResourceStageState::findEmptyTextureSlot() const {
// start from the end of the slots, try to find an empty one that can be used
for (auto i = MAX_NUM_RESOURCE_TEXTURES - 1; i > 0; i--) {
if (!_textures[i]) {
return i;
}
}
return -1;
}

View file

@ -224,6 +224,11 @@ public:
case gpu::SRGBA:
texel.internalFormat = GL_SRGB; // standard 2.2 gamma correction color
break;
case gpu::R11G11B10: {
// the type should be float
texel.internalFormat = GL_R11F_G11F_B10F;
break;
}
default:
qCDebug(gpulogging) << "Unknown combination of texel format";
}
@ -240,6 +245,59 @@ public:
break;
case gpu::RGBA:
texel.internalFormat = GL_RGBA;
switch (dstFormat.getType()) {
case gpu::UINT32:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA32UI;
break;
case gpu::INT32:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA32I;
break;
case gpu::FLOAT:
texel.internalFormat = GL_RGBA32F;
break;
case gpu::UINT16:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA16UI;
break;
case gpu::INT16:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA16I;
break;
case gpu::NUINT16:
texel.format = GL_RGBA;
texel.internalFormat = GL_RGBA16;
break;
case gpu::NINT16:
texel.format = GL_RGBA;
texel.internalFormat = GL_RGBA16_SNORM;
break;
case gpu::HALF:
texel.format = GL_RGBA;
texel.internalFormat = GL_RGBA16F;
break;
case gpu::UINT8:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA8UI;
break;
case gpu::INT8:
texel.format = GL_RGBA_INTEGER;
texel.internalFormat = GL_RGBA8I;
break;
case gpu::NUINT8:
texel.format = GL_RGBA;
texel.internalFormat = GL_RGBA8;
break;
case gpu::NINT8:
texel.format = GL_RGBA;
texel.internalFormat = GL_RGBA8_SNORM;
break;
case gpu::NUINT32:
case gpu::NINT32:
case gpu::NUM_TYPES: // quiet compiler
Q_UNREACHABLE();
}
break;
case gpu::SRGB:
texel.internalFormat = GL_SRGB;
@ -347,7 +405,6 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
object->_target = GL_TEXTURE_2D;
syncSampler(texture.getSampler(), texture.getType(), object);
@ -530,3 +587,37 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, GLTextur
glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
}
void GLBackend::do_generateTextureMips(Batch& batch, size_t paramOffset) {
TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint);
if (!resourceTexture) {
return;
}
GLTexture* object = GLBackend::syncGPUObject(*resourceTexture);
if (!object) {
return;
}
// IN 4.1 we still need to find an available slot
auto freeSlot = _resource.findEmptyTextureSlot();
auto bindingSlot = (freeSlot < 0 ? 0 : freeSlot);
glActiveTexture(GL_TEXTURE0 + bindingSlot);
glBindTexture(object->_target, object->_texture);
glGenerateMipmap(object->_target);
if (freeSlot < 0) {
// If had to use slot 0 then restore state
GLTexture* boundObject = GLBackend::syncGPUObject(*_resource._textures[0]);
if (boundObject) {
glBindTexture(boundObject->_target, boundObject->_texture);
}
} else {
// clean up
glBindTexture(object->_target, 0);
}
(void)CHECK_GL_ERROR();
}

View file

@ -23,7 +23,7 @@ Shader::Shader(Type type, const Source& source):
{
}
Shader::Shader(Type type, Pointer& vertex, Pointer& pixel):
Shader::Shader(Type type, const Pointer& vertex, const Pointer& pixel):
_type(type)
{
_shaders.resize(2);
@ -44,7 +44,7 @@ Shader::Pointer Shader::createPixel(const Source& source) {
return Pointer(new Shader(PIXEL, source));
}
Shader::Pointer Shader::createProgram(Pointer& vertexShader, Pointer& pixelShader) {
Shader::Pointer Shader::createProgram(const Pointer& vertexShader, const Pointer& pixelShader) {
if (vertexShader && vertexShader->getType() == VERTEX &&
pixelShader && pixelShader->getType() == PIXEL) {
return Pointer(new Shader(PROGRAM, vertexShader, pixelShader));

View file

@ -111,7 +111,7 @@ public:
static Pointer createVertex(const Source& source);
static Pointer createPixel(const Source& source);
static Pointer createProgram(Pointer& vertexShader, Pointer& pixelShader);
static Pointer createProgram(const Pointer& vertexShader, const Pointer& pixelShader);
~Shader();
@ -157,7 +157,7 @@ public:
protected:
Shader(Type type, const Source& source);
Shader(Type type, Pointer& vertex, Pointer& pixel);
Shader(Type type, const Pointer& vertex, const Pointer& pixel);
Shader(const Shader& shader); // deep copy of the sysmem shader
Shader& operator=(const Shader& shader); // deep copy of the sysmem texture

View file

@ -407,7 +407,7 @@ public:
TexturePointer _texture = TexturePointer(NULL);
uint16 _subresource = 0;
Element _element = Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
Element _element = Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
TextureView() {};

View file

@ -308,10 +308,9 @@ static NetworkMaterial* buildNetworkMaterial(const FBXMaterial& material, const
material._material->setTextureMap(model::MaterialKey::GLOSS_MAP, glossMap);
}
if (!material.emissiveTexture.filename.isEmpty()) {
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), EMISSIVE_TEXTURE, material.emissiveTexture.content);
networkMaterial->emissiveTexture = textureCache->getTexture(textureBaseUrl.resolved(QUrl(material.emissiveTexture.filename)), LIGHTMAP_TEXTURE, material.emissiveTexture.content);
networkMaterial->emissiveTextureName = material.emissiveTexture.name;
//checkForTexcoordLightmap = true;
auto lightmapMap = model::TextureMapPointer(new model::TextureMap());
lightmapMap->setTextureSource(networkMaterial->emissiveTexture->_textureSource);

View file

@ -85,7 +85,7 @@ const gpu::TexturePointer& TextureCache::getPermutationNormalTexture() {
data[i + 2] = ((randvec.z + 1.0f) / 2.0f) * 255.0f;
}
_permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB), 256, 2));
_permutationNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB), 256, 2));
_permutationNormalTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(data), data);
}
return _permutationNormalTexture;
@ -98,7 +98,7 @@ const unsigned char OPAQUE_BLACK[] = { 0x00, 0x00, 0x00, 0xFF };
const gpu::TexturePointer& TextureCache::getWhiteTexture() {
if (!_whiteTexture) {
_whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
_whiteTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
_whiteTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_WHITE);
}
return _whiteTexture;
@ -106,7 +106,7 @@ const gpu::TexturePointer& TextureCache::getWhiteTexture() {
const gpu::TexturePointer& TextureCache::getGrayTexture() {
if (!_grayTexture) {
_grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
_grayTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
_grayTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_WHITE), OPAQUE_GRAY);
}
return _grayTexture;
@ -114,7 +114,7 @@ const gpu::TexturePointer& TextureCache::getGrayTexture() {
const gpu::TexturePointer& TextureCache::getBlueTexture() {
if (!_blueTexture) {
_blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
_blueTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
_blueTexture->assignStoredMip(0, _blueTexture->getTexelFormat(), sizeof(OPAQUE_BLUE), OPAQUE_BLUE);
}
return _blueTexture;
@ -122,7 +122,7 @@ const gpu::TexturePointer& TextureCache::getBlueTexture() {
const gpu::TexturePointer& TextureCache::getBlackTexture() {
if (!_blackTexture) {
_blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA), 1, 1));
_blackTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, 1, 1));
_blackTexture->assignStoredMip(0, _whiteTexture->getTexelFormat(), sizeof(OPAQUE_BLACK), OPAQUE_BLACK);
}
return _blackTexture;
@ -151,11 +151,11 @@ NetworkTexturePointer TextureCache::getTexture(const QUrl& url, TextureType type
/// Returns a texture version of an image file
gpu::TexturePointer TextureCache::getImageTexture(const QString& path) {
QImage image = QImage(path).mirrored(false, true);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB);
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB);
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA);
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA);
}
gpu::TexturePointer texture = gpu::TexturePointer(
gpu::Texture::create2D(formatGPU, image.width(), image.height(),

View file

@ -29,7 +29,7 @@ class NetworkTexture;
typedef QSharedPointer<NetworkTexture> NetworkTexturePointer;
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, CUSTOM_TEXTURE };
enum TextureType { DEFAULT_TEXTURE, NORMAL_TEXTURE, BUMP_TEXTURE, SPECULAR_TEXTURE, EMISSIVE_TEXTURE, CUBE_TEXTURE, LIGHTMAP_TEXTURE, CUSTOM_TEXTURE };
/// Stores cached textures, including render-to-texture targets.
class TextureCache : public ResourceCache, public Dependency {

View file

@ -44,9 +44,9 @@ Material& Material::operator= (const Material& material) {
Material::~Material() {
}
void Material::setDiffuse(const Color& diffuse) {
void Material::setDiffuse(const Color& diffuse, bool isSRGB) {
_key.setDiffuse(glm::any(glm::greaterThan(diffuse, Color(0.0f))));
_schemaBuffer.edit<Schema>()._diffuse = diffuse;
_schemaBuffer.edit<Schema>()._diffuse = (isSRGB ? ColorUtils::toLinearVec3(diffuse) : diffuse);
}
void Material::setMetallic(float metallic) {
@ -54,9 +54,9 @@ void Material::setMetallic(float metallic) {
_schemaBuffer.edit<Schema>()._metallic = glm::vec3(metallic);
}
void Material::setEmissive(const Color& emissive) {
void Material::setEmissive(const Color& emissive, bool isSRGB) {
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
_schemaBuffer.edit<Schema>()._emissive = emissive;
_schemaBuffer.edit<Schema>()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive);
}
void Material::setGloss(float gloss) {

View file

@ -14,7 +14,7 @@
#include <bitset>
#include <map>
#include <glm/glm.hpp>
#include <ColorUtils.h>
#include <gpu/Resource.h>
@ -219,28 +219,31 @@ public:
virtual ~Material();
const MaterialKey& getKey() const { return _key; }
const Color& getEmissive() const { return _schemaBuffer.get<Schema>()._emissive; }
const Color& getDiffuse() const { return _schemaBuffer.get<Schema>()._diffuse; }
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
void setEmissive(const Color& emissive);
void setDiffuse(const Color& diffuse);
void setEmissive(const Color& emissive, bool isSRGB = true);
Color getEmissive(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._emissive) : _schemaBuffer.get<Schema>()._emissive); }
void setDiffuse(const Color& diffuse, bool isSRGB = true);
Color getDiffuse(bool SRGB = true) const { return (SRGB ? ColorUtils::toGamma22Vec3(_schemaBuffer.get<Schema>()._diffuse) : _schemaBuffer.get<Schema>()._diffuse); }
void setMetallic(float metallic);
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
void setGloss(float gloss);
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
void setOpacity(float opacity);
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
// Schema to access the attribute values of the material
class Schema {
public:
Color _diffuse{0.5f};
glm::vec3 _diffuse{ 0.5f };
float _opacity{1.f};
Color _metallic{0.03f};
glm::vec3 _metallic{ 0.03f };
float _gloss{0.1f};
Color _emissive{0.0f};
glm::vec3 _emissive{ 0.0f };
float _spare0{0.0f};
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4

View file

@ -52,8 +52,7 @@ void main(void) {
}
}
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
_fragColor = vec4(pixel, 0.0);
_fragColor = vec4(color, 0.0);
#endif

View file

@ -119,13 +119,13 @@ gpu::Texture* TextureUsage::create2DTextureFromImage(const QImage& srcImage, con
if ((image.width() > 0) && (image.height() > 0)) {
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
@ -156,11 +156,11 @@ gpu::Texture* TextureUsage::createNormalTextureFromNormalImage(const QImage& src
bool isLinearRGB = true;
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
@ -246,11 +246,11 @@ gpu::Texture* TextureUsage::createNormalTextureFromBumpImage(const QImage& srcIm
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
@ -368,11 +368,11 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = false; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
@ -520,3 +520,89 @@ gpu::Texture* TextureUsage::createCubeTextureFromImage(const QImage& srcImage, c
return theTexture;
}
gpu::Texture* TextureUsage::createLightmapTextureFromImage(const QImage& srcImage, const std::string& srcImageName) {
QImage image = srcImage;
int imageArea = image.width() * image.height();
int opaquePixels = 0;
int translucentPixels = 0;
//bool isTransparent = false;
int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0;
const int EIGHT_BIT_MAXIMUM = 255;
QColor averageColor(EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM, EIGHT_BIT_MAXIMUM);
if (!image.hasAlphaChannel()) {
if (image.format() != QImage::Format_RGB888) {
image = image.convertToFormat(QImage::Format_RGB888);
}
// int redTotal = 0, greenTotal = 0, blueTotal = 0;
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
QRgb rgb = image.pixel(x, y);
redTotal += qRed(rgb);
greenTotal += qGreen(rgb);
blueTotal += qBlue(rgb);
}
}
if (imageArea > 0) {
averageColor.setRgb(redTotal / imageArea, greenTotal / imageArea, blueTotal / imageArea);
}
} else {
if (image.format() != QImage::Format_ARGB32) {
image = image.convertToFormat(QImage::Format_ARGB32);
}
// check for translucency/false transparency
// int opaquePixels = 0;
// int translucentPixels = 0;
// int redTotal = 0, greenTotal = 0, blueTotal = 0, alphaTotal = 0;
for (int y = 0; y < image.height(); y++) {
for (int x = 0; x < image.width(); x++) {
QRgb rgb = image.pixel(x, y);
redTotal += qRed(rgb);
greenTotal += qGreen(rgb);
blueTotal += qBlue(rgb);
int alpha = qAlpha(rgb);
alphaTotal += alpha;
if (alpha == EIGHT_BIT_MAXIMUM) {
opaquePixels++;
} else if (alpha != 0) {
translucentPixels++;
}
}
}
if (opaquePixels == imageArea) {
qCDebug(modelLog) << "Image with alpha channel is completely opaque:" << QString(srcImageName.c_str());
image = image.convertToFormat(QImage::Format_RGB888);
}
averageColor = QColor(redTotal / imageArea,
greenTotal / imageArea, blueTotal / imageArea, alphaTotal / imageArea);
//isTransparent = (translucentPixels >= imageArea / 2);
}
gpu::Texture* theTexture = nullptr;
if ((image.width() > 0) && (image.height() > 0)) {
// bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
bool isLinearRGB = true; //(_type == NORMAL_TEXTURE) || (_type == EMISSIVE_TEXTURE);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, (isLinearRGB ? gpu::RGB : gpu::SRGB));
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::RGBA : gpu::SRGBA));
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, (isLinearRGB ? gpu::BGRA : gpu::SBGRA));
}
theTexture = (gpu::Texture::create2D(formatGPU, image.width(), image.height(), gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));
theTexture->assignStoredMip(0, formatMip, image.byteCount(), image.constBits());
theTexture->autoGenerateMips(-1);
}
return theTexture;
}

View file

@ -35,6 +35,8 @@ public:
static gpu::Texture* createNormalTextureFromNormalImage(const QImage& image, const std::string& srcImageName);
static gpu::Texture* createNormalTextureFromBumpImage(const QImage& image, const std::string& srcImageName);
static gpu::Texture* createCubeTextureFromImage(const QImage& image, const std::string& srcImageName);
static gpu::Texture* createLightmapTextureFromImage(const QImage& image, const std::string& srcImageName);
};

View file

@ -35,6 +35,8 @@ void main(void) {
#ifdef PROCEDURAL
vec3 color = getSkyboxColor();
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
color = pow(color, vec3(2.2));
_fragColor = vec4(color, 0.0);
#else
@ -42,8 +44,7 @@ void main(void) {
vec3 coord = normalize(_normal);
vec3 texel = texture(cubeMap, coord).rgb;
vec3 color = texel * _skybox._color.rgb;
vec3 pixel = pow(color, vec3(1.0/2.2)); // manual Gamma correction
_fragColor = vec4(pixel, 0.0);
_fragColor = vec4(color, 0.0);
#endif

View file

@ -175,10 +175,10 @@ const gpu::PipelinePointer& AmbientOcclusion::getBlendPipeline() {
}
void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
@ -201,7 +201,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
// Occlusion step
getOcclusionPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture());
_occlusionBuffer->setRenderBuffer(0, _occlusionTexture);
batch.setFramebuffer(_occlusionBuffer);
@ -276,7 +276,7 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _hBlurTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setFramebuffer(framebufferCache->getDeferredFramebuffer());
// Bind the fourth gpu::Pipeline we need - for blending the primary color buffer with blurred occlusion texture
batch.setPipeline(getBlendPipeline());

View file

@ -93,14 +93,14 @@ const gpu::PipelinePointer& Antialiasing::getBlendPipeline() {
}
void Antialiasing::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
if (renderContext->args->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
if (renderContext->getArgs()->_renderMode == RenderArgs::MIRROR_RENDER_MODE) {
return;
}
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
@ -123,7 +123,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
// FXAA step
getAntialiasingPipeline();
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture());
_antialiasingBuffer->setRenderBuffer(0, _antialiasingTexture);
batch.setFramebuffer(_antialiasingBuffer);
batch.setPipeline(getAntialiasingPipeline());
@ -153,7 +153,7 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
// Blend step
getBlendPipeline();
batch.setResourceTexture(0, _antialiasingTexture);
batch.setFramebuffer(framebufferCache->getPrimaryFramebuffer());
batch.setFramebuffer(framebufferCache->getDeferredFramebuffer());
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);

View file

@ -0,0 +1,214 @@
//
// DebugDeferredBuffer.cpp
// libraries/render-utils/src
//
// Created by Clement on 12/3/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 "DebugDeferredBuffer.h"
#include <QFile>
#include <gpu/Batch.h>
#include <gpu/Context.h>
#include <render/Scene.h>
#include <ViewFrustum.h>
#include "GeometryCache.h"
#include "FramebufferCache.h"
#include "debug_deferred_buffer_vert.h"
#include "debug_deferred_buffer_frag.h"
using namespace render;
enum Slots {
Diffuse = 0,
Normal,
Specular,
Depth,
Lighting
};
static const std::string DEEFAULT_DIFFUSE_SHADER {
"vec4 getFragmentColor() {"
" return vec4(pow(texture(diffuseMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);"
" }"
};
static const std::string DEEFAULT_ALPHA_SHADER {
"vec4 getFragmentColor() {"
" return vec4(vec3(texture(diffuseMap, uv).a), 1.0);"
" }"
};
static const std::string DEEFAULT_SPECULAR_SHADER {
"vec4 getFragmentColor() {"
" return vec4(texture(specularMap, uv).xyz, 1.0);"
" }"
};
static const std::string DEEFAULT_ROUGHNESS_SHADER {
"vec4 getFragmentColor() {"
" return vec4(vec3(texture(specularMap, uv).a), 1.0);"
" }"
};
static const std::string DEEFAULT_NORMAL_SHADER {
"vec4 getFragmentColor() {"
" return vec4(texture(normalMap, uv).xyz, 1.0);"
" }"
};
static const std::string DEEFAULT_DEPTH_SHADER {
"vec4 getFragmentColor() {"
" return vec4(vec3(texture(depthMap, uv).x), 1.0);"
" }"
};
static const std::string DEEFAULT_LIGHTING_SHADER {
"vec4 getFragmentColor() {"
" return vec4(pow(texture(lightingMap, uv).xyz, vec3(1.0 / 2.2)), 1.0);"
" }"
};
static const std::string DEEFAULT_CUSTOM_SHADER {
"vec4 getFragmentColor() {"
" return vec4(1.0, 0.0, 0.0, 1.0);"
" }"
};
static std::string getFileContent(std::string fileName, std::string defaultContent = std::string()) {
QFile customFile(QString::fromStdString(fileName));
if (customFile.open(QIODevice::ReadOnly)) {
return customFile.readAll().toStdString();
}
qWarning() << "DebugDeferredBuffer::getFileContent(): Could not open"
<< QString::fromStdString(fileName);
return defaultContent;
}
#include <QStandardPaths> // TODO REMOVE: Temporary until UI
DebugDeferredBuffer::DebugDeferredBuffer() {
// TODO REMOVE: Temporary until UI
static const auto DESKTOP_PATH = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
static const auto CUSTOM_FILE = DESKTOP_PATH.toStdString() + "/custom.slh";
CustomPipeline pipeline;
pipeline.info = QFileInfo(QString::fromStdString(CUSTOM_FILE));
_customPipelines.emplace(CUSTOM_FILE, pipeline);
}
std::string DebugDeferredBuffer::getShaderSourceCode(Modes mode, std::string customFile) {
switch (mode) {
case DiffuseMode:
return DEEFAULT_DIFFUSE_SHADER;
case AlphaMode:
return DEEFAULT_ALPHA_SHADER;
case SpecularMode:
return DEEFAULT_SPECULAR_SHADER;
case RoughnessMode:
return DEEFAULT_ROUGHNESS_SHADER;
case NormalMode:
return DEEFAULT_NORMAL_SHADER;
case DepthMode:
return DEEFAULT_DEPTH_SHADER;
case LightingMode:
return DEEFAULT_LIGHTING_SHADER;
case CustomMode:
return getFileContent(customFile, DEEFAULT_CUSTOM_SHADER);
}
Q_UNREACHABLE();
return std::string();
}
bool DebugDeferredBuffer::pipelineNeedsUpdate(Modes mode, std::string customFile) const {
if (mode != CustomMode) {
return !_pipelines[mode];
}
auto it = _customPipelines.find(customFile);
if (it != _customPipelines.end() && it->second.pipeline) {
auto& info = it->second.info;
auto lastModified = info.lastModified();
info.refresh();
return lastModified != info.lastModified();
}
return true;
}
const gpu::PipelinePointer& DebugDeferredBuffer::getPipeline(Modes mode, std::string customFile) {
if (pipelineNeedsUpdate(mode, customFile)) {
static const std::string VERTEX_SHADER { debug_deferred_buffer_vert };
static const std::string FRAGMENT_SHADER { debug_deferred_buffer_frag };
static const std::string SOURCE_PLACEHOLDER { "//SOURCE_PLACEHOLDER" };
static const auto SOURCE_PLACEHOLDER_INDEX = FRAGMENT_SHADER.find(SOURCE_PLACEHOLDER);
Q_ASSERT_X(SOURCE_PLACEHOLDER_INDEX != std::string::npos, Q_FUNC_INFO,
"Could not find source placeholder");
auto bakedFragmentShader = FRAGMENT_SHADER;
bakedFragmentShader.replace(SOURCE_PLACEHOLDER_INDEX, SOURCE_PLACEHOLDER.size(),
getShaderSourceCode(mode, customFile));
static const auto vs = gpu::Shader::createVertex(VERTEX_SHADER);
const auto ps = gpu::Shader::createPixel(bakedFragmentShader);
const auto program = gpu::Shader::createProgram(vs, ps);
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding("diffuseMap", Diffuse));
slotBindings.insert(gpu::Shader::Binding("normalMap", Normal));
slotBindings.insert(gpu::Shader::Binding("specularMap", Specular));
slotBindings.insert(gpu::Shader::Binding("depthMap", Depth));
slotBindings.insert(gpu::Shader::Binding("lightingMap", Lighting));
gpu::Shader::makeProgram(*program, slotBindings);
auto pipeline = gpu::Pipeline::create(program, std::make_shared<gpu::State>());
// Good to go add the brand new pipeline
if (mode != CustomMode) {
_pipelines[mode] = pipeline;
} else {
_customPipelines[customFile].pipeline = pipeline;
}
}
if (mode != CustomMode) {
return _pipelines[mode];
} else {
return _customPipelines[customFile].pipeline;
}
}
void DebugDeferredBuffer::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [&](gpu::Batch& batch) {
const auto geometryBuffer = DependencyManager::get<GeometryCache>();
const auto framebufferCache = DependencyManager::get<FramebufferCache>();
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
args->_viewFrustum->evalViewTransform(viewMat);
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
batch.setModelTransform(Transform());
// TODO REMOVE: Temporary until UI
auto first = _customPipelines.begin()->first;
batch.setPipeline(getPipeline(Modes(renderContext->_deferredDebugMode), first));
batch.setResourceTexture(Diffuse, framebufferCache->getDeferredColorTexture());
batch.setResourceTexture(Normal, framebufferCache->getDeferredNormalTexture());
batch.setResourceTexture(Specular, framebufferCache->getDeferredSpecularTexture());
batch.setResourceTexture(Depth, framebufferCache->getPrimaryDepthTexture());
batch.setResourceTexture(Lighting, framebufferCache->getLightingTexture());
const glm::vec4 color(1.0f, 1.0f, 1.0f, 1.0f);
const glm::vec2 bottomLeft(renderContext->_deferredDebugSize.x, renderContext->_deferredDebugSize.y);
const glm::vec2 topRight(renderContext->_deferredDebugSize.z, renderContext->_deferredDebugSize.w);
geometryBuffer->renderQuad(batch, bottomLeft, topRight, color);
});
}

View file

@ -0,0 +1,54 @@
//
// DebugDeferredBuffer.h
// libraries/render-utils/src
//
// Created by Clement on 12/3/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_DebugDeferredBuffer_h
#define hifi_DebugDeferredBuffer_h
#include <QFileInfo>
#include <render/DrawTask.h>
class DebugDeferredBuffer {
public:
using JobModel = render::Job::Model<DebugDeferredBuffer>;
DebugDeferredBuffer();
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
private:
enum Modes : uint8_t {
DiffuseMode = 0,
AlphaMode,
SpecularMode,
RoughnessMode,
NormalMode,
DepthMode,
LightingMode,
CustomMode // Needs to stay last
};
struct CustomPipeline {
gpu::PipelinePointer pipeline;
mutable QFileInfo info;
};
using StandardPipelines = std::array<gpu::PipelinePointer, CustomMode>;
using CustomPipelines = std::unordered_map<std::string, CustomPipeline>;
bool pipelineNeedsUpdate(Modes mode, std::string customFile = std::string()) const;
const gpu::PipelinePointer& getPipeline(Modes mode, std::string customFile = std::string());
std::string getShaderSourceCode(Modes mode, std::string customFile = std::string());
StandardPipelines _pipelines;
CustomPipelines _customPipelines;
};
#endif // hifi_DebugDeferredBuffer_h

View file

@ -24,6 +24,9 @@ uniform sampler2D specularMap;
// the depth texture
uniform sampler2D depthMap;
// the lighting texture
uniform sampler2D lightingMap;
struct DeferredTransform {
mat4 projection;

View file

@ -51,7 +51,7 @@ void packDeferredFragment(vec3 normal, float alpha, vec3 diffuse, vec3 specular,
discard;
}
_fragColor0 = vec4(diffuse.rgb, alpha);
_fragColor0 = vec4(diffuse.rgb, 1.0); // Opaque
_fragColor1 = vec4(bestFitNormal(normal), 1.0);
_fragColor2 = vec4(specular, shininess / 128.0);
}
@ -61,8 +61,7 @@ void packDeferredFragmentLightmap(vec3 normal, float alpha, vec3 diffuse, vec3 s
discard;
}
_fragColor0 = vec4(diffuse.rgb, alpha);
//_fragColor1 = vec4(normal, 0.0) * 0.5 + vec4(0.5, 0.5, 0.5, 1.0);
_fragColor0 = vec4(diffuse.rgb, 0.5);
_fragColor1 = vec4(bestFitNormal(normal), 0.5);
_fragColor2 = vec4(emissive, shininess / 128.0);
}

View file

@ -83,7 +83,7 @@ vec3 evalAmbienGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
return color;
}
@ -106,7 +106,7 @@ vec3 evalAmbienSphereGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
return color;
}
@ -129,7 +129,7 @@ vec3 evalSkyboxGlobalColor(mat4 invViewMat, float shadowAttenuation, vec3 positi
vec4 shading = evalFragShading(fragNormal, -getLightDirection(light), fragEyeDir, specular, gloss);
color += vec3(diffuse + shading.rgb) * shading.w * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
color += vec3(diffuse * shading.w + shading.rgb) * shadowAttenuation * getLightColor(light) * getLightIntensity(light);
return color;
}

View file

@ -23,17 +23,16 @@ vec4 evalPBRShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 sp
// Specular Lighting depends on the half vector and the gloss
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
// float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0);
float specularPower = pow(max(0.0, dot(halfDir, fragNormal)), gloss * 128.0);
specularPower *= (gloss * 128.0 * 0.125 + 0.25);
float shlickPower = (1.0 - dot(fragLightDir,halfDir));
float shlickPower2 = shlickPower * shlickPower;
float shlickPower5 = shlickPower2 * shlickPower2 * shlickPower;
vec3 schlick = specular * (1.0 - shlickPower5) + vec3(shlickPower5);
vec3 reflect = specularPower * schlick;
vec3 fresnel = specular * (1.0 - shlickPower5) + vec3(shlickPower5);
vec3 reflect = specularPower * fresnel * diffuse;
return vec4(reflect, diffuse);
return vec4(reflect, diffuse * (1 - fresnel.x));
}
<@endfunc@>
@ -49,7 +48,7 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
vec3 halfDir = normalize(fragEyeDir + fragLightDir);
float specularPower = pow(facingLight * max(0.0, dot(halfDir, fragNormal)), gloss * 128.0);
vec3 reflect = specularPower * specular;
vec3 reflect = specularPower * specular * diffuse;
return vec4(reflect, diffuse);
}
@ -59,14 +58,9 @@ vec4 evalBlinnShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3
<$declareEvalPBRShading()$>
// Return xyz the specular/reflection component and w the diffuse component
vec4 evalFragShading(vec3 fragNormal, vec3 fragLightDir, vec3 fragEyeDir, vec3 specular, float gloss) {
/*if (gl_FragCoord.x > 1000) {
return evalBlinnShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss);
} else {*/
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss);
//}
return evalPBRShading(fragNormal, fragLightDir, fragEyeDir, specular, gloss);
}
<@endif@>

View file

@ -34,16 +34,8 @@
#include "deferred_light_spot_vert.h"
#include "directional_light_frag.h"
#include "directional_light_shadow_map_frag.h"
#include "directional_light_cascaded_shadow_map_frag.h"
#include "directional_ambient_light_frag.h"
#include "directional_ambient_light_shadow_map_frag.h"
#include "directional_ambient_light_cascaded_shadow_map_frag.h"
#include "directional_skybox_light_frag.h"
#include "directional_skybox_light_shadow_map_frag.h"
#include "directional_skybox_light_cascaded_shadow_map_frag.h"
#include "point_light_frag.h"
#include "spot_light_frag.h"
@ -51,8 +43,6 @@
static const std::string glowIntensityShaderHandle = "glowIntensity";
struct LightLocations {
int shadowDistances;
int shadowScale;
int radius;
int ambientSphere;
int lightBufferUnit;
@ -92,7 +82,7 @@ gpu::PipelinePointer DeferredLightingEffect::getPipeline(SimpleProgramKey config
return pipeline;
}
void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
void DeferredLightingEffect::init() {
auto VS = gpu::Shader::createVertex(std::string(simple_vert));
auto PS = gpu::Shader::createPixel(std::string(simple_textured_frag));
auto PSEmissive = gpu::Shader::createPixel(std::string(simple_textured_emisive_frag));
@ -105,54 +95,23 @@ void DeferredLightingEffect::init(AbstractViewStateInterface* viewState) {
gpu::Shader::makeProgram(*_simpleShader, slotBindings);
gpu::Shader::makeProgram(*_emissiveShader, slotBindings);
_viewState = viewState;
_directionalLightLocations = std::make_shared<LightLocations>();
_directionalLightShadowMapLocations = std::make_shared<LightLocations>();
_directionalLightCascadedShadowMapLocations = std::make_shared<LightLocations>();
_directionalAmbientSphereLightLocations = std::make_shared<LightLocations>();
_directionalAmbientSphereLightShadowMapLocations = std::make_shared<LightLocations>();
_directionalAmbientSphereLightCascadedShadowMapLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightShadowMapLocations = std::make_shared<LightLocations>();
_directionalSkyboxLightCascadedShadowMapLocations = std::make_shared<LightLocations>();
_pointLightLocations = std::make_shared<LightLocations>();
_spotLightLocations = std::make_shared<LightLocations>();
loadLightProgram(deferred_light_vert, directional_light_frag, false, _directionalLight, _directionalLightLocations);
loadLightProgram(deferred_light_vert, directional_light_shadow_map_frag, false, _directionalLightShadowMap,
_directionalLightShadowMapLocations);
loadLightProgram(deferred_light_vert, directional_light_cascaded_shadow_map_frag, false, _directionalLightCascadedShadowMap,
_directionalLightCascadedShadowMapLocations);
loadLightProgram(deferred_light_vert, directional_ambient_light_frag, false, _directionalAmbientSphereLight, _directionalAmbientSphereLightLocations);
loadLightProgram(deferred_light_vert, directional_ambient_light_shadow_map_frag, false, _directionalAmbientSphereLightShadowMap,
_directionalAmbientSphereLightShadowMapLocations);
loadLightProgram(deferred_light_vert, directional_ambient_light_cascaded_shadow_map_frag, false, _directionalAmbientSphereLightCascadedShadowMap,
_directionalAmbientSphereLightCascadedShadowMapLocations);
loadLightProgram(deferred_light_vert, directional_skybox_light_frag, false, _directionalSkyboxLight, _directionalSkyboxLightLocations);
loadLightProgram(deferred_light_vert, directional_skybox_light_shadow_map_frag, false, _directionalSkyboxLightShadowMap,
_directionalSkyboxLightShadowMapLocations);
loadLightProgram(deferred_light_vert, directional_skybox_light_cascaded_shadow_map_frag, false, _directionalSkyboxLightCascadedShadowMap,
_directionalSkyboxLightCascadedShadowMapLocations);
loadLightProgram(deferred_light_limited_vert, point_light_frag, true, _pointLight, _pointLightLocations);
loadLightProgram(deferred_light_spot_vert, spot_light_frag, true, _spotLight, _spotLightLocations);
{
//auto VSFS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
//auto PSBlit = gpu::StandardShaderLib::getDrawTexturePS();
auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS, gpu::StandardShaderLib::getDrawTexturePS);
gpu::Shader::makeProgram(*blitProgram);
auto blitState = std::make_shared<gpu::State>();
blitState->setBlendFunction(true,
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);
blitState->setColorWriteMask(true, true, true, false);
_blitLightBuffer = gpu::Pipeline::create(blitProgram, blitState);
}
// Allocate a global light representing the Global Directional light casting shadow (the sun) and the ambient light
_globalLights.push_back(0);
_allocatedLights.push_back(std::make_shared<model::Light>());
@ -342,11 +301,27 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
void DeferredLightingEffect::prepare(RenderArgs* args) {
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
// Clear Lighting buffer
auto lightingFbo = DependencyManager::get<FramebufferCache>()->getLightingFramebuffer();
batch.setFramebuffer(lightingFbo);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, vec4(vec3(0), 0), true);
// Clear deferred
auto deferredFbo = DependencyManager::get<FramebufferCache>()->getDeferredFramebuffer();
batch.setFramebuffer(deferredFbo);
// Clear Color, Depth and Stencil
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_DEPTH |
gpu::Framebuffer::BUFFER_STENCIL,
vec4(vec3(0), 1), 1.0, 0.0, true);
batch.setFramebuffer(primaryFbo);
// clear the normal and specular buffers
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
const float MAX_SPECULAR_EXPONENT = 128.0f;
@ -354,8 +329,6 @@ void DeferredLightingEffect::prepare(RenderArgs* args) {
});
}
gpu::FramebufferPointer _copyFBO;
void DeferredLightingEffect::render(RenderArgs* args) {
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
@ -375,18 +348,16 @@ void DeferredLightingEffect::render(RenderArgs* args) {
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// binding the first framebuffer
_copyFBO = framebufferCache->getFramebuffer();
batch.setFramebuffer(_copyFBO);
auto lightingFBO = framebufferCache->getLightingFramebuffer();
batch.setFramebuffer(lightingFBO);
// Clearing it
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.clearColorFramebuffer(_copyFBO->getBufferMask(), glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
// BInd the G-Buffer surfaces
batch.setResourceTexture(0, framebufferCache->getPrimaryColorTexture());
batch.setResourceTexture(1, framebufferCache->getPrimaryNormalTexture());
batch.setResourceTexture(2, framebufferCache->getPrimarySpecularTexture());
batch.setResourceTexture(0, framebufferCache->getDeferredColorTexture());
batch.setResourceTexture(1, framebufferCache->getDeferredNormalTexture());
batch.setResourceTexture(2, framebufferCache->getDeferredSpecularTexture());
batch.setResourceTexture(3, framebufferCache->getPrimaryDepthTexture());
// THe main viewport is assumed to be the mono viewport (or the 2 stereo faces side by side within that viewport)
@ -679,42 +650,6 @@ void DeferredLightingEffect::render(RenderArgs* args) {
}
}
void DeferredLightingEffect::copyBack(RenderArgs* args) {
auto framebufferCache = DependencyManager::get<FramebufferCache>();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
// auto destFbo = framebufferCache->getPrimaryFramebuffer();
auto destFbo = framebufferCache->getPrimaryFramebufferDepthColor();
// gpu::Vec4i vp = args->_viewport;
// batch.blit(_copyFBO, vp, framebufferCache->getPrimaryFramebuffer(), vp);
batch.setFramebuffer(destFbo);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
{
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
Transform model;
batch.setPipeline(_blitLightBuffer);
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
batch.setModelTransform(model);
}
batch.setResourceTexture(0, _copyFBO->getRenderBuffer(0));
batch.draw(gpu::TRIANGLE_STRIP, 4);
args->_context->render(batch);
});
framebufferCache->releaseFramebuffer(_copyFBO);
}
void DeferredLightingEffect::setupTransparent(RenderArgs* args, int lightBufferUnit) {
auto globalLight = _allocatedLights[_globalLights.front()];
args->_batch->setUniformBuffer(lightBufferUnit, globalLight->getSchemaBuffer());
@ -731,7 +666,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), 1));
slotBindings.insert(gpu::Shader::Binding(std::string("specularMap"), 2));
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), 3));
slotBindings.insert(gpu::Shader::Binding(std::string("shadowMap"), 4));
slotBindings.insert(gpu::Shader::Binding(std::string("skyboxMap"), 5));
const int LIGHT_GPU_SLOT = 3;
slotBindings.insert(gpu::Shader::Binding(std::string("lightBuffer"), LIGHT_GPU_SLOT));
@ -742,8 +676,6 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
gpu::Shader::makeProgram(*program, slotBindings);
locations->shadowDistances = program->getUniforms().findLocation("shadowDistances");
locations->shadowScale = program->getUniforms().findLocation("shadowScale");
locations->radius = program->getUniforms().findLocation("radius");
locations->ambientSphere = program->getUniforms().findLocation("ambientSphere.L00");
@ -756,6 +688,11 @@ static void loadLightProgram(const char* vertSource, const char* fragSource, boo
locations->deferredTransformBuffer = program->getBuffers().findLocation("deferredTransformBuffer");
auto state = std::make_shared<gpu::State>();
state->setColorWriteMask(true, true, true, false);
// Stencil test all the light passes for objects pixels only, not the background
state->setStencilTest(true, 0xFF, gpu::State::StencilTest(0, 0xFF, gpu::NOT_EQUAL, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP, gpu::State::STENCIL_OP_KEEP));
if (lightVolume) {
state->setCullMode(gpu::State::CULL_BACK);

View file

@ -21,7 +21,6 @@
#include "model/Stage.h"
#include "model/Geometry.h"
class AbstractViewStateInterface;
class RenderArgs;
class SimpleProgramKey;
struct LightLocations;
@ -34,7 +33,7 @@ public:
static const int NORMAL_FITTING_MAP_SLOT = 10;
static const int DEFERRED_TRANSFORM_BUFFER_SLOT = 2;
void init(AbstractViewStateInterface* viewState);
void init();
/// Sets up the state necessary to render static untextured geometry with the simple program.
gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true,
@ -78,7 +77,6 @@ public:
void prepare(RenderArgs* args);
void render(RenderArgs* args);
void copyBack(RenderArgs* args);
void setupTransparent(RenderArgs* args, int lightBufferUnit);
@ -101,29 +99,15 @@ private:
gpu::ShaderPointer _simpleShader;
gpu::ShaderPointer _emissiveShader;
QHash<SimpleProgramKey, gpu::PipelinePointer> _simplePrograms;
gpu::PipelinePointer _blitLightBuffer;
gpu::PipelinePointer _directionalSkyboxLight;
LightLocationsPtr _directionalSkyboxLightLocations;
gpu::PipelinePointer _directionalSkyboxLightShadowMap;
LightLocationsPtr _directionalSkyboxLightShadowMapLocations;
gpu::PipelinePointer _directionalSkyboxLightCascadedShadowMap;
LightLocationsPtr _directionalSkyboxLightCascadedShadowMapLocations;
gpu::PipelinePointer _directionalAmbientSphereLight;
LightLocationsPtr _directionalAmbientSphereLightLocations;
gpu::PipelinePointer _directionalAmbientSphereLightShadowMap;
LightLocationsPtr _directionalAmbientSphereLightShadowMapLocations;
gpu::PipelinePointer _directionalAmbientSphereLightCascadedShadowMap;
LightLocationsPtr _directionalAmbientSphereLightCascadedShadowMapLocations;
gpu::PipelinePointer _directionalLight;
LightLocationsPtr _directionalLightLocations;
gpu::PipelinePointer _directionalLightShadowMap;
LightLocationsPtr _directionalLightShadowMapLocations;
gpu::PipelinePointer _directionalLightCascadedShadowMap;
LightLocationsPtr _directionalLightCascadedShadowMapLocations;
gpu::PipelinePointer _pointLight;
LightLocationsPtr _pointLightLocations;
@ -155,8 +139,6 @@ private:
std::vector<int> _globalLights;
std::vector<int> _pointLights;
std::vector<int> _spotLights;
AbstractViewStateInterface* _viewState;
int _ambientLightMode = 0;
model::AtmospherePointer _atmosphere;

View file

@ -33,61 +33,76 @@ void FramebufferCache::setFrameBufferSize(QSize frameBufferSize) {
//If the size changed, we need to delete our FBOs
if (_frameBufferSize != frameBufferSize) {
_frameBufferSize = frameBufferSize;
_primaryFramebufferFull.reset();
_primaryFramebufferDepthColor.reset();
_primaryFramebuffer.reset();
_primaryDepthTexture.reset();
_primaryColorTexture.reset();
_primaryNormalTexture.reset();
_primarySpecularTexture.reset();
_deferredFramebuffer.reset();
_deferredFramebufferDepthColor.reset();
_deferredColorTexture.reset();
_deferredNormalTexture.reset();
_deferredSpecularTexture.reset();
_selfieFramebuffer.reset();
_cachedFramebuffers.clear();
_lightingTexture.reset();
_lightingFramebuffer.reset();
}
}
void FramebufferCache::createPrimaryFramebuffer() {
_primaryFramebufferFull = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
_primaryFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_deferredFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_deferredFramebufferDepthColor = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto colorFormat = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
auto colorFormat = gpu::Element::COLOR_RGBA_32;
auto width = _frameBufferSize.width();
auto height = _frameBufferSize.height();
auto defaultSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT);
_primaryColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primarySpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_primaryFramebufferFull->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebufferFull->setRenderBuffer(1, _primaryNormalTexture);
_primaryFramebufferFull->setRenderBuffer(2, _primarySpecularTexture);
_primaryFramebuffer->setRenderBuffer(0, _primaryColorTexture);
_primaryFramebufferDepthColor->setRenderBuffer(0, _primaryColorTexture);
_deferredColorTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredNormalTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredSpecularTexture = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width, height, defaultSampler));
_deferredFramebuffer->setRenderBuffer(0, _deferredColorTexture);
_deferredFramebuffer->setRenderBuffer(1, _deferredNormalTexture);
_deferredFramebuffer->setRenderBuffer(2, _deferredSpecularTexture);
_deferredFramebufferDepthColor->setRenderBuffer(0, _deferredColorTexture);
// auto depthFormat = gpu::Element(gpu::SCALAR, gpu::FLOAT, gpu::DEPTH);
auto depthFormat = gpu::Element(gpu::SCALAR, gpu::UINT32, gpu::DEPTH_STENCIL); // Depth24_Stencil8 texel format
_primaryDepthTexture = gpu::TexturePointer(gpu::Texture::create2D(depthFormat, width, height, defaultSampler));
_primaryFramebufferFull->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_primaryFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_deferredFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_deferredFramebufferDepthColor->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
_selfieFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));
_selfieFramebuffer->setRenderBuffer(0, tex);
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
// FIXME: Decide on the proper one, let s stick to R11G11B10 for now
//_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, defaultSampler));
_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::R11G11B10), width, height, defaultSampler));
//_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA), width, height, defaultSampler));
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
_lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
_lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebuffer() {
if (!_primaryFramebufferFull) {
if (!_primaryFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryFramebufferFull;
}
gpu::FramebufferPointer FramebufferCache::getPrimaryFramebufferDepthColor() {
if (!_primaryFramebufferDepthColor) {
createPrimaryFramebuffer();
}
return _primaryFramebufferDepthColor;
return _primaryFramebuffer;
}
gpu::TexturePointer FramebufferCache::getPrimaryDepthTexture() {
@ -104,18 +119,53 @@ gpu::TexturePointer FramebufferCache::getPrimaryColorTexture() {
return _primaryColorTexture;
}
gpu::TexturePointer FramebufferCache::getPrimaryNormalTexture() {
if (!_primaryNormalTexture) {
gpu::FramebufferPointer FramebufferCache::getDeferredFramebuffer() {
if (!_deferredFramebuffer) {
createPrimaryFramebuffer();
}
return _primaryNormalTexture;
return _deferredFramebuffer;
}
gpu::TexturePointer FramebufferCache::getPrimarySpecularTexture() {
if (!_primarySpecularTexture) {
gpu::FramebufferPointer FramebufferCache::getDeferredFramebufferDepthColor() {
if (!_deferredFramebufferDepthColor) {
createPrimaryFramebuffer();
}
return _primarySpecularTexture;
return _deferredFramebufferDepthColor;
}
gpu::TexturePointer FramebufferCache::getDeferredColorTexture() {
if (!_deferredColorTexture) {
createPrimaryFramebuffer();
}
return _deferredColorTexture;
}
gpu::TexturePointer FramebufferCache::getDeferredNormalTexture() {
if (!_deferredNormalTexture) {
createPrimaryFramebuffer();
}
return _deferredNormalTexture;
}
gpu::TexturePointer FramebufferCache::getDeferredSpecularTexture() {
if (!_deferredSpecularTexture) {
createPrimaryFramebuffer();
}
return _deferredSpecularTexture;
}
gpu::FramebufferPointer FramebufferCache::getLightingFramebuffer() {
if (!_lightingFramebuffer) {
createPrimaryFramebuffer();
}
return _lightingFramebuffer;
}
gpu::TexturePointer FramebufferCache::getLightingTexture() {
if (!_lightingTexture) {
createPrimaryFramebuffer();
}
return _lightingTexture;
}
gpu::FramebufferPointer FramebufferCache::getFramebuffer() {

View file

@ -30,12 +30,20 @@ public:
/// Returns a pointer to the primary framebuffer object. This render target includes a depth component, and is
/// used for scene rendering.
gpu::FramebufferPointer getPrimaryFramebuffer();
gpu::FramebufferPointer getPrimaryFramebufferDepthColor();
gpu::TexturePointer getPrimaryDepthTexture();
gpu::TexturePointer getPrimaryColorTexture();
gpu::TexturePointer getPrimaryNormalTexture();
gpu::TexturePointer getPrimarySpecularTexture();
gpu::FramebufferPointer getDeferredFramebuffer();
gpu::FramebufferPointer getDeferredFramebufferDepthColor();
gpu::TexturePointer getDeferredColorTexture();
gpu::TexturePointer getDeferredNormalTexture();
gpu::TexturePointer getDeferredSpecularTexture();
gpu::TexturePointer getLightingTexture();
gpu::FramebufferPointer getLightingFramebuffer();
/// Returns the framebuffer object used to render shadow maps;
gpu::FramebufferPointer getShadowFramebuffer();
@ -56,14 +64,21 @@ private:
void createPrimaryFramebuffer();
gpu::FramebufferPointer _primaryFramebufferFull;
gpu::FramebufferPointer _primaryFramebufferDepthColor;
gpu::FramebufferPointer _primaryFramebuffer;
gpu::TexturePointer _primaryDepthTexture;
gpu::TexturePointer _primaryColorTexture;
gpu::TexturePointer _primaryNormalTexture;
gpu::TexturePointer _primarySpecularTexture;
gpu::FramebufferPointer _deferredFramebuffer;
gpu::FramebufferPointer _deferredFramebufferDepthColor;
gpu::TexturePointer _deferredColorTexture;
gpu::TexturePointer _deferredNormalTexture;
gpu::TexturePointer _deferredSpecularTexture;
gpu::TexturePointer _lightingTexture;
gpu::FramebufferPointer _lightingFramebuffer;
gpu::FramebufferPointer _shadowFramebuffer;
gpu::FramebufferPointer _selfieFramebuffer;

View file

@ -14,6 +14,7 @@
#include <glm/gtc/random.hpp>
#include <DependencyManager.h>
#include <PathUtils.h>
#include <SharedUtil.h>
@ -60,9 +61,9 @@ const gpu::PipelinePointer& HitEffect::getHitEffectPipeline() {
}
void HitEffect::run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
glm::mat4 projMat;

View file

@ -9,11 +9,7 @@
#ifndef hifi_hitEffect_h
#define hifi_hitEffect_h
#include <DependencyManager.h>
#include "render/DrawTask.h"
class AbstractViewStateInterface;
class ProgramObject;
#include <render/DrawTask.h>
class HitEffect {
public:
@ -23,7 +19,7 @@ public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<HitEffect> JobModel;
const gpu::PipelinePointer& getHitEffectPipeline();
const gpu::PipelinePointer& getHitEffectPipeline();
private:
gpu::PipelinePointer _hitEffectPipeline;

View file

@ -470,6 +470,9 @@ void ModelMeshPartPayload::render(RenderArgs* args) const {
ModelRender::pickPrograms(batch, mode, translucentMesh, alphaThreshold, hasLightmap, hasTangents, hasSpecular, isSkinned, wireframe,
args, locations);
if (!locations) { // the pipeline could not be found
return;
}
// Bind the model transform and the skinCLusterMatrices if needed
bindTransform(batch, locations);

View file

@ -18,10 +18,11 @@
#include <gpu/Context.h>
#include <gpu/StandardShaderLib.h>
#include "FramebufferCache.h"
#include "DebugDeferredBuffer.h"
#include "DeferredLightingEffect.h"
#include "TextureCache.h"
#include "FramebufferCache.h"
#include "HitEffect.h"
#include "TextureCache.h"
#include "render/DrawStatus.h"
#include "AmbientOcclusionEffect.h"
@ -34,92 +35,91 @@
using namespace render;
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
RenderArgs* args = renderContext->args;
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
batch.enableStereo(false);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
batch.setFramebuffer(primaryFbo);
batch.clearFramebuffer(
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_DEPTH |
gpu::Framebuffer::BUFFER_STENCIL,
vec4(vec3(0), 1), 1.0, 0.0, true);
});
}
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
DependencyManager::get<DeferredLightingEffect>()->prepare(renderContext->args);
DependencyManager::get<DeferredLightingEffect>()->prepare(renderContext->getArgs());
}
void RenderDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
DependencyManager::get<DeferredLightingEffect>()->render(renderContext->args);
DependencyManager::get<DeferredLightingEffect>()->render(renderContext->getArgs());
}
void ResolveDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer("ResolveDeferred");
DependencyManager::get<DeferredLightingEffect>()->copyBack(renderContext->args);
void ToneMappingDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer("ToneMappingDeferred");
_toneMappingEffect.render(renderContext->getArgs());
}
RenderDeferredTask::RenderDeferredTask() : Task() {
_jobs.push_back(Job(new SetupDeferred::JobModel("SetupFramebuffer")));
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
// CPU only, create the list of renderedOpaques items
_jobs.push_back(Job(new FetchItems::JobModel("FetchOpaque",
FetchItems(
[] (const RenderContextPointer& context, int count) {
context->_numFeedOpaqueItems = count;
}
)
FetchItems([](const RenderContextPointer& context, int count) {
context->getItemsConfig().opaque.numFeed = count;
})
)));
_jobs.push_back(Job(new CullItemsOpaque::JobModel("CullOpaque", _jobs.back().getOutput())));
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortOpaque", _jobs.back().getOutput())));
auto& renderedOpaques = _jobs.back().getOutput();
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", _jobs.back().getOutput())));
// CPU only, create the list of renderedTransparents items
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
FetchItems(ItemFilter::Builder::transparentShape().withoutLayered(),
[](const RenderContextPointer& context, int count) {
context->getItemsConfig().transparent.numFeed = count;
})
)));
_jobs.push_back(Job(new CullItemsTransparent::JobModel("CullTransparent", _jobs.back().getOutput())));
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false))));
auto& renderedTransparents = _jobs.back().getOutput();
// GPU Jobs: Start preparing the deferred and lighting buffer
_jobs.push_back(Job(new PrepareDeferred::JobModel("PrepareDeferred")));
// Render opaque objects in DeferredBuffer
_jobs.push_back(Job(new DrawOpaqueDeferred::JobModel("DrawOpaqueDeferred", renderedOpaques)));
// Once opaque is all rendered create stencil background
_jobs.push_back(Job(new DrawStencilDeferred::JobModel("DrawOpaqueStencil")));
// Use Stencil and start drawing background in Lighting buffer
_jobs.push_back(Job(new DrawBackgroundDeferred::JobModel("DrawBackgroundDeferred")));
// Draw Lights just add the lights to the current list of lights to deal with. NOt really gpu job for now.
_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")));
// DeferredBuffer is complete, now let's shade it into the LightingBuffer
_jobs.push_back(Job(new RenderDeferred::JobModel("RenderDeferred")));
// AO job, to be revisited
_jobs.push_back(Job(new AmbientOcclusion::JobModel("AmbientOcclusion")));
_jobs.back().setEnabled(false);
_occlusionJobIndex = (int)_jobs.size() - 1;
// AA job to be revisited
_jobs.push_back(Job(new Antialiasing::JobModel("Antialiasing")));
_jobs.back().setEnabled(false);
_antialiasingJobIndex = (int)_jobs.size() - 1;
_jobs.push_back(Job(new FetchItems::JobModel("FetchTransparent",
FetchItems(
ItemFilter::Builder::transparentShape().withoutLayered(),
[] (const RenderContextPointer& context, int count) {
context->_numFeedTransparentItems = count;
}
)
)));
_jobs.push_back(Job(new CullItemsTransparent::JobModel("CullTransparent", _jobs.back().getOutput())));
_jobs.push_back(Job(new DepthSortItems::JobModel("DepthSortTransparent", _jobs.back().getOutput(), DepthSortItems(false))));
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", _jobs.back().getOutput())));
// Render transparent objects forward in LigthingBuffer
_jobs.push_back(Job(new DrawTransparentDeferred::JobModel("TransparentDeferred", renderedTransparents)));
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob
auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg";
auto statusIconMap = DependencyManager::get<TextureCache>()->getImageTexture(iconMapPath);
_jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap))));
// Lighting Buffer ready for tone mapping
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
_toneMappingJobIndex = (int)_jobs.size() - 1;
// Debugging Deferred buffer job
_jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer")));
_jobs.back().setEnabled(false);
_drawStatusJobIndex = (int)_jobs.size() - 1;
_drawDebugDeferredBufferIndex = (int)_jobs.size() - 1;
// Status icon rendering job
{
// Grab a texture map representing the different status icons and assign that to the drawStatsuJob
auto iconMapPath = PathUtils::resourcesPath() + "icons/statusIconAtlas.svg";
auto statusIconMap = DependencyManager::get<TextureCache>()->getImageTexture(iconMapPath);
_jobs.push_back(Job(new render::DrawStatus::JobModel("DrawStatus", renderedOpaques, DrawStatus(statusIconMap))));
_jobs.back().setEnabled(false);
_drawStatusJobIndex = (int)_jobs.size() - 1;
}
_jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D")));
@ -127,7 +127,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
_jobs.back().setEnabled(false);
_drawHitEffectJobIndex = (int)_jobs.size() -1;
// Give ourselves 3 frmaes of timer queries
_timerQueries.push_back(std::make_shared<gpu::Query>());
_timerQueries.push_back(std::make_shared<gpu::Query>());
@ -147,23 +146,29 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
// Is it possible that we render without a viewFrustum ?
if (!(renderContext->args && renderContext->args->_viewFrustum)) {
if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) {
return;
}
// Make sure we turn the displayItemStatus on/off
setDrawItemStatus(renderContext->_drawItemStatus);
// Make sure we turn the deferred buffer debug on/off
setDrawDebugDeferredBuffer(renderContext->_deferredDebugMode);
//Make sure we display hit effect on screen, as desired from a script
setDrawHitEffect(renderContext->_drawHitEffect);
// Make sure we turn the displayItemStatus on/off
setDrawItemStatus(renderContext->getDrawStatus());
// Make sure we display hit effect on screen, as desired from a script
setDrawHitEffect(renderContext->getDrawHitEffect());
// TODO: turn on/off AO through menu item
setOcclusionStatus(renderContext->_occlusionStatus);
setOcclusionStatus(renderContext->getOcclusionStatus());
setAntialiasingStatus(renderContext->_fxaaStatus);
setAntialiasingStatus(renderContext->getFxaaStatus());
renderContext->args->_context->syncCache();
setToneMappingExposure(renderContext->getTone().exposure);
setToneMappingToneCurve(renderContext->getTone().toneCurve);
renderContext->getArgs()->_context->syncCache();
for (auto job : _jobs) {
job.run(sceneContext, renderContext);
@ -172,16 +177,17 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
};
void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
renderContext->_numDrawnOpaqueItems = (int)inItems.size();
auto& opaque = renderContext->getItemsConfig().opaque;
opaque.numDrawn = (int)inItems.size();
glm::mat4 projMat;
Transform viewMat;
@ -195,22 +201,23 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
renderItems(sceneContext, renderContext, inItems, opaque.maxDrawn);
args->_batch = nullptr;
});
}
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
renderContext->_numDrawnTransparentItems = (int)inItems.size();
auto& transparent = renderContext->getItemsConfig().transparent;
transparent.numDrawn = (int)inItems.size();
glm::mat4 projMat;
Transform viewMat;
@ -223,7 +230,7 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
renderItems(sceneContext, renderContext, inItems, transparent.maxDrawn);
args->_batch = nullptr;
});
}
@ -246,8 +253,8 @@ const gpu::PipelinePointer& DrawOverlay3D::getOpaquePipeline() {
}
void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
// render backgrounds
auto& scene = sceneContext->_scene;
@ -262,11 +269,12 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
inItems.emplace_back(id);
}
}
renderContext->_numFeedOverlay3DItems = (int)inItems.size();
renderContext->_numDrawnOverlay3DItems = (int)inItems.size();
auto& overlay3D = renderContext->getItemsConfig().overlay3D;
overlay3D.numFeed = (int)inItems.size();
overlay3D.numDrawn = (int)inItems.size();
if (!inItems.empty()) {
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
// Clear the framebuffer without stereo
// Needs to be distinct from the other batch because using the clear call
@ -295,7 +303,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
batch.setPipeline(getOpaquePipeline());
batch.setResourceTexture(0, args->_whiteTexture);
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
renderItems(sceneContext, renderContext, inItems, renderContext->getItemsConfig().overlay3D.maxDrawn);
});
args->_batch = nullptr;
args->_whiteTexture.reset();
@ -324,19 +332,19 @@ const gpu::PipelinePointer& DrawStencilDeferred::getOpaquePipeline() {
}
void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
// from the touched pixel generate the stencil buffer
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
auto primaryFboColorDepthStencil = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
auto deferredFboColorDepthStencil = DependencyManager::get<FramebufferCache>()->getDeferredFramebufferDepthColor();
batch.enableStereo(false);
batch.setFramebuffer(primaryFboColorDepthStencil);
batch.setFramebuffer(deferredFboColorDepthStencil);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
@ -350,8 +358,8 @@ void DrawStencilDeferred::run(const SceneContextPointer& sceneContext, const Ren
}
void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
// render backgrounds
auto& scene = sceneContext->_scene;
@ -363,16 +371,15 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const
for (auto id : items) {
inItems.emplace_back(id);
}
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
auto primaryFboColorDepthStencil = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
auto primaryFboFull = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
auto lightingFBO = DependencyManager::get<FramebufferCache>()->getLightingFramebuffer();
batch.enableSkybox(true);
batch.setFramebuffer(primaryFboColorDepthStencil);
batch.setFramebuffer(lightingFBO);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
@ -387,8 +394,36 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const
renderItems(sceneContext, renderContext, inItems);
batch.setFramebuffer(primaryFboFull);
});
args->_batch = nullptr;
}
void RenderDeferredTask::setToneMappingExposure(float exposure) {
if (_toneMappingJobIndex >= 0) {
_jobs[_toneMappingJobIndex].edit<ToneMappingDeferred>()._toneMappingEffect.setExposure(exposure);
}
}
float RenderDeferredTask::getToneMappingExposure() const {
if (_toneMappingJobIndex >= 0) {
return _jobs[_toneMappingJobIndex].get<ToneMappingDeferred>()._toneMappingEffect.getExposure();
} else {
return 0.0f;
}
}
void RenderDeferredTask::setToneMappingToneCurve(int toneCurve) {
if (_toneMappingJobIndex >= 0) {
_jobs[_toneMappingJobIndex].edit<ToneMappingDeferred>()._toneMappingEffect.setToneCurve((ToneMappingEffect::ToneCurve)toneCurve);
}
}
int RenderDeferredTask::getToneMappingToneCurve() const {
if (_toneMappingJobIndex >= 0) {
return _jobs[_toneMappingJobIndex].get<ToneMappingDeferred>()._toneMappingEffect.getToneCurve();
} else {
return 0.0f;
}
}

View file

@ -16,6 +16,8 @@
#include "gpu/Pipeline.h"
#include "ToneMappingEffect.h"
class SetupDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
@ -38,11 +40,13 @@ public:
typedef render::Job::Model<RenderDeferred> JobModel;
};
class ResolveDeferred {
class ToneMappingDeferred {
public:
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<ResolveDeferred> JobModel;
ToneMappingEffect _toneMappingEffect;
typedef render::Job::Model<ToneMappingDeferred> JobModel;
};
class DrawOpaqueDeferred {
@ -80,9 +84,9 @@ class DrawOverlay3D {
static gpu::PipelinePointer _opaquePipeline; //lazy evaluation hence mutable
public:
static const gpu::PipelinePointer& getOpaquePipeline();
void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
typedef render::Job::Model<DrawOverlay3D> JobModel;
};
@ -93,16 +97,23 @@ public:
~RenderDeferredTask();
render::Jobs _jobs;
int _drawDebugDeferredBufferIndex = -1;
int _drawStatusJobIndex = -1;
int _drawHitEffectJobIndex = -1;
void setDrawDebugDeferredBuffer(int draw) {
if (_drawDebugDeferredBufferIndex >= 0) {
_jobs[_drawDebugDeferredBufferIndex].setEnabled(draw >= 0);
}
}
bool doDrawDebugDeferredBuffer() const { if (_drawDebugDeferredBufferIndex >= 0) { return _jobs[_drawDebugDeferredBufferIndex].isEnabled(); } else { return false; } }
void setDrawItemStatus(int draw) {
if (_drawStatusJobIndex >= 0) {
_jobs[_drawStatusJobIndex].setEnabled(draw > 0);
}
}
bool doDrawItemStatus() const { if (_drawStatusJobIndex >= 0) { return _jobs[_drawStatusJobIndex].isEnabled(); } else { return false; } }
void setDrawHitEffect(bool draw) { if (_drawHitEffectJobIndex >= 0) { _jobs[_drawHitEffectJobIndex].setEnabled(draw); } }
@ -118,6 +129,14 @@ public:
void setAntialiasingStatus(bool draw) { if (_antialiasingJobIndex >= 0) { _jobs[_antialiasingJobIndex].setEnabled(draw); } }
bool doAntialiasingStatus() const { if (_antialiasingJobIndex >= 0) { return _jobs[_antialiasingJobIndex].isEnabled(); } else { return false; } }
int _toneMappingJobIndex = -1;
void setToneMappingExposure(float exposure);
float getToneMappingExposure() const;
void setToneMappingToneCurve(int toneCurve);
int getToneMappingToneCurve() const;
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);

View file

@ -0,0 +1,41 @@
//
// RenderScriptingInterface.cpp
// libraries/render-utils
//
// Created by Zach Pomerantz on 12/16/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 "RenderScriptingInterface.h"
RenderScriptingInterface::RenderScriptingInterface() {};
void RenderScriptingInterface::setEngineToneMappingToneCurve(const QString& toneCurve) {
if (toneCurve == QString("None")) {
_tone.toneCurve = 0;
} else if (toneCurve == QString("Gamma22")) {
_tone.toneCurve = 1;
} else if (toneCurve == QString("Reinhard")) {
_tone.toneCurve = 2;
} else if (toneCurve == QString("Filmic")) {
_tone.toneCurve = 3;
}
}
QString RenderScriptingInterface::getEngineToneMappingToneCurve() const {
switch (_tone.toneCurve) {
case 0:
return QString("None");
case 1:
return QString("Gamma22");
case 2:
return QString("Reinhard");
case 3:
return QString("Filmic");
default:
return QString("Filmic");
};
}

View file

@ -0,0 +1,95 @@
//
// RenderScriptingInterface.h
// libraries/render-utils
//
// Created by Zach Pomerantz on 12/16/15.
// Copyright 2014 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_RenderScriptingInterface_h
#define hifi_RenderScriptingInterface_h
#include <qscriptengine.h> // QObject
#include <DependencyManager.h> // Dependency
#include "render/Engine.h"
class RenderScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
Q_INVOKABLE void setEngineRenderOpaque(bool renderOpaque) { _items.opaque.render = renderOpaque; };
Q_INVOKABLE bool doEngineRenderOpaque() const { return _items.opaque.render; }
Q_INVOKABLE void setEngineRenderTransparent(bool renderTransparent) { _items.transparent.render = renderTransparent; };
Q_INVOKABLE bool doEngineRenderTransparent() const { return _items.transparent.render; }
Q_INVOKABLE void setEngineCullOpaque(bool cullOpaque) { _items.opaque.cull = cullOpaque; };
Q_INVOKABLE bool doEngineCullOpaque() const { return _items.opaque.cull; }
Q_INVOKABLE void setEngineCullTransparent(bool cullTransparent) { _items.transparent.cull = cullTransparent; };
Q_INVOKABLE bool doEngineCullTransparent() const { return _items.transparent.cull; }
Q_INVOKABLE void setEngineSortOpaque(bool sortOpaque) { _items.opaque.sort = sortOpaque; };
Q_INVOKABLE bool doEngineSortOpaque() const { return _items.opaque.sort; }
Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent) { _items.transparent.sort = sortTransparent; };
Q_INVOKABLE bool doEngineSortTransparent() const { return _items.transparent.sort; }
Q_INVOKABLE int getEngineNumDrawnOpaqueItems() { return _items.opaque.numDrawn; }
Q_INVOKABLE int getEngineNumDrawnTransparentItems() { return _items.transparent.numDrawn; }
Q_INVOKABLE int getEngineNumDrawnOverlay3DItems() { return _items.overlay3D.numDrawn; }
Q_INVOKABLE int getEngineNumFeedOpaqueItems() { return _items.opaque.numFeed; }
Q_INVOKABLE int getEngineNumFeedTransparentItems() { return _items.transparent.numFeed; }
Q_INVOKABLE int getEngineNumFeedOverlay3DItems() { return _items.overlay3D.numFeed; }
Q_INVOKABLE void setEngineMaxDrawnOpaqueItems(int count) { _items.opaque.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnOpaqueItems() { return _items.opaque.maxDrawn; }
Q_INVOKABLE void setEngineMaxDrawnTransparentItems(int count) { _items.transparent.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnTransparentItems() { return _items.transparent.maxDrawn; }
Q_INVOKABLE void setEngineMaxDrawnOverlay3DItems(int count) { _items.overlay3D.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnOverlay3DItems() { return _items.overlay3D.maxDrawn; }
Q_INVOKABLE void setEngineDeferredDebugMode(int mode) { _deferredDebugMode = mode; }
Q_INVOKABLE int getEngineDeferredDebugMode() { return _deferredDebugMode; }
Q_INVOKABLE void setEngineDeferredDebugSize(glm::vec4 size) { _deferredDebugSize = size; }
Q_INVOKABLE glm::vec4 getEngineDeferredDebugSize() { return _deferredDebugSize; }
Q_INVOKABLE void setEngineDisplayItemStatus(int display) { _drawStatus = display; }
Q_INVOKABLE int doEngineDisplayItemStatus() { return _drawStatus; }
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
Q_INVOKABLE void setEngineToneMappingExposure(float exposure) { _tone.exposure = exposure; }
Q_INVOKABLE float getEngineToneMappingExposure() const { return _tone.exposure; }
Q_INVOKABLE void setEngineToneMappingToneCurve(const QString& curve);
Q_INVOKABLE QString getEngineToneMappingToneCurve() const;
int getEngineToneMappingToneCurveValue() const { return _tone.toneCurve; }
inline int getDrawStatus() { return _drawStatus; }
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline const render::RenderContext::ItemsConfig& getItemsConfig() { return _items; }
inline const render::RenderContext::Tone& getTone() { return _tone; }
void setItemCounts(const render::RenderContext::ItemsConfig& items) { _items.setCounts(items); };
protected:
RenderScriptingInterface();
~RenderScriptingInterface() {};
render::RenderContext::ItemsConfig _items;
render::RenderContext::Tone _tone;
// Options
int _drawStatus = 0;
bool _drawHitEffect = false;
// Debugging
int _deferredDebugMode = -1;
glm::vec4 _deferredDebugSize { 0.0f, -1.0f, 1.0f, 1.0f };
};
#endif // hifi_RenderScriptingInterface_h

View file

@ -108,5 +108,6 @@ void main (void)
vec3 finalColor = frontColor.rgb + fMiePhase * secondaryFrontColor.rgb;
outFragColor.a = finalColor.b;
outFragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
// outFragColor.rgb = pow(finalColor.rgb, vec3(1.0/2.2));
outFragColor.rgb = finalColor.rgb;
}

View file

@ -0,0 +1,145 @@
//
// ToneMappingEffect.cpp
// libraries/render-utils/src
//
// Created by Sam Gateau on 12/7/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 "ToneMappingEffect.h"
#include <gpu/Context.h>
#include <gpu/StandardShaderLib.h>
#include <RenderArgs.h>
#include "FramebufferCache.h"
ToneMappingEffect::ToneMappingEffect() {
Parameters parameters;
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) &parameters));
}
void ToneMappingEffect::init() {
const char BlitTextureGamma_frag[] = R"SCRIBE(#version 410 core
// Generated on Sat Oct 24 09:34:37 2015
//
// Draw texture 0 fetched at texcoord.xy
//
// Created by Sam Gateau on 6/22/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
//
struct ToneMappingParams {
vec4 _exp_2powExp_s0_s1;
ivec4 _toneCurve_s0_s1_s2;
};
const float INV_GAMMA_22 = 1.0 / 2.2;
const int ToneCurveNone = 0;
const int ToneCurveGamma22 = 1;
const int ToneCurveReinhard = 2;
const int ToneCurveFilmic = 3;
uniform toneMappingParamsBuffer {
ToneMappingParams params;
};
float getTwoPowExposure() {
return params._exp_2powExp_s0_s1.y;
}
int getToneCurve() {
return params._toneCurve_s0_s1_s2.x;
}
uniform sampler2D colorMap;
in vec2 varTexCoord0;
out vec4 outFragColor;
void main(void) {
vec4 fragColorRaw = texture(colorMap, varTexCoord0);
vec3 fragColor = fragColorRaw.xyz;
vec3 srcColor = fragColor * getTwoPowExposure();
int toneCurve = getToneCurve();
vec3 tonedColor = srcColor;
if (toneCurve == ToneCurveFilmic) {
vec3 x = max(vec3(0.0), srcColor-0.004);
tonedColor = (x * (6.2 * x + 0.5)) / (x * (6.2 * x + 1.7) + 0.06);
} else if (toneCurve == ToneCurveReinhard) {
tonedColor = srcColor/(1.0 + srcColor);
tonedColor = pow(tonedColor, vec3(INV_GAMMA_22));
} else if (toneCurve == ToneCurveGamma22) {
tonedColor = pow(srcColor, vec3(INV_GAMMA_22));
} // else None toned = src
outFragColor = vec4(tonedColor, 1.0);
}
)SCRIBE";
auto blitPS = gpu::ShaderPointer(gpu::Shader::createPixel(std::string(BlitTextureGamma_frag)));
auto blitVS = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS));
gpu::Shader::BindingSet slotBindings;
slotBindings.insert(gpu::Shader::Binding(std::string("toneMappingParamsBuffer"), 3));
gpu::Shader::makeProgram(*blitProgram, slotBindings);
auto blitState = std::make_shared<gpu::State>();
blitState->setColorWriteMask(true, true, true, true);
_blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState));
}
void ToneMappingEffect::setExposure(float exposure) {
_parametersBuffer.edit<Parameters>()._exposure = exposure;
_parametersBuffer.edit<Parameters>()._twoPowExposure = pow(2.0, exposure);
}
void ToneMappingEffect::setToneCurve(ToneCurve curve) {
_parametersBuffer.edit<Parameters>()._toneCurve = curve;
}
void ToneMappingEffect::render(RenderArgs* args) {
if (!_blitLightBuffer) {
init();
}
auto framebufferCache = DependencyManager::get<FramebufferCache>();
gpu::doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
QSize framebufferSize = framebufferCache->getFrameBufferSize();
auto lightingBuffer = framebufferCache->getLightingTexture();
auto destFbo = framebufferCache->getPrimaryFramebuffer();
batch.setFramebuffer(destFbo);
// FIXME: Generate the Luminosity map
//batch.generateTextureMips(lightingBuffer);
batch.setViewportTransform(args->_viewport);
batch.setProjectionTransform(glm::mat4());
batch.setViewTransform(Transform());
{
float sMin = args->_viewport.x / (float)framebufferSize.width();
float sWidth = args->_viewport.z / (float)framebufferSize.width();
float tMin = args->_viewport.y / (float)framebufferSize.height();
float tHeight = args->_viewport.w / (float)framebufferSize.height();
Transform model;
batch.setPipeline(_blitLightBuffer);
model.setTranslation(glm::vec3(sMin, tMin, 0.0));
model.setScale(glm::vec3(sWidth, tHeight, 1.0));
batch.setModelTransform(model);
}
batch.setUniformBuffer(3, _parametersBuffer);
batch.setResourceTexture(0, lightingBuffer);
batch.draw(gpu::TRIANGLE_STRIP, 4);
});
}

View file

@ -0,0 +1,64 @@
//
// ToneMappingEffect.h
// libraries/render-utils/src
//
// Created by Sam Gateau on 12/7/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
//
#ifndef hifi_ToneMappingEffect_h
#define hifi_ToneMappingEffect_h
#include <DependencyManager.h>
#include <NumericalConstants.h>
#include <gpu/Resource.h>
#include <gpu/Pipeline.h>
class RenderArgs;
class ToneMappingEffect {
public:
ToneMappingEffect();
virtual ~ToneMappingEffect() {}
void render(RenderArgs* args);
void setExposure(float exposure);
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
// Different tone curve available
enum ToneCurve {
None = 0,
Gamma22,
Reinhard,
Filmic,
};
void setToneCurve(ToneCurve curve);
ToneCurve getToneCurve() const { return (ToneCurve)_parametersBuffer.get<Parameters>()._toneCurve; }
private:
gpu::PipelinePointer _blitLightBuffer;
// Class describing the uniform buffer with all the parameters common to the tone mapping shaders
class Parameters {
public:
float _exposure = 0.0f;
float _twoPowExposure = 1.0f;
glm::vec2 spareA;
int _toneCurve = Filmic;
glm::vec3 spareB;
Parameters() {}
};
typedef gpu::BufferView UniformBufferView;
gpu::BufferView _parametersBuffer;
void init();
};
#endif // hifi_ToneMappingEffect_h

View file

@ -9,16 +9,15 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
out vec4 _color;
void main(void) {
// pass along the diffuse color
_color = inColor.rgba;
_color = colorToLinearRGBA(inColor.rgba);
TransformCamera cam = getTransformCamera();
TransformObject obj = getTransformObject();

View file

@ -0,0 +1,24 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// debug_deferred_buffer.slf
// fragment shader
//
// Created by Clement on 12/3
// 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 DeferredBuffer.slh@>
in vec2 uv;
out vec4 outFragColor;
//SOURCE_PLACEHOLDER
void main(void) {
outFragColor = getFragmentColor();
}

View file

@ -0,0 +1,22 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// debug_deferred_buffer.slv
// vertex shader
//
// Created by Clement on 12/3
// 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@>
out vec2 uv;
void main(void) {
uv = (inPosition.xy + 1.0) * 0.5;
gl_Position = inPosition;
}

View file

@ -27,7 +27,6 @@ void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,

View file

@ -1,57 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Andrzej Kapolka on 9/3/14.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -1,56 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Andrzej Kapolka on 9/3/14.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientSphereGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienSphereGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -1,59 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Andrzej Kapolka on 9/3/14.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -1,58 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Andrzej Kapolka on 9/3/14.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalAmbientGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalAmbienGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -1,59 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Sam Gateau on 5/8/2015.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalSkyboxGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalCascadedShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -1,58 +0,0 @@
<@include gpu/Config.slh@>
<$VERSION_HEADER$>
// Generated on <$_SCRIBE_DATE$>
//
// directional_light.frag
// fragment shader
//
// Created by Sam Gateau on 5/8/2015.
// Copyright 2014 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
//
// Everything about deferred buffer
<@include DeferredBuffer.slh@>
<@include DeferredGlobalLight.slh@>
<$declareEvalLightmappedColor()$>
<$declareEvalSkyboxGlobalColor()$>
// Everything about shadow
<@include Shadow.slh@>
in vec2 _texCoord0;
out vec4 _fragColor;
void main(void) {
DeferredTransform deferredTransform = getDeferredTransform();
DeferredFragment frag = unpackDeferredFragment(deferredTransform, _texCoord0);
// Eval shadow Texcoord and then Attenuation
vec4 shadowTexcoord = evalShadowTexcoord(frag.position);
float shadowAttenuation = evalShadowAttenuation(shadowTexcoord);
// Light mapped or not ?
if ((frag.normalVal.a >= 0.45) && (frag.normalVal.a <= 0.55)) {
vec3 color = evalLightmappedColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.normal,
frag.diffuse,
frag.specularVal.xyz);
_fragColor = vec4(color, 1.0);
} else {
vec3 color = evalSkyboxGlobalColor(
deferredTransform.viewInverse,
shadowAttenuation,
frag.position.xyz,
frag.normal,
frag.diffuse,
frag.specular,
frag.gloss);
_fragColor = vec4(color, frag.normalVal.a);
}
}

View file

@ -20,8 +20,8 @@ in vec2 varQuadPosition;
out vec4 outFragColor;
void main(void) {
vec2 center = vec2(0.0, 0.0);
float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition);
float alpha = mix(0.0, 0.5, pow(distFromCenter,5.));
outFragColor = vec4(1.0, 0.0, 0.0, alpha);
vec2 center = vec2(0.0, 0.0);
float distFromCenter = distance( vec2(0.0, 0.0), varQuadPosition);
float alpha = mix(0.0, 0.5, pow(distFromCenter,5.));
outFragColor = vec4(1.0, 0.0, 0.0, alpha);
}

View file

@ -12,9 +12,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
const int MAX_TEXCOORDS = 2;
@ -27,9 +26,8 @@ out vec3 _color;
out vec2 _texCoord0;
void main(void) {
// pass along the diffuse color
_color = inColor.xyz;
// pass along the diffuse color in linear space
_color = colorToLinearRGB(inColor.xyz);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
const int MAX_TEXCOORDS = 2;
@ -29,7 +28,8 @@ out vec3 _normal;
out vec3 _color;
void main(void) {
_color = inColor.xyz;
// pass along the diffuse color in linear space
_color = colorToLinearRGB(inColor.xyz);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
const int MAX_TEXCOORDS = 2;
@ -30,7 +29,8 @@ out vec3 _tangent;
out vec3 _color;
void main(void) {
_color = inColor.xyz;
// pass along the diffuse color in linear space
_color = colorToLinearRGB(inColor.xyz);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
const int MAX_TEXCOORDS = 2;
@ -30,7 +29,7 @@ out vec3 _color;
void main(void) {
// pass along the diffuse color
_color = inColor.rgb;
_color = colorToLinearRGB(inColor.xyz);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.xy, 0.0, 1.0)).st;

View file

@ -11,9 +11,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
out vec2 varTexcoord;
@ -30,7 +29,7 @@ void main(void) {
varTexcoord = inTexCoord0.xy;
// pass along the color
varColor = inColor;
varColor = colorToLinearRGBA(inColor);
// standard transform
TransformCamera cam = getTransformCamera();

View file

@ -66,7 +66,7 @@ void main(void) {
float radialAttenuation = evalLightAttenuation(light, fragLightDistance);
// Final Lighting color
vec3 fragColor = shading.w * (frag.diffuse + shading.xyz);
vec3 fragColor = (shading.w * frag.diffuse + shading.xyz);
_fragColor = vec4(fragColor * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0);
if (getLightShowContour(light) > 0.0) {

View file

@ -40,6 +40,8 @@ void main(void) {
#ifdef PROCEDURAL_V1
specular = getProceduralColor().rgb;
// Procedural Shaders are expected to be Gamma corrected so let's bring back the RGB in linear space for the rest of the pipeline
specular = pow(specular, vec3(2.2));
emissiveAmount = 1.0;
#else
emissiveAmount = getProceduralColors(diffuse, specular, shininess);

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
uniform bool Instanced = false;
@ -28,7 +27,7 @@ out vec2 _texCoord0;
out vec4 _position;
void main(void) {
_color = inColor.rgb;
_color = colorToLinearRGB(inColor.rgb);
_texCoord0 = inTexCoord0.st;
_position = inPosition;
_modelNormal = inNormal.xyz;

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
<@include Skinning.slh@>
@ -34,7 +33,7 @@ void main(void) {
skinPositionNormal(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, position, interpolatedNormal);
// pass along the diffuse color
_color = inColor.rgb;
_color = colorToLinearRGB(inColor.rgb);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
<@include Skinning.slh@>
@ -36,7 +35,7 @@ void main(void) {
skinPositionNormalTangent(inSkinClusterIndex, inSkinClusterWeight, inPosition, inNormal.xyz, inTangent.xyz, position, interpolatedNormal.xyz, interpolatedTangent.xyz);
// pass along the diffuse color
_color = inColor.rgb;
_color = colorToLinearRGB(inColor.rgb);
// and the texture coordinates
_texCoord0 = (texcoordMatrices[0] * vec4(inTexCoord0.st, 0.0, 1.0)).st;

View file

@ -73,7 +73,7 @@ void main(void) {
float angularAttenuation = evalLightSpotAttenuation(light, cosSpotAngle);
// Final Lighting color
vec3 fragColor = shading.w * (frag.diffuse + shading.xyz);
vec3 fragColor = (shading.w * frag.diffuse + shading.xyz);
_fragColor = vec4(fragColor * angularAttenuation * radialAttenuation * getLightColor(light) * getLightIntensity(light), 0.0);
if (getLightShowContour(light) > 0.0) {

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
out vec3 varPosition;
@ -25,7 +24,7 @@ out vec4 varColor;
void main(void) {
varTexCoord0 = inTexCoord0.st;
varColor = inColor;
varColor = colorToLinearRGBA(inColor);
// standard transform
TransformCamera cam = getTransformCamera();

View file

@ -13,9 +13,8 @@
//
<@include gpu/Inputs.slh@>
<@include gpu/Color.slh@>
<@include gpu/Transform.slh@>
<$declareStandardTransform()$>
// TODO we need to get the viewport resolution and FOV passed to us so we can modify the point size
@ -26,7 +25,7 @@ out vec4 varColor;
out float varSize;
void main(void) {
varColor = inColor.rgba;
varColor = colorToLinearRGBA(inColor);
// standard transform
TransformCamera cam = getTransformCamera();

View file

@ -198,11 +198,11 @@ void Font::read(QIODevice& in) {
image = image.convertToFormat(QImage::Format_RGBA8888);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::UINT8, gpu::RGB);
gpu::Element formatGPU = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB);
gpu::Element formatMip = gpu::Element(gpu::VEC3, gpu::NUINT8, gpu::RGB);
if (image.hasAlphaChannel()) {
formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::BGRA);
formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::BGRA);
}
_texture = gpu::TexturePointer(gpu::Texture::create2D(formatGPU, image.width(), image.height(),
gpu::Sampler(gpu::Sampler::FILTER_MIN_POINT_MAG_LINEAR)));

View file

@ -97,9 +97,9 @@ const gpu::TexturePointer DrawStatus::getStatusIconMap() const {
void DrawStatus::run(const SceneContextPointer& sceneContext,
const RenderContextPointer& renderContext,
const ItemIDsBounds& inItems) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->getArgs();
auto& scene = sceneContext->_scene;
const int NUM_STATUS_VEC4_PER_ITEM = 2;
const int VEC4_LENGTH = 4;
@ -179,7 +179,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
const unsigned int VEC3_ADRESS_OFFSET = 3;
if ((renderContext->_drawItemStatus & showDisplayStatusFlag) > 0) {
if ((renderContext->getDrawStatus() & showDisplayStatusFlag) > 0) {
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);
@ -192,7 +192,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext,
batch.setPipeline(getDrawItemStatusPipeline());
if ((renderContext->_drawItemStatus & showNetworkStatusFlag) > 0) {
if ((renderContext->getDrawStatus() & showNetworkStatusFlag) > 0) {
for (int i = 0; i < nbItems; i++) {
batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i));
batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET);

View file

@ -37,7 +37,7 @@ void DrawSceneTask::run(const SceneContextPointer& sceneContext, const RenderCon
// Is it possible that we render without a viewFrustum ?
if (!(renderContext->args && renderContext->args->_viewFrustum)) {
if (!(renderContext->getArgs() && renderContext->getArgs()->_viewFrustum)) {
return;
}
@ -54,11 +54,11 @@ Job::~Job() {
void render::cullItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
RenderArgs* args = renderContext->args;
auto renderDetails = renderContext->args->_details._item;
RenderArgs* args = renderContext->getArgs();
auto renderDetails = renderContext->getArgs()->_details._item;
renderDetails->_considered += inItems.size();
@ -115,7 +115,7 @@ void CullItems::run(const SceneContextPointer& sceneContext, const RenderContext
outItems.clear();
outItems.reserve(inItems.size());
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
args->_details.pointTo(RenderDetails::OTHER_ITEM);
cullItems(sceneContext, renderContext, inItems, outItems);
}
@ -124,7 +124,7 @@ void CullItemsOpaque::run(const SceneContextPointer& sceneContext, const RenderC
outItems.clear();
outItems.reserve(inItems.size());
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
args->_details.pointTo(RenderDetails::OPAQUE_ITEM);
cullItems(sceneContext, renderContext, inItems, outItems);
}
@ -133,7 +133,7 @@ void CullItemsTransparent::run(const SceneContextPointer& sceneContext, const Re
outItems.clear();
outItems.reserve(inItems.size());
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
args->_details.pointTo(RenderDetails::TRANSLUCENT_ITEM);
cullItems(sceneContext, renderContext, inItems, outItems);
}
@ -163,11 +163,11 @@ struct BackToFrontSort {
};
void render::depthSortItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, bool frontToBack, const ItemIDsBounds& inItems, ItemIDsBounds& outItems) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
// Allocate and simply copy
@ -211,7 +211,7 @@ void DepthSortItems::run(const SceneContextPointer& sceneContext, const RenderCo
void render::renderItems(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems, int maxDrawnItems) {
auto& scene = sceneContext->_scene;
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
// render
if ((maxDrawnItems < 0) || (maxDrawnItems > (int) inItems.size())) {
for (auto itemDetails : inItems) {
@ -236,8 +236,8 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo
}
void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
// render lights
auto& scene = sceneContext->_scene;
@ -253,7 +253,7 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
ItemIDsBounds culledItems;
culledItems.reserve(inItems.size());
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
args->_details.pointTo(RenderDetails::OTHER_ITEM);
cullItems(sceneContext, renderContext, inItems, culledItems);
@ -265,8 +265,8 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
}
void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
assert(renderContext->getArgs());
assert(renderContext->getArgs()->_viewFrustum);
// render backgrounds
auto& scene = sceneContext->_scene;
@ -278,7 +278,7 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
for (auto id : items) {
inItems.emplace_back(id);
}
RenderArgs* args = renderContext->args;
RenderArgs* args = renderContext->getArgs();
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
batch.enableSkybox(true);

View file

@ -84,6 +84,17 @@ public:
const Varying getInput() const { return _concept->getInput(); }
const Varying getOutput() const { return _concept->getOutput(); }
template <class T> T& edit() {
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
assert(theConcept);
return theConcept->_data;
}
template <class T> const T& get() const {
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
assert(theConcept);
return theConcept->_data;
}
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
PerformanceTimer perfTimer(getName().c_str());
PROFILE_RANGE(getName().c_str());

View file

@ -13,6 +13,16 @@
#include "DrawTask.h"
using namespace render;
void RenderContext::setOptions(int drawStatus, bool drawHitEffect, bool occlusion, bool fxaa, bool showOwned) {
_drawStatus = drawStatus;
_occlusionStatus = occlusion;
_fxaaStatus = fxaa;
_drawHitEffect = drawHitEffect;
if (showOwned) {
_drawStatus |= render::showNetworkStatusFlag;
}
};
Engine::Engine() :
_sceneContext(std::make_shared<SceneContext>()),

View file

@ -23,7 +23,7 @@ public:
SceneContext() {}
};
typedef std::shared_ptr<SceneContext> SceneContextPointer;
using SceneContextPointer = std::shared_ptr<SceneContext>;
// see examples/utilities/tools/renderEngineDebug.js
const int showDisplayStatusFlag = 1;
@ -32,38 +32,84 @@ const int showNetworkStatusFlag = 2;
class RenderContext {
public:
RenderArgs* args;
class ItemsConfig {
public:
inline void setCounts(const ItemsConfig& items) {
opaque.setCounts(items.opaque);
transparent.setCounts(items.transparent);
overlay3D.setCounts(items.overlay3D);
};
bool _cullOpaque = true;
bool _sortOpaque = true;
bool _renderOpaque = true;
bool _cullTransparent = true;
bool _sortTransparent = true;
bool _renderTransparent = true;
class Counter {
public:
Counter() {};
Counter(const Counter& counter) {
numFeed = numDrawn = 0;
maxDrawn = counter.maxDrawn;
};
int _numFeedOpaqueItems = 0;
int _numDrawnOpaqueItems = 0;
int _maxDrawnOpaqueItems = -1;
inline void setCounts(const Counter& counter) {
numFeed = counter.numFeed;
numDrawn = counter.numDrawn;
};
int numFeed = 0;
int numDrawn = 0;
int maxDrawn = -1;
};
class State : public Counter {
public:
bool render = true;
bool cull = true;
bool sort = true;
Counter counter{};
};
// TODO: If member count increases, store counters in a map instead of multiple members
State opaque{};
State transparent{};
Counter overlay3D{};
};
class Tone {
public:
int toneCurve = 1; // Means just Gamma 2.2 correction
float exposure = 0.0;
};
int _numFeedTransparentItems = 0;
int _numDrawnTransparentItems = 0;
int _maxDrawnTransparentItems = -1;
RenderContext(RenderArgs* args, ItemsConfig items, Tone tone) : _args{args}, _items{items}, _tone{tone} {};
RenderContext() : RenderContext(nullptr, {}, {}) {};
int _numFeedOverlay3DItems = 0;
int _numDrawnOverlay3DItems = 0;
int _maxDrawnOverlay3DItems = -1;
inline RenderArgs* getArgs() { return _args; }
inline ItemsConfig& getItemsConfig() { return _items; }
inline Tone& getTone() { return _tone; }
inline int getDrawStatus() { return _drawStatus; }
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline bool getOcclusionStatus() { return _occlusionStatus; }
inline bool getFxaaStatus() { return _fxaaStatus; }
void setOptions(int drawStatus, bool drawHitEffect, bool occlusion, bool fxaa, bool showOwned);
int _drawItemStatus = 0;
// Debugging
int _deferredDebugMode = -1;
glm::vec4 _deferredDebugSize { 0.0f, -1.0f, 1.0f, 1.0f };
protected:
RenderArgs* _args;
// Options
int _drawStatus = 0; // bitflag
bool _drawHitEffect = false;
bool _occlusionStatus = false;
bool _fxaaStatus = false;
RenderContext() {}
ItemsConfig _items;
Tone _tone;
};
typedef std::shared_ptr<RenderContext> RenderContextPointer;
// THe base class for a task that runs on the SceneContext
// The base class for a task that runs on the SceneContext
class Task {
public:
Task() {}
@ -76,7 +122,7 @@ protected:
typedef std::shared_ptr<Task> TaskPointer;
typedef std::vector<TaskPointer> Tasks;
// The root of the takss, the Engine, should not be known from the Tasks,
// The root of the tasks, the Engine, should not be known from the Tasks,
// The SceneContext is what navigates from the engine down to the Tasks
class Engine {
public:

View file

@ -1,6 +1,6 @@
//
// SceneScriptingInterface.cpp
// interface/src/scripting
// libraries/script-engine
//
// Created by Sam Gateau on 2/24/15.
// Copyright 2014 High Fidelity, Inc.
@ -11,16 +11,27 @@
#include "SceneScriptingInterface.h"
#include <AddressManager.h>
#include <procedural/ProceduralSkybox.h>
SceneScriptingInterface::SceneScriptingInterface() {
// Let's make sure the sunSkyStage is using a proceduralSKybox
// Let's make sure the sunSkyStage is using a proceduralSkybox
_skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox()));
}
void SceneScriptingInterface::setShouldRenderAvatars(bool shouldRenderAvatars) {
if (shouldRenderAvatars != _shouldRenderAvatars) {
_shouldRenderAvatars = shouldRenderAvatars;
emit shouldRenderAvatarsChanged(_shouldRenderAvatars);
}
}
void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities) {
if (shouldRenderEntities != _shouldRenderEntities) {
_shouldRenderEntities = shouldRenderEntities;
emit shouldRenderEntitiesChanged(_shouldRenderEntities);
}
}
void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) {
_skyStage->setOriginOrientation(orientation);
}
@ -120,50 +131,3 @@ QString SceneScriptingInterface::getBackgroundMode() const {
model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const {
return _skyStage;
}
void SceneScriptingInterface::setShouldRenderAvatars(bool shouldRenderAvatars) {
if (shouldRenderAvatars != _shouldRenderAvatars) {
_shouldRenderAvatars = shouldRenderAvatars;
emit shouldRenderAvatarsChanged(_shouldRenderAvatars);
}
}
void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities) {
if (shouldRenderEntities != _shouldRenderEntities) {
_shouldRenderEntities = shouldRenderEntities;
emit shouldRenderEntitiesChanged(_shouldRenderEntities);
}
}
void SceneScriptingInterface::setEngineRenderOpaque(bool renderOpaque) {
_engineRenderOpaque = renderOpaque;
}
void SceneScriptingInterface::setEngineRenderTransparent(bool renderTransparent) {
_engineRenderTransparent = renderTransparent;
}
void SceneScriptingInterface::setEngineCullOpaque(bool cullOpaque) {
_engineCullOpaque = cullOpaque;
}
void SceneScriptingInterface::setEngineCullTransparent(bool cullTransparent) {
_engineCullTransparent = cullTransparent;
}
void SceneScriptingInterface::setEngineSortOpaque(bool sortOpaque) {
_engineSortOpaque = sortOpaque;
}
void SceneScriptingInterface::setEngineSortTransparent(bool sortTransparent) {
_engineSortOpaque = sortTransparent;
}
void SceneScriptingInterface::clearEngineCounters() {
_numFeedOpaqueItems = 0;
_numDrawnOpaqueItems = 0;
_numFeedTransparentItems = 0;
_numDrawnTransparentItems = 0;
_numFeedOverlay3DItems = 0;
_numDrawnOverlay3DItems = 0;
}

View file

@ -1,6 +1,6 @@
//
// SceneScriptingInterface.h
// interface/src/scripting
// libraries/script-engine
//
// Created by Sam Gateau on 2/24/15.
// Copyright 2014 High Fidelity, Inc.
@ -12,9 +12,8 @@
#ifndef hifi_SceneScriptingInterface_h
#define hifi_SceneScriptingInterface_h
#include <qscriptengine.h>
#include <DependencyManager.h>
#include <qscriptengine.h> // QObject
#include <DependencyManager.h> // Dependency
#include "model/Stage.h"
@ -22,10 +21,16 @@ class SceneScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
Q_PROPERTY(bool shouldRenderAvatars READ shouldRenderAvatars WRITE setShouldRenderAvatars)
Q_PROPERTY(bool shouldRenderEntities READ shouldRenderEntities WRITE setShouldRenderEntities)
public:
Q_INVOKABLE void setShouldRenderAvatars(bool shouldRenderAvatars);
Q_INVOKABLE bool shouldRenderAvatars() const { return _shouldRenderAvatars; }
Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities);
Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; }
Q_INVOKABLE void setStageOrientation(const glm::quat& orientation);
Q_INVOKABLE void setStageLocation(float longitude, float latitude, float altitude);
@ -43,7 +48,6 @@ public:
Q_INVOKABLE void setStageSunModelEnable(bool isEnabled);
Q_INVOKABLE bool isStageSunModelEnabled() const;
Q_INVOKABLE void setKeyLightColor(const glm::vec3& color);
Q_INVOKABLE glm::vec3 getKeyLightColor() const;
Q_INVOKABLE void setKeyLightIntensity(float intensity);
@ -61,92 +65,19 @@ public:
Q_INVOKABLE QString getBackgroundMode() const;
model::SunSkyStagePointer getSkyStage() const;
Q_INVOKABLE void setShouldRenderAvatars(bool shouldRenderAvatars);
Q_INVOKABLE bool shouldRenderAvatars() const { return _shouldRenderAvatars; }
Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities);
Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; }
// Controlling the rendering engine
Q_INVOKABLE void setEngineRenderOpaque(bool renderOpaque);
Q_INVOKABLE bool doEngineRenderOpaque() const { return _engineRenderOpaque; }
Q_INVOKABLE void setEngineRenderTransparent(bool renderTransparent);
Q_INVOKABLE bool doEngineRenderTransparent() const { return _engineRenderTransparent; }
Q_INVOKABLE void setEngineCullOpaque(bool cullOpaque);
Q_INVOKABLE bool doEngineCullOpaque() const { return _engineCullOpaque; }
Q_INVOKABLE void setEngineCullTransparent(bool cullTransparent);
Q_INVOKABLE bool doEngineCullTransparent() const { return _engineCullTransparent; }
Q_INVOKABLE void setEngineSortOpaque(bool sortOpaque);
Q_INVOKABLE bool doEngineSortOpaque() const { return _engineSortOpaque; }
Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent);
Q_INVOKABLE bool doEngineSortTransparent() const { return _engineSortTransparent; }
void clearEngineCounters();
void setEngineDrawnOpaqueItems(int count) { _numDrawnOpaqueItems = count; }
Q_INVOKABLE int getEngineNumDrawnOpaqueItems() { return _numDrawnOpaqueItems; }
void setEngineDrawnTransparentItems(int count) { _numDrawnTransparentItems = count; }
Q_INVOKABLE int getEngineNumDrawnTransparentItems() { return _numDrawnTransparentItems; }
void setEngineDrawnOverlay3DItems(int count) { _numDrawnOverlay3DItems = count; }
Q_INVOKABLE int getEngineNumDrawnOverlay3DItems() { return _numDrawnOverlay3DItems; }
void setEngineFeedOpaqueItems(int count) { _numFeedOpaqueItems = count; }
Q_INVOKABLE int getEngineNumFeedOpaqueItems() { return _numFeedOpaqueItems; }
void setEngineFeedTransparentItems(int count) { _numFeedTransparentItems = count; }
Q_INVOKABLE int getEngineNumFeedTransparentItems() { return _numFeedTransparentItems; }
void setEngineFeedOverlay3DItems(int count) { _numFeedOverlay3DItems = count; }
Q_INVOKABLE int getEngineNumFeedOverlay3DItems() { return _numFeedOverlay3DItems; }
Q_INVOKABLE void setEngineMaxDrawnOpaqueItems(int count) { _maxDrawnOpaqueItems = count; }
Q_INVOKABLE int getEngineMaxDrawnOpaqueItems() { return _maxDrawnOpaqueItems; }
Q_INVOKABLE void setEngineMaxDrawnTransparentItems(int count) { _maxDrawnTransparentItems = count; }
Q_INVOKABLE int getEngineMaxDrawnTransparentItems() { return _maxDrawnTransparentItems; }
Q_INVOKABLE void setEngineMaxDrawnOverlay3DItems(int count) { _maxDrawnOverlay3DItems = count; }
Q_INVOKABLE int getEngineMaxDrawnOverlay3DItems() { return _maxDrawnOverlay3DItems; }
Q_INVOKABLE void setEngineDisplayItemStatus(int display) { _drawItemStatus = display; }
Q_INVOKABLE int doEngineDisplayItemStatus() { return _drawItemStatus; }
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
signals:
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
void shouldRenderEntitiesChanged(bool shouldRenderEntities);
protected:
SceneScriptingInterface();
~SceneScriptingInterface() {};
model::SunSkyStagePointer _skyStage = std::make_shared<model::SunSkyStage>();
bool _shouldRenderAvatars = true;
bool _shouldRenderEntities = true;
bool _engineRenderOpaque = true;
bool _engineRenderTransparent = true;
bool _engineCullOpaque = true;
bool _engineCullTransparent = true;
bool _engineSortOpaque = true;
bool _engineSortTransparent = true;
int _numFeedOpaqueItems = 0;
int _numDrawnOpaqueItems = 0;
int _numFeedTransparentItems = 0;
int _numDrawnTransparentItems = 0;
int _numFeedOverlay3DItems = 0;
int _numDrawnOverlay3DItems = 0;
int _maxDrawnOpaqueItems = -1;
int _maxDrawnTransparentItems = -1;
int _maxDrawnOverlay3DItems = -1;
int _drawItemStatus = 0;
bool _drawHitEffect = false;
};
#endif // hifi_SceneScriptingInterface_h

View file

@ -46,7 +46,6 @@
#include "XMLHttpRequestClass.h"
#include "WebSocketClass.h"
#include "SceneScriptingInterface.h"
#include "RecordingScriptingInterface.h"
#include "MIDIEvent.h"

View file

@ -20,6 +20,10 @@
class ColorUtils {
public:
inline static glm::vec3 toVec3(const xColor& color);
// Convert from gamma 2.2 space to linear
inline static glm::vec3 toLinearVec3(const glm::vec3& srgb);
inline static glm::vec3 toGamma22Vec3(const glm::vec3& linear);
};
inline glm::vec3 ColorUtils::toVec3(const xColor& color) {
@ -27,4 +31,16 @@ inline glm::vec3 ColorUtils::toVec3(const xColor& color) {
return glm::vec3(color.red * ONE_OVER_255, color.green * ONE_OVER_255, color.blue * ONE_OVER_255);
}
inline glm::vec3 ColorUtils::toLinearVec3(const glm::vec3& srgb) {
const float GAMMA_22 = 2.2f;
// Couldn't find glm::pow(vec3, vec3) ? so did it myself...
return glm::vec3(glm::pow(srgb.x, GAMMA_22), glm::pow(srgb.y, GAMMA_22), glm::pow(srgb.z, GAMMA_22));
}
inline glm::vec3 ColorUtils::toGamma22Vec3(const glm::vec3& linear) {
const float INV_GAMMA_22 = 1.0f / 2.2f;
// Couldn't find glm::pow(vec3, vec3) ? so did it myself...
return glm::vec3(glm::pow(linear.x, INV_GAMMA_22), glm::pow(linear.y, INV_GAMMA_22), glm::pow(linear.z, INV_GAMMA_22));
}
#endif // hifi_ColorUtils_h

View file

@ -104,8 +104,8 @@ void ViveControllerManager::activate() {
// sizeof(vr::RenderModel_Vertex_t),
// gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::UINT8, gpu::RGBA);
gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
_texture = gpu::TexturePointer(
gpu::Texture::create2D(formatGPU, model.diffuseTexture.unWidth, model.diffuseTexture.unHeight,
gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR)));

View file

@ -35,16 +35,10 @@
#include "deferred_light_limited_vert.h"
#include "directional_light_frag.h"
#include "directional_light_shadow_map_frag.h"
#include "directional_light_cascaded_shadow_map_frag.h"
#include "directional_ambient_light_frag.h"
#include "directional_ambient_light_shadow_map_frag.h"
#include "directional_ambient_light_cascaded_shadow_map_frag.h"
#include "directional_skybox_light_frag.h"
#include "directional_skybox_light_shadow_map_frag.h"
#include "directional_skybox_light_cascaded_shadow_map_frag.h"
#include "point_light_frag.h"
#include "spot_light_frag.h"
@ -185,14 +179,8 @@ void QTestWindow::draw() {
testShaderBuild(simple_vert, simple_textured_frag);
testShaderBuild(simple_vert, simple_textured_emisive_frag);
testShaderBuild(deferred_light_vert, directional_light_frag);
testShaderBuild(deferred_light_vert, directional_light_shadow_map_frag);
testShaderBuild(deferred_light_vert, directional_light_cascaded_shadow_map_frag);
testShaderBuild(deferred_light_vert, directional_ambient_light_frag);
testShaderBuild(deferred_light_vert, directional_ambient_light_shadow_map_frag);
testShaderBuild(deferred_light_vert, directional_ambient_light_cascaded_shadow_map_frag);
testShaderBuild(deferred_light_vert, directional_skybox_light_frag);
testShaderBuild(deferred_light_vert, directional_skybox_light_shadow_map_frag);
testShaderBuild(deferred_light_vert, directional_skybox_light_cascaded_shadow_map_frag);
testShaderBuild(deferred_light_limited_vert, point_light_frag);
testShaderBuild(deferred_light_limited_vert, spot_light_frag);
testShaderBuild(standardTransformPNTC_vert, standardDrawTexture_frag);