mirror of
https://github.com/lubosz/overte.git
synced 2025-05-28 14:20:58 +02:00
Adding a simple manual exposure control to configure the tonemapping and expose it to js. Add a convenient way to access the Job._concept._data with template
This commit is contained in:
parent
2bbd5d86b8
commit
d2ebaef69e
18 changed files with 165 additions and 12 deletions
|
@ -109,6 +109,11 @@ panel.newCheckbox("Network/Physics status",
|
||||||
function(value) { return (value & showNetworkStatusFlag) > 0; }
|
function(value) { return (value & showNetworkStatusFlag) > 0; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
panel.newSlider("Tone Mapping Exposure", -10, 10,
|
||||||
|
function (value) { Scene.setEngineToneMappingExposure(value); },
|
||||||
|
function() { return Scene.getEngineToneMappingExposure(); },
|
||||||
|
function (value) { return (value); });
|
||||||
|
|
||||||
var tickTackPeriod = 500;
|
var tickTackPeriod = 500;
|
||||||
|
|
||||||
function updateCounters() {
|
function updateCounters() {
|
||||||
|
|
|
@ -3691,6 +3691,8 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
||||||
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
renderContext._occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
|
||||||
renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
|
renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
|
||||||
|
|
||||||
|
renderContext._toneMappingExposure = sceneInterface->getEngineToneMappingExposure();
|
||||||
|
|
||||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||||
|
|
||||||
renderContext.args = renderArgs;
|
renderContext.args = renderArgs;
|
||||||
|
|
|
@ -311,6 +311,12 @@ void Batch::blit(const FramebufferPointer& src, const Vec4i& srcViewport,
|
||||||
_params.push_back(dstViewport.w);
|
_params.push_back(dstViewport.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Batch::generateTextureMipmap(const TexturePointer& texture) {
|
||||||
|
ADD_COMMAND(generateTextureMipmap);
|
||||||
|
|
||||||
|
_params.push_back(_textures.cache(texture));
|
||||||
|
}
|
||||||
|
|
||||||
void Batch::beginQuery(const QueryPointer& query) {
|
void Batch::beginQuery(const QueryPointer& query) {
|
||||||
ADD_COMMAND(beginQuery);
|
ADD_COMMAND(beginQuery);
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,9 @@ public:
|
||||||
// with xy and zw the bounding corners of the rect region.
|
// 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);
|
void blit(const FramebufferPointer& src, const Vec4i& srcRect, const FramebufferPointer& dst, const Vec4i& dstRect);
|
||||||
|
|
||||||
|
// Generate the mipmap for a texture
|
||||||
|
void generateTextureMipmap(const TexturePointer& texture);
|
||||||
|
|
||||||
// Query Section
|
// Query Section
|
||||||
void beginQuery(const QueryPointer& query);
|
void beginQuery(const QueryPointer& query);
|
||||||
void endQuery(const QueryPointer& query);
|
void endQuery(const QueryPointer& query);
|
||||||
|
@ -292,6 +295,7 @@ public:
|
||||||
COMMAND_setFramebuffer,
|
COMMAND_setFramebuffer,
|
||||||
COMMAND_clearFramebuffer,
|
COMMAND_clearFramebuffer,
|
||||||
COMMAND_blit,
|
COMMAND_blit,
|
||||||
|
COMMAND_generateTextureMipmap,
|
||||||
|
|
||||||
COMMAND_beginQuery,
|
COMMAND_beginQuery,
|
||||||
COMMAND_endQuery,
|
COMMAND_endQuery,
|
||||||
|
|
|
@ -52,6 +52,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
||||||
(&::gpu::GLBackend::do_setFramebuffer),
|
(&::gpu::GLBackend::do_setFramebuffer),
|
||||||
(&::gpu::GLBackend::do_clearFramebuffer),
|
(&::gpu::GLBackend::do_clearFramebuffer),
|
||||||
(&::gpu::GLBackend::do_blit),
|
(&::gpu::GLBackend::do_blit),
|
||||||
|
(&::gpu::GLBackend::do_generateTextureMipmap),
|
||||||
|
|
||||||
(&::gpu::GLBackend::do_beginQuery),
|
(&::gpu::GLBackend::do_beginQuery),
|
||||||
(&::gpu::GLBackend::do_endQuery),
|
(&::gpu::GLBackend::do_endQuery),
|
||||||
|
|
|
@ -376,12 +376,16 @@ protected:
|
||||||
|
|
||||||
// Resource Stage
|
// Resource Stage
|
||||||
void do_setResourceTexture(Batch& batch, size_t paramOffset);
|
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 releaseResourceTexture(uint32_t slot);
|
||||||
|
|
||||||
void resetResourceStage();
|
void resetResourceStage();
|
||||||
struct ResourceStageState {
|
struct ResourceStageState {
|
||||||
Textures _textures;
|
Textures _textures;
|
||||||
|
|
||||||
|
int findEmptyTextureSlot() const;
|
||||||
|
|
||||||
ResourceStageState():
|
ResourceStageState():
|
||||||
_textures(MAX_NUM_RESOURCE_TEXTURES, nullptr)
|
_textures(MAX_NUM_RESOURCE_TEXTURES, nullptr)
|
||||||
{}
|
{}
|
||||||
|
@ -432,6 +436,7 @@ protected:
|
||||||
void do_setFramebuffer(Batch& batch, size_t paramOffset);
|
void do_setFramebuffer(Batch& batch, size_t paramOffset);
|
||||||
void do_clearFramebuffer(Batch& batch, size_t paramOffset);
|
void do_clearFramebuffer(Batch& batch, size_t paramOffset);
|
||||||
void do_blit(Batch& batch, size_t paramOffset);
|
void do_blit(Batch& batch, size_t paramOffset);
|
||||||
|
void do_generateTextureMipmap(Batch& batch, size_t paramOffset);
|
||||||
|
|
||||||
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
// Synchronize the state cache of this Backend with the actual real state of the GL Context
|
||||||
void syncOutputStateCache();
|
void syncOutputStateCache();
|
||||||
|
|
|
@ -361,4 +361,4 @@ void GLBackend::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, co
|
||||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
(void) CHECK_GL_ERROR();
|
(void) CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,7 @@ void GLBackend::releaseResourceTexture(uint32_t slot) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void GLBackend::resetResourceStage() {
|
void GLBackend::resetResourceStage() {
|
||||||
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
|
for (uint32_t i = 0; i < _resource._textures.size(); i++) {
|
||||||
releaseResourceTexture(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -404,8 +404,9 @@ GLBackend::GLTexture* GLBackend::syncGPUObject(const Texture& texture) {
|
||||||
if (bytes && texture.isAutogenerateMips()) {
|
if (bytes && texture.isAutogenerateMips()) {
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
} else if (texture.isAutogenerateMips()) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
object->_target = GL_TEXTURE_2D;
|
object->_target = GL_TEXTURE_2D;
|
||||||
|
|
||||||
syncSampler(texture.getSampler(), texture.getType(), object);
|
syncSampler(texture.getSampler(), texture.getType(), object);
|
||||||
|
@ -588,3 +589,37 @@ void GLBackend::syncSampler(const Sampler& sampler, Texture::Type type, GLTextur
|
||||||
glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
glTexParameterf(object->_target, GL_TEXTURE_MAX_ANISOTROPY_EXT, sampler.getMaxAnisotropy());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void GLBackend::do_generateTextureMipmap(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();
|
||||||
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ static const std::string FUNCTIONS_PLACEHOLDER { "/*FUNCTIONS_PLACEHOLDER*/" };
|
||||||
std::string DebugDeferredBuffer::getCode(Modes mode) {
|
std::string DebugDeferredBuffer::getCode(Modes mode) {
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case DiffuseMode: {
|
case DiffuseMode: {
|
||||||
QString code = "return vec4(texture(%1, uv).xyz, 1.0);";
|
QString code = "return vec4(pow(texture(%1, uv).xyz, vec3(1.0 / 2.2)), 1.0);";
|
||||||
return code.arg(SLOT_NAMES[Diffuse].c_str()).toStdString();
|
return code.arg(SLOT_NAMES[Diffuse].c_str()).toStdString();
|
||||||
}
|
}
|
||||||
case AlphaMode: {
|
case AlphaMode: {
|
||||||
|
@ -73,7 +73,7 @@ std::string DebugDeferredBuffer::getCode(Modes mode) {
|
||||||
return code.arg(SLOT_NAMES[Depth].c_str()).toStdString();
|
return code.arg(SLOT_NAMES[Depth].c_str()).toStdString();
|
||||||
}
|
}
|
||||||
case LightingMode: {
|
case LightingMode: {
|
||||||
QString code = "return vec4(texture(%1, uv).xyz, 1.0);";
|
QString code = "return vec4(pow(texture(%1, uv).xyz, vec3(1.0 / 2.2)), 1.0);";
|
||||||
return code.arg(SLOT_NAMES[Lighting].c_str()).toStdString();
|
return code.arg(SLOT_NAMES[Lighting].c_str()).toStdString();
|
||||||
}
|
}
|
||||||
case CustomMode:
|
case CustomMode:
|
||||||
|
|
|
@ -87,9 +87,11 @@ void FramebufferCache::createPrimaryFramebuffer() {
|
||||||
auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));
|
auto tex = gpu::TexturePointer(gpu::Texture::create2D(colorFormat, width * 0.5, height * 0.5, defaultSampler));
|
||||||
_selfieFramebuffer->setRenderBuffer(0, tex);
|
_selfieFramebuffer->setRenderBuffer(0, tex);
|
||||||
|
|
||||||
|
auto smoothSampler = gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_MIP_LINEAR);
|
||||||
|
|
||||||
//_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, width, height, defaultSampler));
|
//_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::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));
|
_lightingTexture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element(gpu::VEC4, gpu::HALF, gpu::RGBA), width, height, smoothSampler));
|
||||||
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
_lightingFramebuffer = gpu::FramebufferPointer(gpu::Framebuffer::create());
|
||||||
_lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
|
_lightingFramebuffer->setRenderBuffer(0, _lightingTexture);
|
||||||
_lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
_lightingFramebuffer->setDepthStencilBuffer(_primaryDepthTexture, depthFormat);
|
||||||
|
|
|
@ -104,6 +104,7 @@ RenderDeferredTask::RenderDeferredTask() : Task() {
|
||||||
|
|
||||||
// Lighting Buffer ready for tone mapping
|
// Lighting Buffer ready for tone mapping
|
||||||
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
|
_jobs.push_back(Job(new ToneMappingDeferred::JobModel("ToneMapping")));
|
||||||
|
_toneMappingJobIndex = _jobs.size() - 1;
|
||||||
|
|
||||||
// Debugging Deferred buffer job
|
// Debugging Deferred buffer job
|
||||||
_jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer")));
|
_jobs.push_back(Job(new DebugDeferredBuffer::JobModel("DebugDeferredBuffer")));
|
||||||
|
@ -164,6 +165,8 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
||||||
|
|
||||||
setAntialiasingStatus(renderContext->_fxaaStatus);
|
setAntialiasingStatus(renderContext->_fxaaStatus);
|
||||||
|
|
||||||
|
setToneMappingExposure(renderContext->_toneMappingExposure);
|
||||||
|
|
||||||
renderContext->args->_context->syncCache();
|
renderContext->args->_context->syncCache();
|
||||||
|
|
||||||
for (auto job : _jobs) {
|
for (auto job : _jobs) {
|
||||||
|
@ -390,3 +393,18 @@ void DrawBackgroundDeferred::run(const SceneContextPointer& sceneContext, const
|
||||||
});
|
});
|
||||||
args->_batch = nullptr;
|
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) {
|
||||||
|
_jobs[_toneMappingJobIndex].get<ToneMappingDeferred>()._toneMappingEffect.getExposure();
|
||||||
|
} else {
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -129,6 +129,11 @@ public:
|
||||||
void setAntialiasingStatus(bool draw) { if (_antialiasingJobIndex >= 0) { _jobs[_antialiasingJobIndex].setEnabled(draw); } }
|
void setAntialiasingStatus(bool draw) { if (_antialiasingJobIndex >= 0) { _jobs[_antialiasingJobIndex].setEnabled(draw); } }
|
||||||
bool doAntialiasingStatus() const { if (_antialiasingJobIndex >= 0) { return _jobs[_antialiasingJobIndex].isEnabled(); } else { return false; } }
|
bool doAntialiasingStatus() const { if (_antialiasingJobIndex >= 0) { return _jobs[_antialiasingJobIndex].isEnabled(); } else { return false; } }
|
||||||
|
|
||||||
|
int _toneMappingJobIndex = -1;
|
||||||
|
|
||||||
|
void setToneMappingExposure(float exposure);
|
||||||
|
float getToneMappingExposure() const;
|
||||||
|
|
||||||
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
virtual void run(const render::SceneContextPointer& sceneContext, const render::RenderContextPointer& renderContext);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@
|
||||||
|
|
||||||
|
|
||||||
ToneMappingEffect::ToneMappingEffect() {
|
ToneMappingEffect::ToneMappingEffect() {
|
||||||
|
Parameters parameters;
|
||||||
|
_parametersBuffer = gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(Parameters), (const gpu::Byte*) ¶meters));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToneMappingEffect::init() {
|
void ToneMappingEffect::init() {
|
||||||
|
@ -38,6 +39,16 @@ void ToneMappingEffect::init() {
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
struct ToneMappingParams {
|
||||||
|
vec4 _exp_2powExp_s0_s1;
|
||||||
|
};
|
||||||
|
|
||||||
|
uniform toneMappingParamsBuffer {
|
||||||
|
ToneMappingParams params;
|
||||||
|
};
|
||||||
|
float getTwoPowExposure() {
|
||||||
|
return params._exp_2powExp_s0_s1.y;
|
||||||
|
}
|
||||||
|
|
||||||
uniform sampler2D colorMap;
|
uniform sampler2D colorMap;
|
||||||
|
|
||||||
|
@ -45,16 +56,24 @@ void ToneMappingEffect::init() {
|
||||||
out vec4 outFragColor;
|
out vec4 outFragColor;
|
||||||
|
|
||||||
void main(void) {
|
void main(void) {
|
||||||
vec4 fragColor = texture(colorMap, varTexCoord0);
|
vec4 fragColorRaw = textureLod(colorMap, varTexCoord0, 0);
|
||||||
|
vec3 fragColor = fragColorRaw.xyz;
|
||||||
|
|
||||||
|
/* vec4 fragColorAverage = textureLod(colorMap, varTexCoord0, 10);
|
||||||
|
float averageIntensity = length(fragColorAverage.xyz);
|
||||||
|
|
||||||
|
vec3 fragColor = fragColorRaw.xyz / averageIntensity;
|
||||||
|
*/
|
||||||
|
fragColor *= getTwoPowExposure();
|
||||||
|
|
||||||
|
|
||||||
// if (gl_FragCoord.x > 1000) {
|
// if (gl_FragCoord.x > 1000) {
|
||||||
// Manually gamma correct from Ligthing BUffer to color buffer
|
// Manually gamma correct from Ligthing BUffer to color buffer
|
||||||
// outFragColor.xyz = pow( fragColor.xyz , vec3(1.0 / 2.2) );
|
// outFragColor.xyz = pow( fragColor.xyz , vec3(1.0 / 2.2) );
|
||||||
|
|
||||||
fragColor *= 2.0; // Hardcoded Exposure Adjustment
|
|
||||||
vec3 x = max(vec3(0.0),fragColor.xyz-0.004);
|
vec3 x = max(vec3(0.0),fragColor.xyz-0.004);
|
||||||
vec3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
|
vec3 retColor = (x*(6.2*x+.5))/(x*(6.2*x+1.7)+0.06);
|
||||||
|
|
||||||
// fragColor *= 8; // Hardcoded Exposure Adjustment
|
|
||||||
// fragColor = fragColor/(1.0+fragColor);
|
// fragColor = fragColor/(1.0+fragColor);
|
||||||
// vec3 retColor = pow(fragColor.xyz,vec3(1/2.2));
|
// vec3 retColor = pow(fragColor.xyz,vec3(1/2.2));
|
||||||
|
|
||||||
|
@ -70,12 +89,19 @@ void ToneMappingEffect::init() {
|
||||||
auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS));
|
auto blitProgram = gpu::ShaderPointer(gpu::Shader::createProgram(blitVS, blitPS));
|
||||||
|
|
||||||
//auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS, gpu::StandardShaderLib::getDrawTexturePS);
|
//auto blitProgram = gpu::StandardShaderLib::getProgram(gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS, gpu::StandardShaderLib::getDrawTexturePS);
|
||||||
gpu::Shader::makeProgram(*blitProgram);
|
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>();
|
auto blitState = std::make_shared<gpu::State>();
|
||||||
blitState->setColorWriteMask(true, true, true, true);
|
blitState->setColorWriteMask(true, true, true, true);
|
||||||
_blitLightBuffer = gpu::PipelinePointer(gpu::Pipeline::create(blitProgram, blitState));
|
_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::render(RenderArgs* args) {
|
void ToneMappingEffect::render(RenderArgs* args) {
|
||||||
if (!_blitLightBuffer) {
|
if (!_blitLightBuffer) {
|
||||||
|
@ -89,6 +115,9 @@ void ToneMappingEffect::render(RenderArgs* args) {
|
||||||
auto lightingBuffer = framebufferCache->getLightingTexture();
|
auto lightingBuffer = framebufferCache->getLightingTexture();
|
||||||
auto destFbo = framebufferCache->getPrimaryFramebuffer();
|
auto destFbo = framebufferCache->getPrimaryFramebuffer();
|
||||||
batch.setFramebuffer(destFbo);
|
batch.setFramebuffer(destFbo);
|
||||||
|
|
||||||
|
batch.generateTextureMipmap(lightingBuffer);
|
||||||
|
|
||||||
batch.setViewportTransform(args->_viewport);
|
batch.setViewportTransform(args->_viewport);
|
||||||
batch.setProjectionTransform(glm::mat4());
|
batch.setProjectionTransform(glm::mat4());
|
||||||
batch.setViewTransform(Transform());
|
batch.setViewTransform(Transform());
|
||||||
|
@ -104,6 +133,7 @@ void ToneMappingEffect::render(RenderArgs* args) {
|
||||||
batch.setModelTransform(model);
|
batch.setModelTransform(model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
batch.setUniformBuffer(3, _parametersBuffer);
|
||||||
batch.setResourceTexture(0, lightingBuffer);
|
batch.setResourceTexture(0, lightingBuffer);
|
||||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,9 @@ public:
|
||||||
|
|
||||||
void render(RenderArgs* args);
|
void render(RenderArgs* args);
|
||||||
|
|
||||||
|
void setExposure(float exposure);
|
||||||
|
float getExposure() const { return _parametersBuffer.get<Parameters>()._exposure; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
gpu::PipelinePointer _blitLightBuffer;
|
gpu::PipelinePointer _blitLightBuffer;
|
||||||
|
@ -34,7 +37,10 @@ private:
|
||||||
// Class describing the uniform buffer with all the parameters common to the tone mapping shaders
|
// Class describing the uniform buffer with all the parameters common to the tone mapping shaders
|
||||||
class Parameters {
|
class Parameters {
|
||||||
public:
|
public:
|
||||||
|
float _exposure = 0.0f;
|
||||||
|
float _twoPowExposure = 1.0f;
|
||||||
|
glm::vec2 spare;
|
||||||
|
|
||||||
Parameters() {}
|
Parameters() {}
|
||||||
};
|
};
|
||||||
typedef gpu::BufferView UniformBufferView;
|
typedef gpu::BufferView UniformBufferView;
|
||||||
|
|
|
@ -84,6 +84,23 @@ public:
|
||||||
const Varying getInput() const { return _concept->getInput(); }
|
const Varying getInput() const { return _concept->getInput(); }
|
||||||
const Varying getOutput() const { return _concept->getOutput(); }
|
const Varying getOutput() const { return _concept->getOutput(); }
|
||||||
|
|
||||||
|
template <class T> T& edit() {
|
||||||
|
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
|
||||||
|
if (theConcept) {
|
||||||
|
return theConcept->_data;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
template <class T> const T& get() const {
|
||||||
|
auto theConcept = std::dynamic_pointer_cast<typename T::JobModel>(_concept);
|
||||||
|
if (theConcept) {
|
||||||
|
return theConcept->_data;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return T();
|
||||||
|
}
|
||||||
|
|
||||||
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
|
||||||
PerformanceTimer perfTimer(getName().c_str());
|
PerformanceTimer perfTimer(getName().c_str());
|
||||||
PROFILE_RANGE(getName().c_str());
|
PROFILE_RANGE(getName().c_str());
|
||||||
|
|
|
@ -61,6 +61,8 @@ public:
|
||||||
bool _occlusionStatus = false;
|
bool _occlusionStatus = false;
|
||||||
bool _fxaaStatus = false;
|
bool _fxaaStatus = false;
|
||||||
|
|
||||||
|
float _toneMappingExposure = 0.0;
|
||||||
|
|
||||||
RenderContext() {}
|
RenderContext() {}
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
typedef std::shared_ptr<RenderContext> RenderContextPointer;
|
||||||
|
|
|
@ -118,6 +118,9 @@ public:
|
||||||
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
|
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
|
||||||
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
|
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
|
||||||
|
|
||||||
|
Q_INVOKABLE void setEngineToneMappingExposure(float exposure) { _engineToneMappingExposure = exposure; }
|
||||||
|
Q_INVOKABLE float getEngineToneMappingExposure() { return _engineToneMappingExposure; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
||||||
void shouldRenderEntitiesChanged(bool shouldRenderEntities);
|
void shouldRenderEntitiesChanged(bool shouldRenderEntities);
|
||||||
|
@ -154,6 +157,7 @@ protected:
|
||||||
|
|
||||||
bool _drawHitEffect = false;
|
bool _drawHitEffect = false;
|
||||||
|
|
||||||
|
float _engineToneMappingExposure = 0.0f;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_SceneScriptingInterface_h
|
#endif // hifi_SceneScriptingInterface_h
|
||||||
|
|
Loading…
Reference in a new issue