如何在3D对象上使部分的颜色不同 [英] How to make color of a section be different on a 3D object

查看:203
本文介绍了如何在3D对象上使部分的颜色不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下3D对象:

我的3D对象的材质使用Qt3D进行了这样的编码:

The material of my 3D object is coded like this with Qt3D:

void MyClass::addMaterial(Qt3DCore::QEntity *entity)
{
    Qt3DExtras::QPhongMaterial * material = new Qt3DExtras::QPhongMaterial();
    material->setAmbient(QColor(245-30, 245-15, 245));
    material->setDiffuse(QColor(125-30, 125-15, 125));
    material->setSpecular(QColor(215-30, 255-15, 255));
    entity->addComponent(material);
}

上面的代码为3D对象实体统一赋予了相同的颜色.如何为实体的不同部分赋予不同的颜色?我想在我的3D对象上突出显示某些部分,是否可以使用Qt3D做到这一点?

The above code gives the same colors to 3D object entity uniformly. How can I give different colors to different sections of my entity? I want to highlight some section on my 3D object, is there a way to do that with Qt3D?

如果Qt3D无法实现,那么使用 OpenGL 的最佳实践是什么?

If it isn't possible with Qt3D, what is the best practice to do it with OpenGL?

我发现了一个讨论非常有帮助.

I found a discussion which I feel like it would be very helpful.

经过研究,最好的方法可能是使用OpenGL阴影语言或 GLSL .我不确定.

After doing some research, the best approach might be to use OpenGL shading language or GLSL. I'm not sure.

推荐答案

在Qt中,我可以想象他们使用材质"作为其预定义着色器的抽象.您创建了一个诸如QPhongMaterial的材质,您想使用它来渲染实体并为该材质设置东西,这些东西将作为诸如室内,镜面和漫射照明颜色之类的着色器(均匀)的参数传递.

In Qt I would imagine they are using "materials" as an abstraction of their predefined shaders. You create a material such as QPhongMaterial that you want to render an entity with and set things for that material which will be passed in as arguments to the shader (uniforms) like the ambient, specular and diffuse lighting color.

因此,您需要一个支持模型顶点颜色的着色器.因此,模型的每个顶点都将具有与之关联的颜色,并且这些值将传递到顶点着色器中并转发到片段着色器.使用OpenGL进行操作相当简单,但是您使用的是Qt3D,因此使用现有的基础结构可能会更容易.

So you need a shader that will support vertex colors for your model. So each vertex of your model will have a color associated with it and these values get passed in to the vertex shader and forwarded to the fragment shader. It's fairly straightforward to do this with OpenGL but you're using Qt3D so it might be easier to use the infrastructure that's already there.

Qt3D已经具有一些材质类,您可以使用这些材质类来创建其中的一些着色器以应用于您的实体.您可以尝试改用QPerVertexColorMaterial.

Qt3D already has some material classes that you can use to create some of these shaders to apply to your entity. You could try using the QPerVertexColorMaterial instead.

https://doc.qt.io/qt-5/qt3dextras -qpervertexcolormaterial.html

Qt3DExtras :: QPerVertexColorMaterial的默认实现 渲染为每个顶点设置的颜色属性

Qt3DExtras::QPerVertexColorMaterial Default implementation for rendering the color properties set for each vertex

很显然,您需要提供顶点颜色列表,以便对模型的各个部分进行不同的着色.除此之外,即使您要为三角形的每个顶点都上色相同的颜色(面色),也需要为每个顶点提供顶点颜色.

Obviously you will need to provide the list of vertex colors in order to color parts of the model differently. In addition to this, you will need to provide vertex colors for each vertex, even if you want to color each vertex of the triangle all the same color (face colors).

或者,您可以创建自己的着色器并将其提供给Qt3D以绑定到管道: (来自论坛)

Alternatively you could create your own shader and give it to Qt3D to bind to the pipeline: (from the forum)

Qt3D在运行时不会生成着色器.对于其默认管道,它带有预定义的默认着色器.但是,您可以随意更改管道(在C ++和QML中),并且可以使用自己的着色器.

Qt3D does not generate shaders at runtime. For its default pipeline it comes with predefined default shaders. But you are free to change the pipeline as you wish (in C++ and also in QML) and you can use your own shaders.

对于定制材料,以下示例看起来很有希望: https://doc.qt.io/qt-5/qt3d- simplecustommaterial-example.html

For custom materials the following example look promising: https://doc.qt.io/qt-5/qt3d-simplecustommaterial-example.html

有关Qt3D着色器的信息: https://doc.qt.io/qt-5/qml-qt3d-render-shaderprogram.html

And for information on Qt3D shaders: https://doc.qt.io/qt-5/qml-qt3d-render-shaderprogram.html

ShaderProgram类封装了着色器程序.着色器程序由几个不同的着色器组成,例如顶点和片段着色器. 如果在着色器自省阶段遇到默认制服,则Qt3D将自动填充一组默认制服.

ShaderProgram class encapsulates a shader program. A shader program consists of several different shaders, such as vertex and fragment shaders. Qt3D will automatically populate a set of default uniforms if they are encountered during the shader instrospection phase.

如果您从未用GLSL编写着色器并在OpenGL程序中对其进行编译,则可能需要首先了解如何完成顶点,几何和片段着色器的所有部分,以加快其完成速度以及属性和制服的作用.我想您仍然可以不做而完成工作,但我想这会困难得多.

If you've never written a shader in GLSL and compiled it in an OpenGL program you might want to first get up to speed on how that is done as you need to understand the parts that the vertex, geometry and fragment shaders all play as well as the role of attributes and uniforms. I suppose you could still get the job done without doing that but I would imagine it would be significantly harder.

着色器上有很多页面,但是只是短暂的...

There is pages and pages out there on shaders but just briefly...

着色器通常包括三个部分;顶点着色器,几何着色器和片段着色器是使用GLSL编写的,通常保存为三个文件.至少要编译着色器,您需要顶点着色器源和片段着色器源.

A shader generally comprises of three parts; the vertex shader, the geometry shader and the fragment shader, these are written using GLSL and usually saved as three files. At a minimum to compile a shader you need the vertex shader source and the fragment shader source.

通常,人们喜欢使用相应的扩展名(例如.frag,.vert或.vs/.fs)保存这些文件,但最终它们只是文本文件. 要编译着色器并将其绑定到渲染管道,您需要从相应文件加载源并将其链接以创建着色器程序,然后将其绑定到渲染管道并渲染几何图形即可使用. Lazy Foo有一个很棒的教程,介绍了如何在OpenGL中完成该操作: http://lazyfoo. net/tutorials/SDL/51_SDL_and_modern_opengl/index.php

Generally people like to save these files with the respective extension such as .frag, .vert or .vs/ .fs but ultimately they are just text files. To compile a shader and bind it to the render pipeline you need to load the source from the respective files and link them to create your shader program which you can then use by binding it to the render pipeline and rendering your geometry. Lazy Foo has an awesome tutorial on how that is done in OpenGL: http://lazyfoo.net/tutorials/SDL/51_SDL_and_modern_opengl/index.php

如果仅使用OpenGL,则首先要编写一个顶点着色器,然后编写一个具有正确输入/输出的片段着色器,以渲染具有顶点颜色的几何图形,然后完成该过程以创建着色器程序.

If you were just using OpenGL, you would first write a vertex shader then a fragment shader with the correct inputs/outputs for rendering geometry with vertex colors, then you would go through that process to create your shader program.

对于着色器实现本身,这是您的顶点和片段着色器外观的快速实现:

As for the shader implementation itself, here is a quick implementation of what your vertex and fragment shader would look like:

顶点着色器(Color.vs)

Vertex Shader (Color.vs)

#version 330

in vec3 position;
in vec4 vertexColor;

uniform mat4 WORLD_VIEW_PROJECTION_MATRIX;

out vec4 fragColor;

void main()
{
  fragColor.x = vertexColor.x;
  fragColor.y = vertexColor.y;
  fragColor.z = vertexColor.z;
  fragColor.w = vertexColor.w; //alpha
  gl_Position = WORLD_VIEW_PROJECTION_MATRIX * vec4( position, 1 );
}

片段着色器(Color.fs)

Fragment Shader (Color.fs)

#version 330 
out vec4 LFragment; 

in vec4 fragColor;

void main() 
{   
    LFragment = fragColor;
}

这篇关于如何在3D对象上使部分的颜色不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆