From 26ec1df6a67645805d877de32257f0333b97d8d3 Mon Sep 17 00:00:00 2001 From: Jean Felder Date: Mon, 27 May 2024 14:53:50 +0200 Subject: [PATCH] qgsgoochmaterialsettings: Merge datadefined and constant cases This is similar to the previous QgsPhongMaterialSettings change: This commit makes two changes to `QgsGoochMaterialSettings`: 1. It merges `dataDefinedMaterial()` and `constantColorMaterial` into one new function: `buildMaterial`. 2. There is one fragment shader file called `gooch.frag`. This is achieved by a `#define` logic. If `DATA_DEFINED` is defined, this is the dataDefined case. Otherwise, this is the constant case. --- src/3d/materials/qgsgoochmaterialsettings.cpp | 57 ++++++++++--------- src/3d/materials/qgsgoochmaterialsettings.h | 2 +- src/3d/shaders.qrc | 2 +- .../{goochDataDefined.frag => gooch.frag} | 22 ++++++- 4 files changed, 51 insertions(+), 32 deletions(-) rename src/3d/shaders/{goochDataDefined.frag => gooch.frag} (71%) diff --git a/src/3d/materials/qgsgoochmaterialsettings.cpp b/src/3d/materials/qgsgoochmaterialsettings.cpp index 3be24b33ca73a..8f3afc0f18663 100644 --- a/src/3d/materials/qgsgoochmaterialsettings.cpp +++ b/src/3d/materials/qgsgoochmaterialsettings.cpp @@ -15,6 +15,7 @@ #include "qgsgoochmaterialsettings.h" #include "qgscolorutils.h" +#include "qgs3dutils.h" #include #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) @@ -113,24 +114,7 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::toMaterial( QgsMaterialSettings case QgsMaterialSettingsRenderingTechnique::TrianglesWithFixedTexture: case QgsMaterialSettingsRenderingTechnique::TrianglesFromModel: { - if ( dataDefinedProperties().hasActiveProperties() ) - return dataDefinedMaterial(); - Qt3DExtras::QGoochMaterial *material = new Qt3DExtras::QGoochMaterial; - material->setDiffuse( mDiffuse ); - material->setWarm( mWarm ); - material->setCool( mCool ); - - material->setSpecular( mSpecular ); - material->setShininess( mShininess ); - material->setAlpha( mAlpha ); - material->setBeta( mBeta ); - - if ( context.isSelected() ) - { - // update the material with selection colors - material->setDiffuse( context.selectionColor() ); - } - return material; + return buildMaterial( context ); } case QgsMaterialSettingsRenderingTechnique::Lines: @@ -234,11 +218,11 @@ void QgsGoochMaterialSettings::applyDataDefinedToGeometry( Qt3DQGeometry *geomet dataBuffer->setData( data ); } -Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const +Qt3DRender::QMaterial *QgsGoochMaterialSettings::buildMaterial( const QgsMaterialContext &context ) const { Qt3DRender::QMaterial *material = new Qt3DRender::QMaterial; - Qt3DRender::QEffect *eff = new Qt3DRender::QEffect( material ); + Qt3DRender::QEffect *effect = new Qt3DRender::QEffect( material ); Qt3DRender::QTechnique *technique = new Qt3DRender::QTechnique; technique->graphicsApiFilter()->setApi( Qt3DRender::QGraphicsApiFilter::OpenGL ); @@ -253,11 +237,30 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const Qt3DRender::QRenderPass *renderPass = new Qt3DRender::QRenderPass(); Qt3DRender::QShaderProgram *shaderProgram = new Qt3DRender::QShaderProgram(); - //Load shader programs - const QUrl urlVert( QStringLiteral( "qrc:/shaders/goochDataDefined.vert" ) ); - shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) ); - const QUrl urlFrag( QStringLiteral( "qrc:/shaders/goochDataDefined.frag" ) ); - shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Fragment, Qt3DRender::QShaderProgram::loadSource( urlFrag ) ); + const QByteArray fragmentShaderCode = Qt3DRender::QShaderProgram::loadSource( QUrl( QStringLiteral( "qrc:/shaders/gooch.frag" ) ) ); + + if ( dataDefinedProperties().hasActiveProperties() ) + { + //Load shader programs + const QUrl urlVert( QStringLiteral( "qrc:/shaders/goochDataDefined.vert" ) ); + shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) ); + + const QByteArray finalFragmentShaderCode = Qgs3DUtils::addDefinesToShaderCode( fragmentShaderCode, QStringList( {"DATA_DEFINED"} ) ); + shaderProgram->setFragmentShaderCode( finalFragmentShaderCode ); + } + else + { + //Load shader programs + const QUrl urlVert( QStringLiteral( "qrc:/shaders/default.vert" ) ); + shaderProgram->setShaderCode( Qt3DRender::QShaderProgram::Vertex, Qt3DRender::QShaderProgram::loadSource( urlVert ) ); + shaderProgram->setFragmentShaderCode( fragmentShaderCode ); + + const QColor diffuseColor = context.isSelected() ? context.selectionColor() : mDiffuse; + effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kd" ), diffuseColor ) ); + effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "ks" ), mSpecular ) ); + effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kblue" ), mCool ) ); + effect->addParameter( new Qt3DRender::QParameter( QStringLiteral( "kyellow" ), mWarm ) ); + } renderPass->setShaderProgram( shaderProgram ); technique->addRenderPass( renderPass ); @@ -266,8 +269,8 @@ Qt3DRender::QMaterial *QgsGoochMaterialSettings::dataDefinedMaterial() const technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "alpha" ), mAlpha ) ); technique->addParameter( new Qt3DRender::QParameter( QStringLiteral( "beta" ), mBeta ) ); - eff->addTechnique( technique ); - material->setEffect( eff ); + effect->addTechnique( technique ); + material->setEffect( effect ); return material; } diff --git a/src/3d/materials/qgsgoochmaterialsettings.h b/src/3d/materials/qgsgoochmaterialsettings.h index e31847b79ca33..1537a87e172ac 100644 --- a/src/3d/materials/qgsgoochmaterialsettings.h +++ b/src/3d/materials/qgsgoochmaterialsettings.h @@ -134,7 +134,7 @@ class _3D_EXPORT QgsGoochMaterialSettings : public QgsAbstractMaterialSettings float mBeta = 0.5f; //! Constructs a material from shader files - Qt3DRender::QMaterial *dataDefinedMaterial() const; + Qt3DRender::QMaterial *buildMaterial( const QgsMaterialContext &context ) const; }; diff --git a/src/3d/shaders.qrc b/src/3d/shaders.qrc index 7e1013eaeb63b..7a33d600f801c 100644 --- a/src/3d/shaders.qrc +++ b/src/3d/shaders.qrc @@ -24,7 +24,7 @@ shaders/preview.frag shaders/phongDataDefined.vert shaders/phong.frag - shaders/goochDataDefined.frag + shaders/gooch.frag shaders/goochDataDefined.vert shaders/depth_render.frag shaders/depth_render.vert diff --git a/src/3d/shaders/goochDataDefined.frag b/src/3d/shaders/gooch.frag similarity index 71% rename from src/3d/shaders/goochDataDefined.frag rename to src/3d/shaders/gooch.frag index f196b9fdad2bc..c06ee0ef040cd 100644 --- a/src/3d/shaders/goochDataDefined.frag +++ b/src/3d/shaders/gooch.frag @@ -1,11 +1,18 @@ #version 150 core +#ifdef DATA_DEFINED in DataColor { vec3 diffuse; vec3 warm; vec3 cool; vec3 specular; } vs_in; +#else +uniform vec3 kd; // Diffuse reflectivity +uniform vec3 ks; // Specular reflectivity +uniform vec3 kblue; // Cool color +uniform vec3 kyellow; // Warm color +#endif uniform float alpha; // Fraction of diffuse added to kblue @@ -27,8 +34,13 @@ vec3 goochModel( const in vec3 pos, const in vec3 n ) // http://www.cs.northwestern.edu/~ago820/SIG98/abstract.html // Calculate kcool and kwarm from equation (3) - vec3 kcool = clamp(vs_in.cool + alpha * vs_in.diffuse, 0.0, 1.0); - vec3 kwarm = clamp(vs_in.warm + beta * vs_in.diffuse, 0.0, 1.0); + #ifdef DATA_DEFINED + vec3 kcool = clamp(vs_in.cool + alpha * vs_in.diffuse, 0.0, 1.0); + vec3 kwarm = clamp(vs_in.warm + beta * vs_in.diffuse, 0.0, 1.0); + #else + vec3 kcool = clamp(kblue + alpha * kd, 0.0, 1.0); + vec3 kwarm = clamp(kyellow + beta * kd, 0.0, 1.0); + #endif vec3 result = vec3(0.0); for (int i = 0; i < lightCount; ++i) { @@ -54,7 +66,11 @@ vec3 goochModel( const in vec3 pos, const in vec3 n ) specular = pow( max( dot( r, v ), 0.0 ), shininess ); // Sum the blended tone and specular highlight - result += intensity + vs_in.specular * specular; + #ifdef DATA_DEFINED + result += intensity + vs_in.specular * specular; + #else + result += intensity + ks * specular; + #endif } return result;