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>
|
||||
<pre>
|
||||
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>
|
||||
|
||||
<h1>David Rosen</h1>
|
||||
|
|
|
@ -86,6 +86,7 @@ uniform samplerCube environmentIrradianceMapId;
|
|||
uniform int environmentIrradianceMapEnabled;
|
||||
uniform samplerCube environmentSpecularMapId;
|
||||
uniform int environmentSpecularMapEnabled;
|
||||
uniform int tongShadingEnabled;
|
||||
|
||||
const int MAX_LIGHTS = 8;
|
||||
const int TYPE_POINT = 0;
|
||||
|
@ -352,6 +353,25 @@ vec3 gammaCorrect(const in vec3 color)
|
|||
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,
|
||||
const in float metalness,
|
||||
const in float roughness,
|
||||
|
@ -365,24 +385,35 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
|||
// Remap roughness for a perceptually more linear correspondence
|
||||
float alpha = remapRoughness(roughness);
|
||||
|
||||
if (environmentIrradianceMapEnabled == 1) {
|
||||
cLinear += pbrIblModel(worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
ambientOcclusion);
|
||||
}
|
||||
if (tongShadingEnabled != 1) {
|
||||
if (environmentIrradianceMapEnabled == 1) {
|
||||
cLinear += pbrIblModel(worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
ambientOcclusion);
|
||||
}
|
||||
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
cLinear += pbrModel(i,
|
||||
worldPosition,
|
||||
worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
ambientOcclusion);
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
cLinear += pbrModel(i,
|
||||
worldPosition,
|
||||
worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
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
|
||||
|
|
|
@ -80,6 +80,7 @@ uniform int ambientOcclusionMapEnabled;
|
|||
uniform int mousePickEnabled;
|
||||
uniform vec3 mousePickTargetPosition;
|
||||
uniform float mousePickRadius;
|
||||
uniform int tongShadingEnabled;
|
||||
|
||||
const int MAX_LIGHTS = 8;
|
||||
const int TYPE_POINT = 0;
|
||||
|
@ -248,6 +249,25 @@ vec3 gammaCorrect(const in vec3 color)
|
|||
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,
|
||||
const in float metalness,
|
||||
const in float roughness,
|
||||
|
@ -261,15 +281,26 @@ vec4 metalRoughFunction(const in vec4 baseColor,
|
|||
// Remap roughness for a perceptually more linear correspondence
|
||||
float alpha = remapRoughness(roughness);
|
||||
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
cLinear += pbrModel(i,
|
||||
worldPosition,
|
||||
worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
ambientOcclusion);
|
||||
if (tongShadingEnabled != 1) {
|
||||
for (int i = 0; i < lightCount; ++i) {
|
||||
cLinear += pbrModel(i,
|
||||
worldPosition,
|
||||
worldNormal,
|
||||
worldView,
|
||||
baseColor.rgb,
|
||||
metalness,
|
||||
alpha,
|
||||
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
|
||||
|
|
|
@ -58,6 +58,7 @@ ModelShaderProgram::ModelShaderProgram(bool isCoreProfile)
|
|||
m_mousePickEnabledLoc = this->uniformLocation("mousePickEnabled");
|
||||
m_mousePickTargetPositionLoc = this->uniformLocation("mousePickTargetPosition");
|
||||
m_mousePickRadiusLoc = this->uniformLocation("mousePickRadius");
|
||||
m_tongShadingEnabledLoc = this->uniformLocation("tongShadingEnabled");
|
||||
if (m_isCoreProfile) {
|
||||
m_environmentIrradianceMapIdLoc = this->uniformLocation("environmentIrradianceMapId");
|
||||
m_environmentIrradianceMapEnabledLoc = this->uniformLocation("environmentIrradianceMapEnabled");
|
||||
|
@ -166,3 +167,7 @@ int ModelShaderProgram::environmentSpecularMapEnabledLoc()
|
|||
return m_environmentSpecularMapEnabledLoc;
|
||||
}
|
||||
|
||||
int ModelShaderProgram::tongShadingEnabledLoc()
|
||||
{
|
||||
return m_tongShadingEnabledLoc;
|
||||
}
|
|
@ -27,6 +27,7 @@ public:
|
|||
int environmentIrradianceMapEnabledLoc();
|
||||
int environmentSpecularMapIdLoc();
|
||||
int environmentSpecularMapEnabledLoc();
|
||||
int tongShadingEnabledLoc();
|
||||
bool isCoreProfile();
|
||||
static const QString &loadShaderSource(const QString &name);
|
||||
private:
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
int m_environmentIrradianceMapEnabledLoc = 0;
|
||||
int m_environmentSpecularMapIdLoc = 0;
|
||||
int m_environmentSpecularMapEnabledLoc = 0;
|
||||
int m_tongShadingEnabledLoc = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include <QSurfaceFormat>
|
||||
#include "modelwidget.h"
|
||||
#include "util.h"
|
||||
#include "preferences.h"
|
||||
|
||||
// Modifed from http://doc.qt.io/qt-5/qtopengl-hellogl2-glwidget-cpp.html
|
||||
|
||||
|
@ -46,6 +47,13 @@ ModelWidget::ModelWidget(QWidget *parent) :
|
|||
}
|
||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
zoom(200);
|
||||
|
||||
connect(&Preferences::instance(), &Preferences::tongShadingChanged, this, &ModelWidget::reRender);
|
||||
}
|
||||
|
||||
void ModelWidget::reRender()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
int ModelWidget::xRot()
|
||||
|
@ -173,6 +181,7 @@ void ModelWidget::paintGL()
|
|||
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);
|
||||
|
||||
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->modelMatrixLoc(), m_world);
|
||||
QMatrix3x3 normalMatrix = m_world.normalMatrix();
|
||||
|
|
|
@ -56,6 +56,7 @@ public slots:
|
|||
void zoom(float delta);
|
||||
void setMousePickTargetPositionInModelSpace(QVector3D position);
|
||||
void setMousePickRadius(float radius);
|
||||
void reRender();
|
||||
signals:
|
||||
void xRotationChanged(int angle);
|
||||
void yRotationChanged(int angle);
|
||||
|
|
|
@ -15,6 +15,7 @@ void Preferences::loadDefault()
|
|||
m_componentCombineMode = CombineMode::Normal;
|
||||
m_partColor = Qt::white;
|
||||
m_flatShading = true;
|
||||
m_tongShading = false;
|
||||
m_textureSize = 1024;
|
||||
}
|
||||
|
||||
|
@ -38,6 +39,13 @@ Preferences::Preferences()
|
|||
else
|
||||
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();
|
||||
if (!value.isEmpty())
|
||||
|
@ -60,6 +68,11 @@ bool Preferences::flatShading() const
|
|||
return m_flatShading;
|
||||
}
|
||||
|
||||
bool Preferences::tongShading() const
|
||||
{
|
||||
return m_tongShading;
|
||||
}
|
||||
|
||||
int Preferences::textureSize() const
|
||||
{
|
||||
return m_textureSize;
|
||||
|
@ -92,6 +105,15 @@ void Preferences::setFlatShading(bool flatShading)
|
|||
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)
|
||||
{
|
||||
if (m_textureSize == textureSize)
|
||||
|
@ -118,5 +140,6 @@ void Preferences::reset()
|
|||
emit componentCombineModeChanged();
|
||||
emit partColorChanged();
|
||||
emit flatShadingChanged();
|
||||
emit tongShadingChanged();
|
||||
emit textureSizeChanged();
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ public:
|
|||
CombineMode componentCombineMode() const;
|
||||
const QColor &partColor() const;
|
||||
bool flatShading() const;
|
||||
bool tongShading() const;
|
||||
QSize documentWindowSize() const;
|
||||
void setDocumentWindowSize(const QSize&);
|
||||
int textureSize() const;
|
||||
|
@ -21,17 +22,20 @@ signals:
|
|||
void componentCombineModeChanged();
|
||||
void partColorChanged();
|
||||
void flatShadingChanged();
|
||||
void tongShadingChanged();
|
||||
void textureSizeChanged();
|
||||
public slots:
|
||||
void setComponentCombineMode(CombineMode mode);
|
||||
void setPartColor(const QColor &color);
|
||||
void setFlatShading(bool flatShading);
|
||||
void setTongShading(bool tongShading);
|
||||
void setTextureSize(int textureSize);
|
||||
void reset();
|
||||
private:
|
||||
CombineMode m_componentCombineMode;
|
||||
QColor m_partColor;
|
||||
bool m_flatShading;
|
||||
bool m_tongShading;
|
||||
QSettings m_settings;
|
||||
int m_textureSize;
|
||||
private:
|
||||
|
|
|
@ -65,6 +65,12 @@ PreferencesWidget::PreferencesWidget(const Document *document, QWidget *parent)
|
|||
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;
|
||||
textureSizeSelectBox->addItem("512");
|
||||
textureSizeSelectBox->addItem("1024");
|
||||
|
@ -78,12 +84,14 @@ PreferencesWidget::PreferencesWidget(const Document *document, QWidget *parent)
|
|||
formLayout->addRow(tr("Part color:"), colorLayout);
|
||||
formLayout->addRow(tr("Combine mode:"), combineModeSelectBox);
|
||||
formLayout->addRow(tr("Flat shading:"), flatShadingBox);
|
||||
formLayout->addRow(tr("Tong shading:"), tongShadingBox);
|
||||
formLayout->addRow(tr("Texture size:"), textureSizeSelectBox);
|
||||
|
||||
auto loadFromPreferences = [=]() {
|
||||
updatePickButtonColor();
|
||||
combineModeSelectBox->setCurrentIndex((int)Preferences::instance().componentCombineMode());
|
||||
flatShadingBox->setChecked(Preferences::instance().flatShading());
|
||||
tongShadingBox->setChecked(Preferences::instance().tongShading());
|
||||
textureSizeSelectBox->setCurrentIndex(
|
||||
textureSizeSelectBox->findText(QString::number(Preferences::instance().textureSize()))
|
||||
);
|
||||
|
|
Loading…
Reference in New Issue