mirror of
https://github.com/alicevision/Meshroom.git
synced 2025-08-06 10:18:42 +02:00
[ui] Viewer3D: introduce SphericalHarmonics shader + display mode
Add experimental render mode to display model normals or shading based on spherical harmonics coefficients
This commit is contained in:
parent
9aa059a565
commit
3ae95869bd
7 changed files with 194 additions and 1 deletions
|
@ -3,6 +3,7 @@ import Qt3D.Render 2.9
|
||||||
import Qt3D.Input 2.0
|
import Qt3D.Input 2.0
|
||||||
import Qt3D.Extras 2.10
|
import Qt3D.Extras 2.10
|
||||||
import QtQuick 2.0
|
import QtQuick 2.0
|
||||||
|
import Utils 1.0
|
||||||
import "Materials"
|
import "Materials"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,6 +68,10 @@ Entity {
|
||||||
// "textured" material resolution order: diffuse map > vertex color data > no color info
|
// "textured" material resolution order: diffuse map > vertex color data > no color info
|
||||||
material: diffuseMap ? textured : (Scene3DHelper.vertexColorCount(root.parent) ? colored : solid)
|
material: diffuseMap ? textured : (Scene3DHelper.vertexColorCount(root.parent) ? colored : solid)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
State {
|
||||||
|
name: "Spherical Harmonics"
|
||||||
|
PropertyChanges { target: m; material: shMaterial }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -112,4 +117,11 @@ Entity {
|
||||||
specular: root.specular
|
specular: root.specular
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SphericalHarmonicsMaterial {
|
||||||
|
id: shMaterial
|
||||||
|
objectName: "SphericalHarmonicsMaterial"
|
||||||
|
effect: SphericalHarmonicsEffect {}
|
||||||
|
shlSource: Filepath.stringToUrl(Viewer3DSettings.shlFile)
|
||||||
|
displayNormals: Viewer3DSettings.displayNormals
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import Qt3D.Core 2.0
|
||||||
|
import Qt3D.Render 2.0
|
||||||
|
|
||||||
|
Effect {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
|
||||||
|
parameters: [
|
||||||
|
Parameter { name: "shCoeffs[0]"; value: [] },
|
||||||
|
Parameter { name: "displayNormals"; value: false }
|
||||||
|
]
|
||||||
|
|
||||||
|
techniques: [
|
||||||
|
Technique {
|
||||||
|
graphicsApiFilter {
|
||||||
|
api: GraphicsApiFilter.OpenGL
|
||||||
|
profile: GraphicsApiFilter.CoreProfile
|
||||||
|
majorVersion: 3
|
||||||
|
minorVersion: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
filterKeys: [ FilterKey { name: "renderingStyle"; value: "forward" } ]
|
||||||
|
|
||||||
|
renderPasses: [
|
||||||
|
RenderPass {
|
||||||
|
shaderProgram: ShaderProgram {
|
||||||
|
vertexShaderCode: loadSource(Qt.resolvedUrl("shaders/SphericalHarmonics.vert"))
|
||||||
|
fragmentShaderCode: loadSource(Qt.resolvedUrl("shaders/SphericalHarmonics.frag"))
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import Qt3D.Core 2.0
|
||||||
|
import Qt3D.Render 2.0
|
||||||
|
import Utils 1.0
|
||||||
|
|
||||||
|
Material {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
/// Source file containing coefficients
|
||||||
|
property url shlSource
|
||||||
|
/// Spherical Harmonics coefficients (array of 9 vector3d)
|
||||||
|
property var coefficients: noCoeffs
|
||||||
|
/// Whether to display normals instead of SH
|
||||||
|
property bool displayNormals: false
|
||||||
|
|
||||||
|
// default coefficients (uniform magenta)
|
||||||
|
readonly property var noCoeffs: [
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(1.0, 0.0, 1.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0),
|
||||||
|
Qt.vector3d(0.0, 0.0, 0.0)
|
||||||
|
]
|
||||||
|
|
||||||
|
effect: SphericalHarmonicsEffect {}
|
||||||
|
|
||||||
|
onShlSourceChanged: {
|
||||||
|
if(!shlSource) {
|
||||||
|
coefficients = noCoeffs;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Request.get(Filepath.urlToString(shlSource), function(xhr) {
|
||||||
|
if(xhr.readyState === XMLHttpRequest.DONE) {
|
||||||
|
var coeffs = [];
|
||||||
|
var lines = xhr.responseText.split("\n");
|
||||||
|
lines.forEach(function(l){
|
||||||
|
var lineCoeffs = [];
|
||||||
|
l.split(" ").forEach(function(v){
|
||||||
|
if(v) { lineCoeffs.push(v); }
|
||||||
|
})
|
||||||
|
if(lineCoeffs.length == 3)
|
||||||
|
coeffs.push(Qt.vector3d(lineCoeffs[0], lineCoeffs[1], lineCoeffs[2]));
|
||||||
|
});
|
||||||
|
|
||||||
|
if(coeffs.length == 9) {
|
||||||
|
coefficients = coeffs;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
console.warn("Invalid SHL file: " + shlSource + " with " + coeffs.length + " coefficients.");
|
||||||
|
coefficients = noCoeffs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters: [
|
||||||
|
Parameter { name: "shCoeffs[0]"; value: coefficients },
|
||||||
|
Parameter { name: "displayNormals"; value: displayNormals }
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 normal;
|
||||||
|
out vec4 fragColor;
|
||||||
|
|
||||||
|
uniform vec3 shCoeffs[9];
|
||||||
|
uniform bool displayNormals = false;
|
||||||
|
|
||||||
|
vec3 resolveSH_Opt(vec3 premulCoefficients[9], vec3 dir)
|
||||||
|
{
|
||||||
|
vec3 result = premulCoefficients[0] * dir.x;
|
||||||
|
result += premulCoefficients[1] * dir.y;
|
||||||
|
result += premulCoefficients[2] * dir.z;
|
||||||
|
result += premulCoefficients[3];
|
||||||
|
vec3 dirSq = dir * dir;
|
||||||
|
result += premulCoefficients[4] * (dir.x * dir.y);
|
||||||
|
result += premulCoefficients[5] * (dir.x * dir.z);
|
||||||
|
result += premulCoefficients[6] * (dir.y * dir.z);
|
||||||
|
result += premulCoefficients[7] * (dirSq.x - dirSq.y);
|
||||||
|
result += premulCoefficients[8] * (3 * dirSq.z - 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
if(displayNormals) {
|
||||||
|
// Display normals mode
|
||||||
|
fragColor = vec4(normal, 1.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Calculate the color from spherical harmonics coeffs
|
||||||
|
fragColor = vec4(resolveSH_Opt(shCoeffs, normal), 1.0);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
#version 330 core
|
||||||
|
|
||||||
|
in vec3 vertexPosition;
|
||||||
|
in vec3 vertexNormal;
|
||||||
|
|
||||||
|
out vec3 normal;
|
||||||
|
|
||||||
|
uniform mat4 modelView;
|
||||||
|
uniform mat3 modelViewNormal;
|
||||||
|
uniform mat4 mvp;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
normal = vertexNormal;
|
||||||
|
gl_Position = mvp * vec4( vertexPosition, 1.0 );
|
||||||
|
}
|
|
@ -77,7 +77,7 @@ FocusScope {
|
||||||
if (event.key == Qt.Key_F) {
|
if (event.key == Qt.Key_F) {
|
||||||
resetCameraPosition();
|
resetCameraPosition();
|
||||||
}
|
}
|
||||||
else if(Qt.Key_1 <= event.key && event.key <= Qt.Key_3)
|
else if(Qt.Key_1 <= event.key && event.key < Qt.Key_1 + Viewer3DSettings.renderModes.length)
|
||||||
{
|
{
|
||||||
Viewer3DSettings.renderMode = event.key - Qt.Key_1;
|
Viewer3DSettings.renderMode = event.key - Qt.Key_1;
|
||||||
}
|
}
|
||||||
|
@ -274,8 +274,34 @@ FocusScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FloatingPane {
|
||||||
|
visible: Viewer3DSettings.renderMode == 3
|
||||||
|
anchors.bottom: renderModesPanel.top
|
||||||
|
GridLayout {
|
||||||
|
columns: 2
|
||||||
|
rowSpacing: 0
|
||||||
|
|
||||||
|
RadioButton { text: "SHL File"; autoExclusive: true; checked: true }
|
||||||
|
TextField {
|
||||||
|
text: Viewer3DSettings.shlFile
|
||||||
|
selectByMouse: true
|
||||||
|
Layout.minimumWidth: 300
|
||||||
|
onEditingFinished: Viewer3DSettings.shlFile = text
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioButton {
|
||||||
|
Layout.columnSpan: 2
|
||||||
|
autoExclusive: true
|
||||||
|
text: "Normals"
|
||||||
|
onCheckedChanged: Viewer3DSettings.displayNormals = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Rendering modes
|
// Rendering modes
|
||||||
FloatingPane {
|
FloatingPane {
|
||||||
|
id: renderModesPanel
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
padding: 4
|
padding: 4
|
||||||
Row {
|
Row {
|
||||||
|
|
|
@ -26,10 +26,16 @@ Item {
|
||||||
{"name": "Solid", "icon": MaterialIcons.crop_din },
|
{"name": "Solid", "icon": MaterialIcons.crop_din },
|
||||||
{"name": "Wireframe", "icon": MaterialIcons.details },
|
{"name": "Wireframe", "icon": MaterialIcons.details },
|
||||||
{"name": "Textured", "icon": MaterialIcons.texture },
|
{"name": "Textured", "icon": MaterialIcons.texture },
|
||||||
|
{"name": "Spherical Harmonics", "icon": MaterialIcons.brightness_7}
|
||||||
]
|
]
|
||||||
// Current render mode
|
// Current render mode
|
||||||
property int renderMode: 2
|
property int renderMode: 2
|
||||||
|
|
||||||
|
// Spherical Harmonics file
|
||||||
|
property string shlFile: ""
|
||||||
|
// Whether to display normals
|
||||||
|
property bool displayNormals: false
|
||||||
|
|
||||||
// Rasterized point size
|
// Rasterized point size
|
||||||
property real pointSize: 1.5
|
property real pointSize: 1.5
|
||||||
// Whether point size is fixed or view dependent
|
// Whether point size is fixed or view dependent
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue