in qt3D can not use custom QMaterial on QEntity, why?
-
i use a customs QMaterial move to an entity,but Show blank. when i use QPhongMaterial, it worked。this is my codes:
Qt3DCore::QEntity* createTorusWithGradient(Qt3DCore::QEntity* rootEntity)
{
Qt3DCore::QEntity* torusEntity = new Qt3DCore::QEntity(rootEntity);
// 圆环网格
Qt3DExtras::QTorusMesh* torusMesh = new Qt3DExtras::QTorusMesh(torusEntity);
torusMesh->setRadius(5.0f);
torusMesh->setMinorRadius(1.0f);
torusMesh->setRings(100);
torusMesh->setSlices(20);
torusEntity->addComponent(torusMesh);// 变换组件(可选)
Qt3DCore::QTransform* transform = new Qt3DCore::QTransform(torusEntity);
transform->setScale3D(QVector3D(1.5, 1.5, 01.5));
transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 60.0f));
torusEntity->addComponent(transform);Qt3DExtras::QPhongMaterial* torusMaterial = new Qt3DExtras::QPhongMaterial();
torusMaterial->setDiffuse(QColor(QRgb(0x000000)));QMaterial* material1 = new QMaterial(torusEntity);
QMaterial* material2 = new QMaterial(torusEntity);// Create effect, technique, render pass and shader
QEffect* effect1 = new QEffect();
QTechnique* gl3Technique = new QTechnique();
QRenderPass* gl3Pass = new QRenderPass();
QShaderProgram* glShader = new QShaderProgram();// Set the shader on the render pass
gl3Pass->setShaderProgram(glShader);// Add the pass to the technique
gl3Technique->addRenderPass(gl3Pass);// Set the targeted GL version for the technique
gl3Technique->graphicsApiFilter()->setApi(QGraphicsApiFilter::OpenGL);
gl3Technique->graphicsApiFilter()->setMajorVersion(3);
gl3Technique->graphicsApiFilter()->setMinorVersion(3);
gl3Technique->graphicsApiFilter()->setProfile(QGraphicsApiFilter::CoreProfile);// Add the technique to the effect
effect1->addTechnique(gl3Technique);// Set the effect on the materials
material1->setEffect(effect1);
material2->setEffect(effect1);// Set different parameters on the materials
const QString parameterName = QStringLiteral("color");
material1->addParameter(new QParameter(parameterName, QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f)));
material2->addParameter(new QParameter(parameterName, QColor::fromRgbF(1.0f, 0.0f, 1.0f, 1.0f)));
// 添加组件到实体
torusEntity->addComponent(material1);// 监听编译状态
QObject::connect(shaderProgram, &Qt3DRender::QShaderProgram::statusChanged,
[=](Qt3DRender::QShaderProgram::Status status) {
if (status == Qt3DRender::QShaderProgram::Error) {
qDebug() << "Shader Error:" << shaderProgram->log();
}
});return torusEntity;
}
when i use custom QMaterial it can run successfully, but Show blank:
when i use QPhongMaterial, it worked :
why ? any help please! -
You can ask deepseek or grok first. 5.14.2 is old. Better to use the latest Qt and this module has been changed a lot.
QMaterial (custom material) setup is incomplete because you haven’t provided shader code to the QShaderProgram object (glShader). When you use QPhongMaterial, it works because it’s a pre-built material with its own shaders and properties handled internally by Qt 3D. For a custom material like QMaterial, you need to explicitly define and load the vertex and fragment shaders to tell the renderer how to draw the entity. Without shaders, the material has no instructions, and the entity renders blank.
-
@JoeCFD Try the following
Qt3DCore::QEntity* createTorusWithGradient(Qt3DCore::QEntity* rootEntity) { Qt3DCore::QEntity* torusEntity = new Qt3DCore::QEntity(rootEntity); // Torus mesh Qt3DExtras::QTorusMesh* torusMesh = new Qt3DExtras::QTorusMesh(torusEntity); torusMesh->setRadius(5.0f); torusMesh->setMinorRadius(1.0f); torusMesh->setRings(100); torusMesh->setSlices(20); torusEntity->addComponent(torusMesh); // Transform Qt3DCore::QTransform* transform = new Qt3DCore::QTransform(torusEntity); transform->setScale3D(QVector3D(1.5f, 1.5f, 1.5f)); // Fixed typo transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 60.0f)); torusEntity->addComponent(transform); // Custom material setup Qt3DRender::QMaterial* material = new Qt3DRender::QMaterial(torusEntity); // Effect, technique, render pass, and shader Qt3DRender::QEffect* effect = new Qt3DRender::QEffect(); Qt3DRender::QTechnique* gl3Technique = new Qt3DRender::QTechnique(); Qt3DRender::QRenderPass* gl3Pass = new Qt3DRender::QRenderPass(); Qt3DRender::QShaderProgram* glShader = new Qt3DRender::QShaderProgram(); // Simple vertex shader const QByteArray vertexShaderCode = R"( #version 330 core in vec3 vertexPosition; in vec3 vertexNormal; uniform mat4 modelViewProjection; out vec3 fragPosition; void main() { fragPosition = vertexPosition; gl_Position = modelViewProjection * vec4(vertexPosition, 1.0); } )"; // Simple fragment shader with color parameter const QByteArray fragmentShaderCode = R"( #version 330 core in vec3 fragPosition; out vec4 fragColor; uniform vec4 color; void main() { fragColor = color; // Use the color parameter directly } )"; // Set shader code glShader->setVertexShaderCode(vertexShaderCode); glShader->setFragmentShaderCode(fragmentShaderCode); // Connect shader program to render pass gl3Pass->setShaderProgram(glShader); gl3Technique->addRenderPass(gl3Pass); // Set OpenGL 3.3 Core profile gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); gl3Technique->graphicsApiFilter()->setMajorVersion(3); gl3Technique->graphicsApiFilter()->setMinorVersion(3); gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile); // Add technique to effect effect->addTechnique(gl3Technique); material->setEffect(effect); // Add a color parameter material->addParameter(new Qt3DRender::QParameter("color", QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f))); // Add material to entity torusEntity->addComponent(material); // Debug shader compilation errors QObject::connect(glShader, &Qt3DRender::QShaderProgram::statusChanged, [=](Qt3DRender::QShaderProgram::Status status) { if (status == Qt3DRender::QShaderProgram::Error) { qDebug() << "Shader Error:" << glShader->log(); } }); return torusEntity; }
-
@JoeCFD said in in qt3D can not use custom QMaterial on QEntity, why?:
// Custom material setup
Qt3DRender::QMaterial* material = new Qt3DRender::QMaterial(torusEntity);// Effect, technique, render pass, and shader Qt3DRender::QEffect* effect = new Qt3DRender::QEffect(); Qt3DRender::QTechnique* gl3Technique = new Qt3DRender::QTechnique(); Qt3DRender::QRenderPass* gl3Pass = new Qt3DRender::QRenderPass(); Qt3DRender::QShaderProgram* glShader = new Qt3DRender::QShaderProgram(); // Simple vertex shader const QByteArray vertexShaderCode = R"( #version 330 core in vec3 vertexPosition; in vec3 vertexNormal; uniform mat4 modelViewProjection; out vec3 fragPosition; void main() { fragPosition = vertexPosition; gl_Position = modelViewProjection * vec4(vertexPosition, 1.0); } )"; // Simple fragment shader with color parameter const QByteArray fragmentShaderCode = R"( #version 330 core in vec3 fragPosition; out vec4 fragColor; uniform vec4 color; void main() { fragColor = color; // Use the color parameter directly } )"; // Set shader code glShader->setVertexShaderCode(vertexShaderCode); glShader->setFragmentShaderCode(fragmentShaderCode); // Connect shader program to render pass gl3Pass->setShaderProgram(glShader); gl3Technique->addRenderPass(gl3Pass); // Set OpenGL 3.3 Core profile gl3Technique->graphicsApiFilter()->setApi(Qt3DRender::QGraphicsApiFilter::OpenGL); gl3Technique->graphicsApiFilter()->setMajorVersion(3); gl3Technique->graphicsApiFilter()->setMinorVersion(3); gl3Technique->graphicsApiFilter()->setProfile(Qt3DRender::QGraphicsApiFilter::CoreProfile); // Add technique to effect effect->addTechnique(gl3Technique); material->setEffect(effect); // Add a color parameter material->addParameter(new Qt3DRender::QParameter("color", QColor::fromRgbF(0.0f, 1.0f, 0.0f, 1.0f))); // Add material to entity torusEntity->addComponent(material);
i used your code in qt6.5.3,it still shown blank