diff --git a/dust3d.pro b/dust3d.pro
index 60f56e1d..c4fc6ba1 100644
--- a/dust3d.pro
+++ b/dust3d.pro
@@ -224,6 +224,27 @@ HEADERS += src/motionpreviewsgenerator.h
SOURCES += src/animationclipplayer.cpp
HEADERS += src/animationclipplayer.h
+SOURCES += src/texturetype.cpp
+HEADERS += src/texturetype.h
+
+SOURCES += src/imageforever.cpp
+HEADERS += src/imageforever.h
+
+SOURCES += src/materialeditwidget.cpp
+HEADERS += src/materialeditwidget.h
+
+SOURCES += src/materiallistwidget.cpp
+HEADERS += src/materiallistwidget.h
+
+SOURCES += src/materialmanagewidget.cpp
+HEADERS += src/materialmanagewidget.h
+
+SOURCES += src/materialpreviewsgenerator.cpp
+HEADERS += src/materialpreviewsgenerator.h
+
+SOURCES += src/materialwidget.cpp
+HEADERS += src/materialwidget.h
+
SOURCES += src/main.cpp
HEADERS += src/version.h
diff --git a/resources.qrc b/resources.qrc
index 12c324c5..ea6258e0 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -6,6 +6,7 @@
resources/tree-branch-more.png
resources/tree-branch-open.png
resources/tree-vline.png
+ resources/material-demo-model.ds3
shaders/default.vert
shaders/default.frag
shaders/default.core.vert
diff --git a/resources/material-demo-model.ds3 b/resources/material-demo-model.ds3
new file mode 100644
index 00000000..be193198
Binary files /dev/null and b/resources/material-demo-model.ds3 differ
diff --git a/shaders/default.core.vert b/shaders/default.core.vert
index 876b2ba6..c607e107 100644
--- a/shaders/default.core.vert
+++ b/shaders/default.core.vert
@@ -5,6 +5,7 @@ in vec3 color;
in vec2 texCoord;
in float metalness;
in float roughness;
+in vec3 tangent;
out vec3 vert;
out vec3 vertNormal;
out vec3 vertColor;
diff --git a/shaders/default.vert b/shaders/default.vert
index dae66df8..1145ccd5 100644
--- a/shaders/default.vert
+++ b/shaders/default.vert
@@ -4,6 +4,7 @@ attribute vec3 color;
attribute vec2 texCoord;
attribute float metalness;
attribute float roughness;
+attribute vec3 tangent;
varying vec3 vert;
varying vec3 vertNormal;
varying vec3 vertColor;
@@ -11,17 +12,50 @@ 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;
+uniform highp int normalMapEnabled;
+
+mat3 transpose(mat3 m)
+{
+ return mat3(m[0][0], m[1][0], m[2][0],
+ m[0][1], m[1][1], m[2][1],
+ m[0][2], m[1][2], m[2][2]);
+}
+
void main()
{
vert = (modelMatrix * vertex).xyz;
vertNormal = normalize((modelMatrix * vec4(normal, 1.0)).xyz);
vertColor = color;
+ cameraPos = vec3(0, 0, -2.1);
+
+ firstLightPos = vec3(5.0, 5.0, 5.0);
+ secondLightPos = vec3(-5.0, 5.0, 5.0);
+ thirdLightPos = vec3(0.0, -5.0, -5.0);
+
+ gl_Position = projectionMatrix * viewMatrix * vec4(vert, 1.0);
+
+ if (normalMapEnabled == 1) {
+ vec3 T = normalize(normalMatrix * tangent);
+ vec3 N = normalize(normalMatrix * normal);
+ T = normalize(T - dot(T, N) * N);
+ vec3 B = cross(N, T);
+
+ mat3 TBN = transpose(mat3(T, B, N));
+ firstLightPos = TBN * firstLightPos;
+ secondLightPos = TBN * secondLightPos;
+ thirdLightPos = TBN * thirdLightPos;
+ cameraPos = TBN * cameraPos;
+ vert = TBN * vert;
+ }
+
vertTexCoord = texCoord;
vertMetalness = metalness;
vertRoughness = roughness;
- cameraPos = vec3(0, 0, -2.1);
- gl_Position = projectionMatrix * viewMatrix * vec4(vert, 1.0);
}
\ No newline at end of file
diff --git a/shaders/pbr-qt.frag b/shaders/pbr-qt.frag
index 22f603d1..ee15bfcd 100644
--- a/shaders/pbr-qt.frag
+++ b/shaders/pbr-qt.frag
@@ -63,9 +63,18 @@ varying highp vec2 vertTexCoord;
varying highp float vertMetalness;
varying highp float vertRoughness;
varying highp vec3 cameraPos;
+varying vec3 firstLightPos;
+varying vec3 secondLightPos;
+varying vec3 thirdLightPos;
uniform highp vec3 lightPos;
uniform highp sampler2D textureId;
uniform highp int textureEnabled;
+uniform highp sampler2D normalMapId;
+uniform highp int normalMapEnabled;
+uniform highp sampler2D metalnessRoughnessAmbientOcclusionMapId;
+uniform highp int metalnessMapEnabled;
+uniform highp int roughnessMapEnabled;
+uniform highp int ambientOcclusionMapEnabled;
const int MAX_LIGHTS = 8;
const int TYPE_POINT = 0;
@@ -275,7 +284,6 @@ void main()
// FIXME: don't hard code here
exposure = 0.0;
gamma = 2.2;
- const highp float vertAmbientOcclusion = 1.0;
// Light settings:
// https://doc-snapshots.qt.io/qt5-5.12/qt3d-pbr-materials-lights-qml.html
@@ -283,7 +291,7 @@ void main()
// Key light
lights[0].type = TYPE_POINT;
- lights[0].position = vec3(5.0, 5.0, 5.0);
+ lights[0].position = firstLightPos;
lights[0].color = vec3(0.588, 0.588, 0.588);
lights[0].intensity = 5.0;
lights[0].constantAttenuation = 0.0;
@@ -292,7 +300,7 @@ void main()
// Fill light
lights[1].type = TYPE_POINT;
- lights[1].position = vec3(-5.0, 5.0, 5.0);
+ lights[1].position = secondLightPos;
lights[1].color = vec3(0.588, 0.588, 0.588);
lights[1].intensity = 3.0;
lights[1].constantAttenuation = 0.0;
@@ -301,7 +309,7 @@ void main()
// Rim light
lights[2].type = TYPE_POINT;
- lights[2].position = vec3(0.0, -5.0, -5.0);
+ lights[2].position = thirdLightPos;
lights[2].color = vec3(0.588, 0.588, 0.588);
lights[2].intensity = 2.5;
lights[2].constantAttenuation = 0.0;
@@ -314,13 +322,34 @@ void main()
}
color = pow(color, vec3(gamma));
- float roughness = min(0.99, vertRoughness);
+ highp vec3 normal = vertNormal;
+ if (normalMapEnabled == 1) {
+ normal = texture2D(normalMapId, vertTexCoord).rgb;
+ normal = normalize(normal * 2.0 - 1.0);
+ }
+
+ float metalness = vertMetalness;
+ if (metalnessMapEnabled == 1) {
+ metalness = texture2D(metalnessRoughnessAmbientOcclusionMapId, vertTexCoord).b / 255.0;
+ }
+
+ float roughness = vertRoughness;
+ if (roughnessMapEnabled == 1) {
+ roughness = texture2D(metalnessRoughnessAmbientOcclusionMapId, vertTexCoord).r / 255.0;
+ }
+
+ float ambientOcclusion = 1.0;
+ if (ambientOcclusionMapEnabled == 1) {
+ ambientOcclusion = texture2D(metalnessRoughnessAmbientOcclusionMapId, vertTexCoord).g / 255.0;
+ }
+
+ roughness = min(0.99, roughness);
gl_FragColor = metalRoughFunction(vec4(color, 1.0),
- vertMetalness,
+ metalness,
roughness,
- vertAmbientOcclusion,
+ ambientOcclusion,
vert,
normalize(cameraPos - vert),
- vertNormal);
+ normal);
}
diff --git a/src/ambientocclusionbaker.cpp b/src/ambientocclusionbaker.cpp
index a431990c..1bfb6cff 100644
--- a/src/ambientocclusionbaker.cpp
+++ b/src/ambientocclusionbaker.cpp
@@ -143,6 +143,7 @@ void AmbientOcclusionBaker::process()
m_resultMesh = new MeshLoader(m_meshResultContext);
m_resultMesh->setTextureImage(new QImage(*m_textureImage));
+ //m_resultMesh->setNormalMapImage(new QImage(*m_textureImage));
}
this->moveToThread(QGuiApplication::instance()->thread());
diff --git a/src/gltffile.cpp b/src/gltffile.cpp
index cffed23e..a25ab188 100644
--- a/src/gltffile.cpp
+++ b/src/gltffile.cpp
@@ -8,6 +8,7 @@
#include "version.h"
#include "dust3dutil.h"
#include "jointnodetree.h"
+#include "meshloader.h"
// Play with glTF online:
// https://gltf-viewer.donmccurdy.com/
@@ -157,8 +158,8 @@ GltfFileWriter::GltfFileWriter(MeshResultContext &resultContext,
m_json["meshes"][0]["primitives"][primitiveIndex]["attributes"]["WEIGHTS_0"] = bufferViewIndex + (++attributeIndex);
}
m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["baseColorTexture"]["index"] = 0;
- m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = part.second.material.metalness;
- m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = part.second.material.roughness;
+ m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["metallicFactor"] = MeshLoader::m_defaultMetalness;
+ m_json["materials"][primitiveIndex]["pbrMetallicRoughness"]["roughnessFactor"] = MeshLoader::m_defaultRoughness;
primitiveIndex++;
diff --git a/src/imageforever.cpp b/src/imageforever.cpp
new file mode 100644
index 00000000..d58a885f
--- /dev/null
+++ b/src/imageforever.cpp
@@ -0,0 +1,41 @@
+#include