Dust3D开源项目分析——渲染与材质部分 | 纹理生成 Part3

2021SC@SDUSC

纹理生成函数generate(),函数相对复杂,主要负责纹理的生成功能。因为代码跨度较大,这里会分成几篇文章进行分析。

void TextureGenerator::generate()
{
    m_resultMesh = new Model(*m_object);
    
    if (nullptr == m_object->triangleVertexUvs())
        return;
    if (nullptr == m_object->triangleSourceNodes())
        return;
    if (nullptr == m_object->partUvRects())
        return;
    
    QElapsedTimer countTimeConsumed;
    countTimeConsumed.start();
    
    prepare();
    
    bool hasNormalMap = false;
    bool hasMetalnessMap = false;
    bool hasRoughnessMap = false;
    bool hasAmbientOcclusionMap = false;
    
    const auto &triangleVertexUvs = *m_object->triangleVertexUvs();
    const auto &triangleSourceNodes = *m_object->triangleSourceNodes();
    const auto &partUvRects = *m_object->partUvRects();
    const auto &triangleNormals = m_object->triangleNormals;
    
    std::map<QUuid, QColor> partColorMap;
    std::map<std::pair<QUuid, QUuid>, const ObjectNode *> nodeMap;
    std::map<QUuid, float> partColorSolubilityMap;
    std::map<QUuid, float> partMetalnessMap;
    std::map<QUuid, float> partRoughnessMap;
    for (const auto &item: m_object->nodes) {
        if (!m_hasTransparencySettings) {
            if (!qFuzzyCompare(1.0, item.color.alphaF()))
                m_hasTransparencySettings = true;
        }
        nodeMap.insert({{item.partId, item.nodeId}, &item});
        partColorMap.insert({item.partId, item.color});
        partColorSolubilityMap.insert({item.partId, item.colorSolubility});
        partMetalnessMap.insert({item.partId, item.metalness});
        partRoughnessMap.insert({item.partId, item.roughness});
    }
    
    auto createImageBeginTime = countTimeConsumed.elapsed();
    
    m_resultTextureColorImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
    m_resultTextureColorImage->fill(m_hasTransparencySettings ? m_defaultTextureColor : Qt::white);
    
    m_resultTextureNormalImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
    m_resultTextureNormalImage->fill(QColor(128, 128, 255));
    
    m_resultTextureMetalnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
    m_resultTextureMetalnessImage->fill(Qt::black);
    
    m_resultTextureRoughnessImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
    m_resultTextureRoughnessImage->fill(Qt::white);
    
    m_resultTextureAmbientOcclusionImage = new QImage(TextureGenerator::m_textureSize, TextureGenerator::m_textureSize, QImage::Format_ARGB32);
    m_resultTextureAmbientOcclusionImage->fill(Qt::white);
    
    auto createImageEndTime = countTimeConsumed.elapsed();
    
    QColor borderColor = Qt::darkGray;
    QPen pen(borderColor);
    
    QPainter texturePainter;
    texturePainter.begin(m_resultTextureColorImage);
    texturePainter.setRenderHint(QPainter::Antialiasing);
    texturePainter.setRenderHint(QPainter::HighQualityAntialiasing);
    
    QPainter textureNormalPainter;
    textureNormalPainter.begin(m_resultTextureNormalImage);
    textureNormalPainter.setRenderHint(QPainter::Antialiasing);
    textureNormalPainter.setRenderHint(QPainter::HighQualityAntialiasing);
    
    QPainter textureMetalnessPainter;
    textureMetalnessPainter.begin(m_resultTextureMetalnessImage);
    textureMetalnessPainter.setRenderHint(QPainter::Antialiasing);
    textureMetalnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
    
    QPainter textureRoughnessPainter;
    textureRoughnessPainter.begin(m_resultTextureRoughnessImage);
    textureRoughnessPainter.setRenderHint(QPainter::Antialiasing);
    textureRoughnessPainter.setRenderHint(QPainter::HighQualityAntialiasing);
    
    QPainter textureAmbientOcclusionPainter;
    textureAmbientOcclusionPainter.begin(m_resultTextureAmbientOcclusionImage);
    textureAmbientOcclusionPainter.setRenderHint(QPainter::Antialiasing);
    textureAmbientOcclusionPainter.setRenderHint(QPainter::HighQualityAntialiasing);
    
    auto paintTextureBeginTime = countTimeConsumed.elapsed();
    texturePainter.setPen(Qt::NoPen);
    
   

首先检测一些必要数据是否为空(顶点UV、源节点等),如果为空则无法生成纹理,直接return。如果可以生成,执行prepare(),然后从m_object指向的对象中提取三角形顶点UV、三角形来源节点、局部UV数据和三角面法线的信息。之后遍历m_object的nodes,依次将检测到的nodeMap、colorMap、colorSolubilityMap、metalnessMap和roughnessMap键值对添加到类的对应数据成员中,并且用QImage构建新的color、normal、metalness、roughness和AO贴图并初始化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值