Add tong shader
parent
ae478fc064
commit
120b59b45f
|
@ -548,6 +548,7 @@ https://www.reddit.com/r/gamedev/comments/5iuf3h/i_am_writting_a_3d_monster_mode
|
||||||
<h1>Sam Hocevar</h1>
|
<h1>Sam Hocevar</h1>
|
||||||
<pre>
|
<pre>
|
||||||
https://gamedev.stackexchange.com/questions/98246/quaternion-slerp-and-lerp-implementation-with-overshoot
|
https://gamedev.stackexchange.com/questions/98246/quaternion-slerp-and-lerp-implementation-with-overshoot
|
||||||
|
http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<h1>David Rosen</h1>
|
<h1>David Rosen</h1>
|
||||||
|
|
|
@ -86,6 +86,7 @@ uniform samplerCube environmentIrradianceMapId;
|
||||||
uniform int environmentIrradianceMapEnabled;
|
uniform int environmentIrradianceMapEnabled;
|
||||||
uniform samplerCube environmentSpecularMapId;
|
uniform samplerCube environmentSpecularMapId;
|
||||||
uniform int environmentSpecularMapEnabled;
|
uniform int environmentSpecularMapEnabled;
|
||||||
|
uniform int tongShadingEnabled;
|
||||||
|
|
||||||
const int MAX_LIGHTS = 8;
|
const int MAX_LIGHTS = 8;
|
||||||
const int TYPE_POINT = 0;
|
const int TYPE_POINT = 0;
|
||||||
|
@ -352,6 +353,25 @@ vec3 gammaCorrect(const in vec3 color)
|
||||||
return pow(color, vec3(1.0 / gamma));
|
return pow(color, vec3(1.0 / gamma));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
|
||||||
|
vec3 rgb2hsv(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
|
||||||
|
float d = q.x - min(q.w, q.y);
|
||||||
|
float e = 1.0e-10;
|
||||||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hsv2rgb(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 metalRoughFunction(const in vec4 baseColor,
|
vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
const in float metalness,
|
const in float metalness,
|
||||||
const in float roughness,
|
const in float roughness,
|
||||||
|
@ -365,6 +385,7 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
// Remap roughness for a perceptually more linear correspondence
|
// Remap roughness for a perceptually more linear correspondence
|
||||||
float alpha = remapRoughness(roughness);
|
float alpha = remapRoughness(roughness);
|
||||||
|
|
||||||
|
if (tongShadingEnabled != 1) {
|
||||||
if (environmentIrradianceMapEnabled == 1) {
|
if (environmentIrradianceMapEnabled == 1) {
|
||||||
cLinear += pbrIblModel(worldNormal,
|
cLinear += pbrIblModel(worldNormal,
|
||||||
worldView,
|
worldView,
|
||||||
|
@ -384,6 +405,16 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
alpha,
|
alpha,
|
||||||
ambientOcclusion);
|
ambientOcclusion);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
float intensity;
|
||||||
|
intensity = dot(vec3(1.0, 1.0, 1.0), worldNormal);
|
||||||
|
|
||||||
|
vec3 hsv = rgb2hsv(baseColor.rgb);
|
||||||
|
if (intensity > 0.966)
|
||||||
|
cLinear = hsv2rgb(vec3(hsv.r, hsv.g, hsv.b * 2.0));
|
||||||
|
else
|
||||||
|
cLinear = hsv2rgb(vec3(hsv.r, hsv.g, hsv.b * 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
// Apply exposure correction
|
// Apply exposure correction
|
||||||
cLinear *= pow(2.0, exposure);
|
cLinear *= pow(2.0, exposure);
|
||||||
|
|
|
@ -80,6 +80,7 @@ uniform int ambientOcclusionMapEnabled;
|
||||||
uniform int mousePickEnabled;
|
uniform int mousePickEnabled;
|
||||||
uniform vec3 mousePickTargetPosition;
|
uniform vec3 mousePickTargetPosition;
|
||||||
uniform float mousePickRadius;
|
uniform float mousePickRadius;
|
||||||
|
uniform int tongShadingEnabled;
|
||||||
|
|
||||||
const int MAX_LIGHTS = 8;
|
const int MAX_LIGHTS = 8;
|
||||||
const int TYPE_POINT = 0;
|
const int TYPE_POINT = 0;
|
||||||
|
@ -248,6 +249,25 @@ vec3 gammaCorrect(const in vec3 color)
|
||||||
return pow(color, vec3(1.0 / gamma));
|
return pow(color, vec3(1.0 / gamma));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
|
||||||
|
vec3 rgb2hsv(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||||
|
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||||
|
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||||
|
|
||||||
|
float d = q.x - min(q.w, q.y);
|
||||||
|
float e = 1.0e-10;
|
||||||
|
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 hsv2rgb(vec3 c)
|
||||||
|
{
|
||||||
|
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||||
|
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||||
|
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||||
|
}
|
||||||
|
|
||||||
vec4 metalRoughFunction(const in vec4 baseColor,
|
vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
const in float metalness,
|
const in float metalness,
|
||||||
const in float roughness,
|
const in float roughness,
|
||||||
|
@ -261,6 +281,7 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
// Remap roughness for a perceptually more linear correspondence
|
// Remap roughness for a perceptually more linear correspondence
|
||||||
float alpha = remapRoughness(roughness);
|
float alpha = remapRoughness(roughness);
|
||||||
|
|
||||||
|
if (tongShadingEnabled != 1) {
|
||||||
for (int i = 0; i < lightCount; ++i) {
|
for (int i = 0; i < lightCount; ++i) {
|
||||||
cLinear += pbrModel(i,
|
cLinear += pbrModel(i,
|
||||||
worldPosition,
|
worldPosition,
|
||||||
|
@ -271,6 +292,16 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
||||||
alpha,
|
alpha,
|
||||||
ambientOcclusion);
|
ambientOcclusion);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
float intensity;
|
||||||
|
intensity = dot(vec3(1.0, 1.0, 1.0), worldNormal);
|
||||||
|
|
||||||
|
vec3 hsv = rgb2hsv(baseColor.rgb);
|
||||||
|
if (intensity > 0.966)
|
||||||
|
cLinear = hsv2rgb(vec3(hsv.r, hsv.g, hsv.b * 2.0));
|
||||||
|
else
|
||||||
|
cLinear = hsv2rgb(vec3(hsv.r, hsv.g, hsv.b * 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
// Apply exposure correction
|
// Apply exposure correction
|
||||||
cLinear *= pow(2.0, exposure);
|
cLinear *= pow(2.0, exposure);
|
||||||
|
|
|
@ -58,6 +58,7 @@ ModelShaderProgram::ModelShaderProgram(bool isCoreProfile)
|
||||||
m_mousePickEnabledLoc = this->uniformLocation("mousePickEnabled");
|
m_mousePickEnabledLoc = this->uniformLocation("mousePickEnabled");
|
||||||
m_mousePickTargetPositionLoc = this->uniformLocation("mousePickTargetPosition");
|
m_mousePickTargetPositionLoc = this->uniformLocation("mousePickTargetPosition");
|
||||||
m_mousePickRadiusLoc = this->uniformLocation("mousePickRadius");
|
m_mousePickRadiusLoc = this->uniformLocation("mousePickRadius");
|
||||||
|
m_tongShadingEnabledLoc = this->uniformLocation("tongShadingEnabled");
|
||||||
if (m_isCoreProfile) {
|
if (m_isCoreProfile) {
|
||||||
m_environmentIrradianceMapIdLoc = this->uniformLocation("environmentIrradianceMapId");
|
m_environmentIrradianceMapIdLoc = this->uniformLocation("environmentIrradianceMapId");
|
||||||
m_environmentIrradianceMapEnabledLoc = this->uniformLocation("environmentIrradianceMapEnabled");
|
m_environmentIrradianceMapEnabledLoc = this->uniformLocation("environmentIrradianceMapEnabled");
|
||||||
|
@ -166,3 +167,7 @@ int ModelShaderProgram::environmentSpecularMapEnabledLoc()
|
||||||
return m_environmentSpecularMapEnabledLoc;
|
return m_environmentSpecularMapEnabledLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ModelShaderProgram::tongShadingEnabledLoc()
|
||||||
|
{
|
||||||
|
return m_tongShadingEnabledLoc;
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ public:
|
||||||
int environmentIrradianceMapEnabledLoc();
|
int environmentIrradianceMapEnabledLoc();
|
||||||
int environmentSpecularMapIdLoc();
|
int environmentSpecularMapIdLoc();
|
||||||
int environmentSpecularMapEnabledLoc();
|
int environmentSpecularMapEnabledLoc();
|
||||||
|
int tongShadingEnabledLoc();
|
||||||
bool isCoreProfile();
|
bool isCoreProfile();
|
||||||
static const QString &loadShaderSource(const QString &name);
|
static const QString &loadShaderSource(const QString &name);
|
||||||
private:
|
private:
|
||||||
|
@ -51,6 +52,7 @@ private:
|
||||||
int m_environmentIrradianceMapEnabledLoc = 0;
|
int m_environmentIrradianceMapEnabledLoc = 0;
|
||||||
int m_environmentSpecularMapIdLoc = 0;
|
int m_environmentSpecularMapIdLoc = 0;
|
||||||
int m_environmentSpecularMapEnabledLoc = 0;
|
int m_environmentSpecularMapEnabledLoc = 0;
|
||||||
|
int m_tongShadingEnabledLoc = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <QSurfaceFormat>
|
#include <QSurfaceFormat>
|
||||||
#include "modelwidget.h"
|
#include "modelwidget.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "preferences.h"
|
||||||
|
|
||||||
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
|
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
|
||||||
|
|
||||||
|
@ -46,6 +47,13 @@ ModelWidget::ModelWidget(QWidget *parent) :
|
||||||
}
|
}
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||||
zoom(200);
|
zoom(200);
|
||||||
|
|
||||||
|
connect(&Preferences::instance(), &Preferences::tongShadingChanged, this, &ModelWidget::reRender);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelWidget::reRender()
|
||||||
|
{
|
||||||
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ModelWidget::xRot()
|
int ModelWidget::xRot()
|
||||||
|
@ -173,6 +181,7 @@ void ModelWidget::paintGL()
|
||||||
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
|
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
|
||||||
|
|
||||||
m_program->bind();
|
m_program->bind();
|
||||||
|
m_program->setUniformValue(m_program->tongShadingEnabledLoc(), Preferences::instance().tongShading() ? 1 : 0);
|
||||||
m_program->setUniformValue(m_program->projectionMatrixLoc(), m_projection);
|
m_program->setUniformValue(m_program->projectionMatrixLoc(), m_projection);
|
||||||
m_program->setUniformValue(m_program->modelMatrixLoc(), m_world);
|
m_program->setUniformValue(m_program->modelMatrixLoc(), m_world);
|
||||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||||
|
|
|
@ -56,6 +56,7 @@ public slots:
|
||||||
void zoom(float delta);
|
void zoom(float delta);
|
||||||
void setMousePickTargetPositionInModelSpace(QVector3D position);
|
void setMousePickTargetPositionInModelSpace(QVector3D position);
|
||||||
void setMousePickRadius(float radius);
|
void setMousePickRadius(float radius);
|
||||||
|
void reRender();
|
||||||
signals:
|
signals:
|
||||||
void xRotationChanged(int angle);
|
void xRotationChanged(int angle);
|
||||||
void yRotationChanged(int angle);
|
void yRotationChanged(int angle);
|
||||||
|
|
|
@ -15,6 +15,7 @@ void Preferences::loadDefault()
|
||||||
m_componentCombineMode = CombineMode::Normal;
|
m_componentCombineMode = CombineMode::Normal;
|
||||||
m_partColor = Qt::white;
|
m_partColor = Qt::white;
|
||||||
m_flatShading = true;
|
m_flatShading = true;
|
||||||
|
m_tongShading = false;
|
||||||
m_textureSize = 1024;
|
m_textureSize = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,6 +39,13 @@ Preferences::Preferences()
|
||||||
else
|
else
|
||||||
m_flatShading = isTrueValueString(value);
|
m_flatShading = isTrueValueString(value);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
QString value = m_settings.value("tongShading").toString();
|
||||||
|
if (value.isEmpty())
|
||||||
|
m_tongShading = false;
|
||||||
|
else
|
||||||
|
m_tongShading = isTrueValueString(value);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
QString value = m_settings.value("textureSize").toString();
|
QString value = m_settings.value("textureSize").toString();
|
||||||
if (!value.isEmpty())
|
if (!value.isEmpty())
|
||||||
|
@ -60,6 +68,11 @@ bool Preferences::flatShading() const
|
||||||
return m_flatShading;
|
return m_flatShading;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Preferences::tongShading() const
|
||||||
|
{
|
||||||
|
return m_tongShading;
|
||||||
|
}
|
||||||
|
|
||||||
int Preferences::textureSize() const
|
int Preferences::textureSize() const
|
||||||
{
|
{
|
||||||
return m_textureSize;
|
return m_textureSize;
|
||||||
|
@ -92,6 +105,15 @@ void Preferences::setFlatShading(bool flatShading)
|
||||||
emit flatShadingChanged();
|
emit flatShadingChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Preferences::setTongShading(bool tongShading)
|
||||||
|
{
|
||||||
|
if (m_tongShading == tongShading)
|
||||||
|
return;
|
||||||
|
m_tongShading = tongShading;
|
||||||
|
m_settings.setValue("tongShading", tongShading ? "true" : "false");
|
||||||
|
emit tongShadingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void Preferences::setTextureSize(int textureSize)
|
void Preferences::setTextureSize(int textureSize)
|
||||||
{
|
{
|
||||||
if (m_textureSize == textureSize)
|
if (m_textureSize == textureSize)
|
||||||
|
@ -118,5 +140,6 @@ void Preferences::reset()
|
||||||
emit componentCombineModeChanged();
|
emit componentCombineModeChanged();
|
||||||
emit partColorChanged();
|
emit partColorChanged();
|
||||||
emit flatShadingChanged();
|
emit flatShadingChanged();
|
||||||
|
emit tongShadingChanged();
|
||||||
emit textureSizeChanged();
|
emit textureSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ public:
|
||||||
CombineMode componentCombineMode() const;
|
CombineMode componentCombineMode() const;
|
||||||
const QColor &partColor() const;
|
const QColor &partColor() const;
|
||||||
bool flatShading() const;
|
bool flatShading() const;
|
||||||
|
bool tongShading() const;
|
||||||
QSize documentWindowSize() const;
|
QSize documentWindowSize() const;
|
||||||
void setDocumentWindowSize(const QSize&);
|
void setDocumentWindowSize(const QSize&);
|
||||||
int textureSize() const;
|
int textureSize() const;
|
||||||
|
@ -21,17 +22,20 @@ signals:
|
||||||
void componentCombineModeChanged();
|
void componentCombineModeChanged();
|
||||||
void partColorChanged();
|
void partColorChanged();
|
||||||
void flatShadingChanged();
|
void flatShadingChanged();
|
||||||
|
void tongShadingChanged();
|
||||||
void textureSizeChanged();
|
void textureSizeChanged();
|
||||||
public slots:
|
public slots:
|
||||||
void setComponentCombineMode(CombineMode mode);
|
void setComponentCombineMode(CombineMode mode);
|
||||||
void setPartColor(const QColor &color);
|
void setPartColor(const QColor &color);
|
||||||
void setFlatShading(bool flatShading);
|
void setFlatShading(bool flatShading);
|
||||||
|
void setTongShading(bool tongShading);
|
||||||
void setTextureSize(int textureSize);
|
void setTextureSize(int textureSize);
|
||||||
void reset();
|
void reset();
|
||||||
private:
|
private:
|
||||||
CombineMode m_componentCombineMode;
|
CombineMode m_componentCombineMode;
|
||||||
QColor m_partColor;
|
QColor m_partColor;
|
||||||
bool m_flatShading;
|
bool m_flatShading;
|
||||||
|
bool m_tongShading;
|
||||||
QSettings m_settings;
|
QSettings m_settings;
|
||||||
int m_textureSize;
|
int m_textureSize;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -65,6 +65,12 @@ PreferencesWidget::PreferencesWidget(const Document *document, QWidget *parent)
|
||||||
Preferences::instance().setFlatShading(flatShadingBox->isChecked());
|
Preferences::instance().setFlatShading(flatShadingBox->isChecked());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QCheckBox *tongShadingBox = new QCheckBox();
|
||||||
|
Theme::initCheckbox(tongShadingBox);
|
||||||
|
connect(tongShadingBox, &QCheckBox::stateChanged, this, [=]() {
|
||||||
|
Preferences::instance().setTongShading(tongShadingBox->isChecked());
|
||||||
|
});
|
||||||
|
|
||||||
QComboBox *textureSizeSelectBox = new QComboBox;
|
QComboBox *textureSizeSelectBox = new QComboBox;
|
||||||
textureSizeSelectBox->addItem("512");
|
textureSizeSelectBox->addItem("512");
|
||||||
textureSizeSelectBox->addItem("1024");
|
textureSizeSelectBox->addItem("1024");
|
||||||
|
@ -78,12 +84,14 @@ PreferencesWidget::PreferencesWidget(const Document *document, QWidget *parent)
|
||||||
formLayout->addRow(tr("Part color:"), colorLayout);
|
formLayout->addRow(tr("Part color:"), colorLayout);
|
||||||
formLayout->addRow(tr("Combine mode:"), combineModeSelectBox);
|
formLayout->addRow(tr("Combine mode:"), combineModeSelectBox);
|
||||||
formLayout->addRow(tr("Flat shading:"), flatShadingBox);
|
formLayout->addRow(tr("Flat shading:"), flatShadingBox);
|
||||||
|
formLayout->addRow(tr("Tong shading:"), tongShadingBox);
|
||||||
formLayout->addRow(tr("Texture size:"), textureSizeSelectBox);
|
formLayout->addRow(tr("Texture size:"), textureSizeSelectBox);
|
||||||
|
|
||||||
auto loadFromPreferences = [=]() {
|
auto loadFromPreferences = [=]() {
|
||||||
updatePickButtonColor();
|
updatePickButtonColor();
|
||||||
combineModeSelectBox->setCurrentIndex((int)Preferences::instance().componentCombineMode());
|
combineModeSelectBox->setCurrentIndex((int)Preferences::instance().componentCombineMode());
|
||||||
flatShadingBox->setChecked(Preferences::instance().flatShading());
|
flatShadingBox->setChecked(Preferences::instance().flatShading());
|
||||||
|
tongShadingBox->setChecked(Preferences::instance().tongShading());
|
||||||
textureSizeSelectBox->setCurrentIndex(
|
textureSizeSelectBox->setCurrentIndex(
|
||||||
textureSizeSelectBox->findText(QString::number(Preferences::instance().textureSize()))
|
textureSizeSelectBox->findText(QString::number(Preferences::instance().textureSize()))
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue