mirror of
https://github.com/lubosz/overte.git
synced 2025-04-19 17:03:43 +02:00
Merge pull request #6678 from samcake/hdr
Graphics: Tone mapping Tone curve is now configurable and Material colors are sRGB by default
This commit is contained in:
commit
aac59ad442
11 changed files with 134 additions and 36 deletions
|
@ -3703,6 +3703,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
|
|||
renderContext._fxaaStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
|
||||
|
||||
renderContext._toneMappingExposure = sceneInterface->getEngineToneMappingExposure();
|
||||
renderContext._toneMappingToneCurve = sceneInterface->getEngineToneMappingToneCurveValue();
|
||||
|
||||
renderArgs->_shouldRender = LODManager::shouldRender;
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
const 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);
|
||||
const 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
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ void RenderDeferredTask::run(const SceneContextPointer& sceneContext, const Rend
|
|||
setAntialiasingStatus(renderContext->_fxaaStatus);
|
||||
|
||||
setToneMappingExposure(renderContext->_toneMappingExposure);
|
||||
setToneMappingToneCurve(renderContext->_toneMappingToneCurve);
|
||||
|
||||
renderContext->args->_context->syncCache();
|
||||
|
||||
|
@ -403,8 +404,23 @@ void RenderDeferredTask::setToneMappingExposure(float exposure) {
|
|||
|
||||
float RenderDeferredTask::getToneMappingExposure() const {
|
||||
if (_toneMappingJobIndex >= 0) {
|
||||
_jobs[_toneMappingJobIndex].get<ToneMappingDeferred>()._toneMappingEffect.getExposure();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,9 @@ public:
|
|||
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);
|
||||
|
||||
|
||||
|
|
|
@ -36,18 +36,28 @@ void ToneMappingEffect::init() {
|
|||
// 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;
|
||||
|
@ -56,25 +66,26 @@ void ToneMappingEffect::init() {
|
|||
void main(void) {
|
||||
vec4 fragColorRaw = textureLod(colorMap, varTexCoord0, 0);
|
||||
vec3 fragColor = fragColorRaw.xyz;
|
||||
|
||||
/* vec4 fragColorAverage = textureLod(colorMap, varTexCoord0, 10);
|
||||
/*
|
||||
vec4 fragColorAverage = textureLod(colorMap, varTexCoord0, 10);
|
||||
float averageIntensity = length(fragColorAverage.xyz);
|
||||
|
||||
vec3 fragColor = fragColorRaw.xyz / averageIntensity;
|
||||
fragColor /= averageIntensity;
|
||||
*/
|
||||
fragColor *= getTwoPowExposure();
|
||||
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
|
||||
|
||||
// Manually gamma correct from Ligthing BUffer to color buffer
|
||||
// outFragColor.xyz = pow( fragColor.xyz , vec3(1.0 / 2.2) );
|
||||
|
||||
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);
|
||||
|
||||
// fragColor = fragColor/(1.0+fragColor);
|
||||
// vec3 retColor = pow(fragColor.xyz,vec3(1/2.2));
|
||||
|
||||
outFragColor = vec4(retColor, 1.0);
|
||||
outFragColor = vec4(tonedColor, 1.0);
|
||||
}
|
||||
|
||||
)SCRIBE";
|
||||
|
@ -96,6 +107,9 @@ void ToneMappingEffect::setExposure(float 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) {
|
||||
|
|
|
@ -30,6 +30,16 @@ public:
|
|||
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;
|
||||
|
@ -39,7 +49,9 @@ private:
|
|||
public:
|
||||
float _exposure = 0.0f;
|
||||
float _twoPowExposure = 1.0f;
|
||||
glm::vec2 spare;
|
||||
glm::vec2 spareA;
|
||||
int _toneCurve = Filmic;
|
||||
glm::vec3 spareB;
|
||||
|
||||
Parameters() {}
|
||||
};
|
||||
|
|
|
@ -62,6 +62,7 @@ public:
|
|||
bool _fxaaStatus = false;
|
||||
|
||||
float _toneMappingExposure = 0.0;
|
||||
int _toneMappingToneCurve = 3;
|
||||
|
||||
RenderContext() {}
|
||||
};
|
||||
|
|
|
@ -167,3 +167,30 @@ void SceneScriptingInterface::clearEngineCounters() {
|
|||
_numFeedOverlay3DItems = 0;
|
||||
_numDrawnOverlay3DItems = 0;
|
||||
}
|
||||
|
||||
|
||||
void SceneScriptingInterface::setEngineToneMappingToneCurve(const QString& toneCurve) {
|
||||
if (toneCurve == QString("None")) {
|
||||
_engineToneMappingToneCurve = 0;
|
||||
} else if (toneCurve == QString("Gamma22")) {
|
||||
_engineToneMappingToneCurve = 1;
|
||||
} else if (toneCurve == QString("Reinhard")) {
|
||||
_engineToneMappingToneCurve = 2;
|
||||
} else if (toneCurve == QString("Filmic")) {
|
||||
_engineToneMappingToneCurve = 3;
|
||||
}
|
||||
}
|
||||
QString SceneScriptingInterface::getEngineToneMappingToneCurve() const {
|
||||
switch (_engineToneMappingToneCurve) {
|
||||
case 0:
|
||||
return QString("None");
|
||||
case 1:
|
||||
return QString("Gamma22");
|
||||
case 2:
|
||||
return QString("Reinhard");
|
||||
case 3:
|
||||
return QString("Filmic");
|
||||
default:
|
||||
return QString("Filmic");
|
||||
};
|
||||
}
|
|
@ -119,7 +119,11 @@ public:
|
|||
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
|
||||
|
||||
Q_INVOKABLE void setEngineToneMappingExposure(float exposure) { _engineToneMappingExposure = exposure; }
|
||||
Q_INVOKABLE float getEngineToneMappingExposure() { return _engineToneMappingExposure; }
|
||||
Q_INVOKABLE float getEngineToneMappingExposure() const { return _engineToneMappingExposure; }
|
||||
|
||||
Q_INVOKABLE void setEngineToneMappingToneCurve(const QString& curve);
|
||||
Q_INVOKABLE QString getEngineToneMappingToneCurve() const;
|
||||
int getEngineToneMappingToneCurveValue() const { return _engineToneMappingToneCurve; }
|
||||
|
||||
signals:
|
||||
void shouldRenderAvatarsChanged(bool shouldRenderAvatars);
|
||||
|
@ -158,6 +162,7 @@ protected:
|
|||
bool _drawHitEffect = false;
|
||||
|
||||
float _engineToneMappingExposure = 0.0f;
|
||||
int _engineToneMappingToneCurve = 3;
|
||||
};
|
||||
|
||||
#endif // hifi_SceneScriptingInterface_h
|
||||
|
|
|
@ -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
|
Loading…
Reference in a new issue