首页 > 其他分享 >Qt3D绘制光照效果

Qt3D绘制光照效果

时间:2023-09-22 10:56:05浏览次数:43  
标签:1.0 modelMatrix 0.333 Qt3D program QVector3D vec3 绘制 光照

直接给出一个例子供参考。此例子参考了以下博文中公开的代码并做了整理:

这里把立方体换成了四面体,贴图也换成了顶点的颜色。并对代码结构做了简化,以使读者更容易看懂。有兴趣的读者可以调节软件中相机位置、EYE位置和视角方向(即调整lookAt(...)函数的参数)等观察这些参数对渲染结果的影响。本文开发环境是VS2017和Qt5.9。软件效果如下图:

头文件如下:

class QOpenGLTexture;
class QOpenGLBuffer;

class MwOpenGLWidget : public QOpenGLWidget, private QOpenGLFunctions
{
    Q_OBJECT

private:
    struct VertexData
    {
        QVector3D pos;
        QVector3D normal;
        QVector3D color;
    };

public:
    MwOpenGLWidget(QWidget* parent = 0);

private:
    void initializeGL() override;
    void paintGL() override;
    void resizeGL(int w, int h) override;

private:
    QOpenGLShaderProgram* program;
    QOpenGLBuffer* vertexBuff;
    QOpenGLBuffer* indexBuff;
    int iter;
};

CPP文件:

MwOpenGLWidget::MwOpenGLWidget(QWidget* parent) :
    QOpenGLWidget(parent), iter(0)
{
    QSurfaceFormat surface;
    surface.setSamples(4);
    setFormat(surface);

    QTimer* timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, QOverload<>::of(&MyOpenGLWidget::update));
    timer->setInterval(100);
    timer->start();
}

void MwOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glEnable(GL_DEPTH_TEST);

    program = new QOpenGLShaderProgram(this);
    const char* vsrc = u8R"(
        #version 330 core
        layout (location = 0) in vec3 aPos; // 空间坐标
        layout (location = 1) in vec3 aNormal; // 法线向量
        layout (location = 2) in vec3 aColor; // 顶点颜色
        uniform mat4 modelMatrix;
        uniform mat4 mvpMatrix;
        out vec3 oNormal;
        out vec3 oFragPos;
        out vec3 oColor;

        void main()
        {
            oFragPos = vec3(modelMatrix * vec4(aPos, 1.0));
            oNormal =  mat3(transpose(inverse(modelMatrix))) * aNormal;
            oColor = aColor;
            gl_Position = mvpMatrix * vec4(aPos, 1.0);
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Vertex, vsrc);
    const char* fsrc = u8R"(
        #version 330 core
        uniform vec3 lightPos; 
        uniform vec3 viewPos; 
        uniform vec3 lightColor;
        in vec3 oNormal;
        in vec3 oFragPos;
        in vec3 oColor;

        void main()
        {
            // 环境光照
            float ambientStrength = 0.1;
            vec3 ambient = ambientStrength * lightColor;
            // 漫反射光照 
            vec3 norm = normalize(oNormal);
            vec3 lightDir = normalize(lightPos - oFragPos);
            float diff = max(dot(norm, lightDir), 0.0);
            vec3 diffuse = diff * lightColor;
            // 镜面光照
            float specularStrength = 1.0;
            vec3 viewDir = normalize(viewPos - oFragPos);
            vec3 reflectDir = reflect(-lightDir, norm);
            float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32.0);
            vec3 specular = specularStrength * spec * lightColor;
            // 把纹理中的颜色和光照参数相乘
            gl_FragColor = vec4((ambient + diffuse + specular) * oColor, 1.0);
        })";
    program->addShaderFromSourceCode(QOpenGLShader::Fragment, fsrc);

    program->link();
    program->bind();

    VertexData vertices[] =
    {
        { QVector3D(-0.433f, 0, -0.25f), QVector3D(-0.816f, 0.333f, 0.471f), QVector3D(1.0f, 0, 0) },
        { QVector3D(0, 0, 0.5f), QVector3D(-0.816f, 0.333f, 0.471f), QVector3D(0, 1.0f, 0) },
        { QVector3D(0, 0.707f, 0), QVector3D(-0.816f, 0.333f, 0.471f), QVector3D(0, 0, 1.0f) },

        { QVector3D(0, 0, 0.5f), QVector3D(0.816f, 0.333f, 0.471f), QVector3D(1.0f, 1.0f, 0) },
        { QVector3D(0.433f, 0, -0.25f), QVector3D(0.816f, 0.333f, 0.471f), QVector3D(1.0f, 0, 1.0f) },
        { QVector3D(0, 0.707f, 0), QVector3D(0.816f, 0.333f, 0.471f), QVector3D(0, 1.0f, 1.0f) },

        { QVector3D(0.433f, 0, -0.25f), QVector3D(0, 0.333f, -0.943f), QVector3D(0, 0, 1.0f) },
        { QVector3D(-0.433f, 0, -0.25f), QVector3D(0, 0.333f, -0.943f), QVector3D(0, 1.0f, 0) },
        { QVector3D(0, 0.707f, 0), QVector3D(0, 0.333f, -0.943f), QVector3D(1.0f, 0, 0) },

        { QVector3D(0, 0, 0.5f), QVector3D(0, -1.0f, 0), QVector3D(0, 1.0f, 1.0f) },
        { QVector3D(-0.433f, 0, -0.25f), QVector3D(0, -1.0f, 0), QVector3D(1.0f, 1.0f, 0) },
        { QVector3D(0.433f, 0, -0.25f), QVector3D(0, -1.0f, 0), QVector3D(1.0f, 0, 1.0f) },
    };
    GLushort indices[] =
    {
        0, 1, 2, 3, 4, 5,
        6, 7, 8, 9, 10, 11,
    };
    vertexBuff = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    vertexBuff->create();
    vertexBuff->bind();
    vertexBuff->allocate(vertices, 12 * sizeof(VertexData));
    indexBuff = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
    indexBuff->create();
    indexBuff->bind();
    indexBuff->allocate(indices, 12 * sizeof(float));

    int offset = 0;
    int vertexLocation = program->attributeLocation("aPos");
    program->enableAttributeArray(vertexLocation);
    program->setAttributeBuffer(vertexLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
    offset += sizeof(QVector3D);
    int normalLocation = program->attributeLocation("aNormal");
    program->enableAttributeArray(normalLocation);
    program->setAttributeBuffer(normalLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
    offset += sizeof(QVector3D);
    int colorLocation = program->attributeLocation("aColor");
    program->enableAttributeArray(colorLocation);
    program->setAttributeBuffer(colorLocation, GL_FLOAT, offset, 3, sizeof(VertexData));
}

#define LIGHT_COLOR QVector3D(0.9f, 1.0f, 2.0f) /* 这里的颜色值可以大于1不知道为什么 */
#define LIGHT_POS   QVector3D(2.5f, 2.8f, 2.0f)
#define EYE_CENTER  QVector3D(0.0, -1.4, 8.0)

void MwOpenGLWidget::paintGL()
{
    QMatrix4x4 projection;
    projection.perspective(45.0f, 1, 0.1f, 100.0f);
    QMatrix4x4 viewMatrix;
    viewMatrix.lookAt(EYE_CENTER, QVector3D(0, 2, -5), QVector3D(0, 1, 0));
    QMatrix4x4 modelMatrix;
    modelMatrix.translate(0, -0.8, 0); // 平移
    modelMatrix.rotate(iter, 0, 1); // 旋转
    modelMatrix.scale(4.0); // 缩放
    QMatrix4x4 mvpMatrix = projection * viewMatrix * modelMatrix;

    program->setUniformValue("lightColor", LIGHT_COLOR);
    program->setUniformValue("lightPos", LIGHT_POS);
    program->setUniformValue("viewPos", EYE_CENTER);
    program->setUniformValue("mvpMatrix", mvpMatrix);
    program->setUniformValue("modelMatrix", modelMatrix);
    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_SHORT, 0);
    iter++;
}

#undef LIGHT_COLOR
#undef LIGHT_POS
#undef EYE_CENTER

void MwOpenGLWidget::resizeGL(int w, int h)
{
}

 

标签:1.0,modelMatrix,0.333,Qt3D,program,QVector3D,vec3,绘制,光照
From: https://www.cnblogs.com/mengxiangdu/p/17721798.html

相关文章

  • 【小睿的ML之路】Seaborn-多变量分析绘制
    %matplotlibinlineimportseabornassns#导入seaborn库,用于绘制统计图形。importnumpyasnp#导入numpy库,用于处理数值计算。importpandasaspd#导入pandas库,用于处理数据。importmatplotlibasmpl#导入matplotlib库,用于绘图。importmatplotlib.py......
  • 【小睿的ML之路】Seaborn-单变量分析绘制
    importseabornassnsimportnumpyasnpimportpandasaspdimportmatplotlibasmplimportmatplotlib.pyplotasplt%matplotlibinlinex=np.random.normal(size=100)print(x)[0.22404072-1.9394295-0.32313598-0.25468579-0.719277940.66163234......
  • vue+openlayers绘制线
    绘制线1<template>2<div></div>3</template>4<script>5importVectorLayerfrom'ol/layer/Vector.js';6importVectorSourcefrom'ol/source/Vector.js';7importFeaturefrom'ol/Feature&......
  • win10 uwp 简单制作一个 Path 路径绘制的图标按钮
    本文告诉大家在UWP或WinUI3里面如何简单制作一个由Path几何路径图形绘制的图标按钮先在资源里面定义按钮的样式,重写Template属性,通过在Template里面放入Path绑定Data到内容从而实现让Path显示集合路径图形,代码如下<Stylex:Key="Style.TitlebarButton"......
  • pyecharts绘制K线的记录
    importtushareastsimportpandasaspdimportnumpyasnpimportmatplotlib.pyplotaspltfrompyecharts.chartsimport*frompyechartsimportoptionsasoptsfrompyecharts.globalsimportThemeTypepd.set_option('expand_frame_repr',False)p......
  • vuejs+antv-g6绘制图表
    该内容包括antv-g6官网地址、antv-g6的基本使用(包括自定义节点、常用插件(右键菜单等)、基本事件、目前我所遇到的一些需求)。1、antv-g6的官网地址:https://g6.antv.antgroup.com/examples2、安装antv-g6组件npminstall@antv/g6 3、创建antvView.vue文件使用antv/g6......
  • arcgis api for javascript 4.x, 删除绘制的点、线、面
    1、在视图mapView上添加的点线面//删除所有mapView.graphics.removeAll();//删除一个constpointGraphic=newGraphic({geometry,symbol})mapView.graphics.remove(pointGraphic);//删除多个mapView.graphics.removeMany([pointGraphic,polylineGraphic]);2、G......
  • 184_Python 在 Excel 和 Power BI 绘制堆积瀑布图
    184_Python在Excel和PowerBI绘制堆积瀑布图一、背景在2023年8月22日微软Excel官方宣布:在Excel原生内置的支持了Python。博客原文笔者第一时间就更新到了Excel的预览版,通过了漫长等待分发,现在可以体验了,先来看看效果。在Excel公式选项卡下Python菜单......
  • vue+openlayers 绘制点
    绘制点使用point在绘制点的位置,使用Circle绘制点的样式疑问:将style放在Feature上就绘制不出来样式? <template><divclass="setting"><divclass="title">设置</div><ul><li><p>边框大小:&......
  • ggplot2箱线图绘制教程
    箱线图是什么?箱线图(Boxplot),也称为盒须图或盒式图,是一种用于展示数据分布的统计图表。它通过展示数据的五个关键统计量,即最小值、下四分位数(Q1)、中位数、上四分位数(Q3)和最大值,帮助我们了解数据的中心趋势、离散程度以及可能存在的异常值。箱线图如何看?箱线图由一个矩形框和两条延伸......