diff --git a/languages/dust3d_zh_CN.ts b/languages/dust3d_zh_CN.ts
index 9543f7e5..3d4309c9 100644
--- a/languages/dust3d_zh_CN.ts
+++ b/languages/dust3d_zh_CN.ts
@@ -787,6 +787,10 @@ Tips:
空心
+
+
+ 透明度
+
PoseEditWidget
diff --git a/shaders/default.vert b/shaders/default.vert
index 2c3a575e..f0ccbf7c 100644
--- a/shaders/default.vert
+++ b/shaders/default.vert
@@ -1,25 +1,27 @@
-attribute vec4 vertex;
-attribute vec3 normal;
-attribute vec3 color;
-attribute vec2 texCoord;
-attribute float metalness;
-attribute float roughness;
-attribute vec3 tangent;
-varying vec3 vert;
-varying vec3 vertRaw;
-varying vec3 vertNormal;
-varying vec3 vertColor;
-varying vec2 vertTexCoord;
-varying float vertMetalness;
-varying float vertRoughness;
-varying vec3 cameraPos;
-varying vec3 firstLightPos;
-varying vec3 secondLightPos;
-varying vec3 thirdLightPos;
-uniform mat4 projectionMatrix;
-uniform mat4 modelMatrix;
-uniform mat3 normalMatrix;
-uniform mat4 viewMatrix;
+attribute highp vec4 vertex;
+attribute highp vec3 normal;
+attribute highp vec3 color;
+attribute highp vec2 texCoord;
+attribute highp float metalness;
+attribute highp float roughness;
+attribute highp vec3 tangent;
+attribute highp float alpha;
+varying highp vec3 vert;
+varying highp vec3 vertRaw;
+varying highp vec3 vertNormal;
+varying highp vec3 vertColor;
+varying highp vec2 vertTexCoord;
+varying highp float vertMetalness;
+varying highp float vertRoughness;
+varying highp vec3 cameraPos;
+varying highp vec3 firstLightPos;
+varying highp vec3 secondLightPos;
+varying highp vec3 thirdLightPos;
+varying highp float vertAlpha;
+uniform highp mat4 projectionMatrix;
+uniform highp mat4 modelMatrix;
+uniform highp mat3 normalMatrix;
+uniform highp mat4 viewMatrix;
uniform highp int normalMapEnabled;
mat3 transpose(mat3 m)
@@ -35,6 +37,7 @@ void main()
vertRaw = vert;
vertNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
vertColor = color;
+ vertAlpha = alpha;
cameraPos = vec3(0, 0, -4.0);
firstLightPos = vec3(5.0, 5.0, 5.0);
diff --git a/shaders/pbr-qt.frag b/shaders/pbr-qt.frag
index d85877f9..773b1291 100644
--- a/shaders/pbr-qt.frag
+++ b/shaders/pbr-qt.frag
@@ -67,6 +67,7 @@ varying highp vec3 cameraPos;
varying highp vec3 firstLightPos;
varying highp vec3 secondLightPos;
varying highp vec3 thirdLightPos;
+varying highp float vertAlpha;
uniform highp vec3 lightPos;
uniform highp sampler2D textureId;
uniform highp int textureEnabled;
@@ -280,7 +281,7 @@ highp vec4 metalRoughFunction(const in highp vec4 baseColor,
// Apply gamma correction prior to display
highp vec3 cGamma = gammaCorrect(cToneMapped);
- return vec4(cGamma, 1.0);
+ return vec4(cGamma, baseColor.a);
}
void main()
@@ -321,8 +322,11 @@ void main()
lights[2].quadraticAttenuation = 0.0;
highp vec3 color = vertColor;
+ highp float alpha = vertAlpha;
if (textureEnabled == 1) {
- color = texture2D(textureId, vertTexCoord).rgb;
+ highp vec4 textColor = texture2D(textureId, vertTexCoord);
+ color = textColor.rgb;
+ alpha = textColor.a;
}
if (mousePickEnabled == 1) {
if (distance(mousePickTargetPosition, vertRaw) <= mousePickRadius) {
@@ -358,7 +362,7 @@ void main()
roughness = min(0.99, roughness);
- gl_FragColor = metalRoughFunction(vec4(color, 1.0),
+ gl_FragColor = metalRoughFunction(vec4(color, alpha),
metalness,
roughness,
ambientOcclusion,
diff --git a/src/document.cpp b/src/document.cpp
index b8d9ae31..a2328ec2 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1064,7 +1064,7 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set &limitNodeId
}
part["dirty"] = partIt.second.dirty ? "true" : "false";
if (partIt.second.hasColor)
- part["color"] = partIt.second.color.name();
+ part["color"] = partIt.second.color.name(QColor::HexArgb);
if (partIt.second.colorSolubilityAdjusted())
part["colorSolubility"] = QString::number(partIt.second.colorSolubility);
if (partIt.second.deformThicknessAdjusted())
diff --git a/src/glbfile.cpp b/src/glbfile.cpp
index 016ff485..8c4616ae 100644
--- a/src/glbfile.cpp
+++ b/src/glbfile.cpp
@@ -169,6 +169,7 @@ GlbFileWriter::GlbFileWriter(Outcome &outcome,
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorTexture"]["index"] = textureIndex++;
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = MeshLoader::m_defaultMetalness;
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = MeshLoader::m_defaultRoughness;
+ m_json["materials"][primitiveIndex]["alphaMode"] = "BLEND";
if (normalImage) {
m_json["materials"][primitiveIndex]["normalTexture"]["index"] = textureIndex++;
}
diff --git a/src/meshloader.cpp b/src/meshloader.cpp
index 6ef87d4e..f1c45ee2 100644
--- a/src/meshloader.cpp
+++ b/src/meshloader.cpp
@@ -82,6 +82,7 @@ MeshLoader::MeshLoader(const std::vector &vertices, const std::vector
dest->colorR = color.redF();
dest->colorG = color.greenF();
dest->colorB = color.blueF();
+ dest->alpha = color.alphaF();
dest->posX = srcVert->x();
dest->posY = srcVert->y();
dest->posZ = srcVert->z();
@@ -138,6 +139,7 @@ MeshLoader::MeshLoader(Outcome &outcome) :
dest->colorR = triangleColor->redF();
dest->colorG = triangleColor->greenF();
dest->colorB = triangleColor->blueF();
+ dest->alpha = triangleColor->alphaF();
dest->posX = srcVert->x();
dest->posY = srcVert->y();
dest->posZ = srcVert->z();
@@ -155,7 +157,6 @@ MeshLoader::MeshLoader(Outcome &outcome) :
}
}
- // Uncomment out to show wireframes
size_t edgeCount = 0;
for (const auto &face: outcome.triangleAndQuads) {
edgeCount += face.size();
diff --git a/src/modelmeshbinder.cpp b/src/modelmeshbinder.cpp
index 061f41b3..2564af45 100644
--- a/src/modelmeshbinder.cpp
+++ b/src/modelmeshbinder.cpp
@@ -118,6 +118,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glEnableVertexAttribArray(4);
f->glEnableVertexAttribArray(5);
f->glEnableVertexAttribArray(6);
+ f->glEnableVertexAttribArray(7);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(6 * sizeof(GLfloat)));
@@ -125,6 +126,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(11 * sizeof(GLfloat)));
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(12 * sizeof(GLfloat)));
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(13 * sizeof(GLfloat)));
+ f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(16 * sizeof(GLfloat)));
m_vboTriangle.release();
}
{
@@ -143,6 +145,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glEnableVertexAttribArray(4);
f->glEnableVertexAttribArray(5);
f->glEnableVertexAttribArray(6);
+ f->glEnableVertexAttribArray(7);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(6 * sizeof(GLfloat)));
@@ -150,6 +153,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(11 * sizeof(GLfloat)));
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(12 * sizeof(GLfloat)));
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(13 * sizeof(GLfloat)));
+ f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(16 * sizeof(GLfloat)));
m_vboEdge.release();
}
if (m_toolEnabled) {
@@ -168,6 +172,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glEnableVertexAttribArray(4);
f->glEnableVertexAttribArray(5);
f->glEnableVertexAttribArray(6);
+ f->glEnableVertexAttribArray(7);
f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), 0);
f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(3 * sizeof(GLfloat)));
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(6 * sizeof(GLfloat)));
@@ -175,6 +180,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(11 * sizeof(GLfloat)));
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(12 * sizeof(GLfloat)));
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(13 * sizeof(GLfloat)));
+ f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast(16 * sizeof(GLfloat)));
m_vboTool.release();
} else {
m_renderToolVertexCount = 0;
diff --git a/src/modelshaderprogram.cpp b/src/modelshaderprogram.cpp
index 1f3f80f2..fdde882d 100644
--- a/src/modelshaderprogram.cpp
+++ b/src/modelshaderprogram.cpp
@@ -37,6 +37,7 @@ ModelShaderProgram::ModelShaderProgram(bool usePBR)
this->bindAttributeLocation("metalness", 4);
this->bindAttributeLocation("roughness", 5);
this->bindAttributeLocation("tangent", 6);
+ this->bindAttributeLocation("alpha", 7);
this->link();
this->bind();
diff --git a/src/modelwidget.cpp b/src/modelwidget.cpp
index 64fb4175..e1d47f9b 100644
--- a/src/modelwidget.cpp
+++ b/src/modelwidget.cpp
@@ -146,6 +146,8 @@ void ModelWidget::initializeGL()
void ModelWidget::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
#ifdef GL_LINE_SMOOTH
diff --git a/src/partwidget.cpp b/src/partwidget.cpp
index 7432402c..2d63773b 100644
--- a/src/partwidget.cpp
+++ b/src/partwidget.cpp
@@ -376,11 +376,44 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
QColor color = QColorDialog::getColor(part->color, this);
emit enableBackgroundBlur();
if (color.isValid()) {
+ const SkeletonPart *part = m_document->findPart(m_partId);
+ if (nullptr == part) {
+ return;
+ }
+ color.setAlphaF(part->color.alphaF());
emit setPartColorState(m_partId, true, color);
emit groupOperationAdded();
}
});
+ FloatNumberWidget *colorTransparencyWidget = new FloatNumberWidget;
+ colorTransparencyWidget->setItemName(tr("Transparency"));
+ colorTransparencyWidget->setRange(0.0, 1.0);
+ colorTransparencyWidget->setValue(1.0 - part->color.alphaF());
+
+ connect(colorTransparencyWidget, &FloatNumberWidget::valueChanged, [=](float value) {
+ const SkeletonPart *part = m_document->findPart(m_partId);
+ if (nullptr == part) {
+ return;
+ }
+ QColor color = part->color;
+ color.setAlphaF(1.0 - value);
+ emit setPartColorState(m_partId, true, color);
+ emit groupOperationAdded();
+ });
+
+ QPushButton *colorTransparencyEraser = new QPushButton(QChar(fa::eraser));
+ initToolButton(colorTransparencyEraser);
+
+ connect(colorTransparencyEraser, &QPushButton::clicked, [=]() {
+ colorTransparencyWidget->setValue(0.0);
+ emit groupOperationAdded();
+ });
+
+ QHBoxLayout *colorTransparencyLayout = new QHBoxLayout;
+ colorTransparencyLayout->addWidget(colorTransparencyEraser);
+ colorTransparencyLayout->addWidget(colorTransparencyWidget);
+
FloatNumberWidget *colorSolubilityWidget = new FloatNumberWidget;
colorSolubilityWidget->setItemName(tr("Solubility"));
colorSolubilityWidget->setRange(0.0, 1.0);
@@ -405,6 +438,7 @@ void PartWidget::showColorSettingPopup(const QPoint &pos)
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addLayout(colorLayout);
+ mainLayout->addLayout(colorTransparencyLayout);
mainLayout->addLayout(colorSolubilityLayout);
if (m_document->materialIdList.empty()) {
diff --git a/src/shadervertex.h b/src/shadervertex.h
index e3cbd7b4..c6bd976d 100644
--- a/src/shadervertex.h
+++ b/src/shadervertex.h
@@ -22,6 +22,7 @@ typedef struct
GLfloat tangentX;
GLfloat tangentY;
GLfloat tangentZ;
+ GLfloat alpha = 1.0;
} ShaderVertex;
#pragma pack(pop)
diff --git a/src/texturegenerator.cpp b/src/texturegenerator.cpp
index 86917b0c..666c1004 100644
--- a/src/texturegenerator.cpp
+++ b/src/texturegenerator.cpp
@@ -11,7 +11,7 @@
#include "material.h"
int TextureGenerator::m_textureSize = 1024;
-QColor TextureGenerator::m_defaultTextureColor = Qt::white; //Qt::darkGray;
+QColor TextureGenerator::m_defaultTextureColor = Qt::transparent; //Qt::darkGray;
TextureGenerator::TextureGenerator(const Outcome &outcome, Snapshot *snapshot) :
m_resultTextureGuideImage(nullptr),
@@ -540,11 +540,22 @@ void TextureGenerator::generate()
m_resultTextureImage = new QImage(*m_resultTextureColorImage);
+ QImage uvCheckImage(":/resources/checkuv.png");
+
m_resultTextureGuideImage = new QImage(*m_resultTextureImage);
- QPainter mergeTextureGuidePainter(m_resultTextureGuideImage);
- mergeTextureGuidePainter.setCompositionMode(QPainter::CompositionMode_Multiply);
- mergeTextureGuidePainter.drawImage(0, 0, *m_resultTextureBorderImage);
- mergeTextureGuidePainter.end();
+ {
+ QPainter mergeTextureGuidePainter(m_resultTextureGuideImage);
+ mergeTextureGuidePainter.setCompositionMode(QPainter::CompositionMode_DestinationOver);
+ mergeTextureGuidePainter.drawImage(0, 0, uvCheckImage);
+ mergeTextureGuidePainter.end();
+ }
+
+ {
+ QPainter mergeTextureGuidePainter(m_resultTextureGuideImage);
+ mergeTextureGuidePainter.setCompositionMode(QPainter::CompositionMode_Multiply);
+ mergeTextureGuidePainter.drawImage(0, 0, *m_resultTextureBorderImage);
+ mergeTextureGuidePainter.end();
+ }
auto createResultBeginTime = countTimeConsumed.elapsed();
m_resultMesh = new MeshLoader(*m_outcome);