Support transparent texture
Add alpha channel support for color texture. The transparency is supported in render preview, export texture preview and glTF exporter.master
parent
4bd14b935d
commit
1d3c4142d4
|
@ -787,6 +787,10 @@ Tips:
|
|||
<source>Hollow</source>
|
||||
<translation>空心</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Transparency</source>
|
||||
<translation>透明度</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>PoseEditWidget</name>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -1064,7 +1064,7 @@ void Document::toSnapshot(Snapshot *snapshot, const std::set<QUuid> &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())
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -82,6 +82,7 @@ MeshLoader::MeshLoader(const std::vector<QVector3D> &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();
|
||||
|
|
|
@ -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<void *>(3 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
|
||||
|
@ -125,6 +126,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
|
|||
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(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<void *>(3 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
|
||||
|
@ -150,6 +153,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
|
|||
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(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<void *>(3 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(6 * sizeof(GLfloat)));
|
||||
|
@ -175,6 +180,7 @@ void ModelMeshBinder::paint(ModelShaderProgram *program)
|
|||
f->glVertexAttribPointer(4, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(11 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(5, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(12 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(6, 3, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(13 * sizeof(GLfloat)));
|
||||
f->glVertexAttribPointer(7, 1, GL_FLOAT, GL_FALSE, sizeof(ShaderVertex), reinterpret_cast<void *>(16 * sizeof(GLfloat)));
|
||||
m_vboTool.release();
|
||||
} else {
|
||||
m_renderToolVertexCount = 0;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -22,6 +22,7 @@ typedef struct
|
|||
GLfloat tangentX;
|
||||
GLfloat tangentY;
|
||||
GLfloat tangentZ;
|
||||
GLfloat alpha = 1.0;
|
||||
} ShaderVertex;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue