qt - Qt3D中网格尺寸变化时如何保持纹理纵横比

标签 qt opengl qml qt5 qt3d

我正在测试Qt3D的当前状态。我非常喜欢 MetalRoughMaterial,但我似乎无法在 Qt3D 中处理这个简单的用例:我想使用重复的纹理来填充它们所在的面。

期望的结果:

desired result desired result2

我得到的是这个(见下面的代码):

longcube

如果您想知道,我制作了两个相邻的立方体来制作第二张图像,但我不认为这是一个真正的解决方案......)

我一直在尝试 WrapMode、Qtexture、textureScale,但在 Qt3D 中还找不到解决方案。

我注意到,当我更改纹理比例时,这会在所有面上重复纹理。但在小脸上,我们得到的图像数量与长脸上的图像数量相同。有没有办法以不同的方式改变 x、y 和 z 的值?

代码:

import Qt3D.Core 2.12
import Qt3D.Render 2.12
import Qt3D.Input 2.12
import Qt3D.Extras 2.12

Entity {
    id: sceneRoot

    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer{ 
                camera: camera
            }
        },
        InputSettings { },

        DirectionalLight {
            worldDirection: Qt.vector3d(-1, -1, -1);
            color: "white"
            intensity: 2.0
        }
   ]

    Camera {
        id: camera
        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        aspectRatio: 800/600
        nearPlane : 0.1
        farPlane : 1000.0
        position: Qt.vector3d( 2.0, 2.0, 2.0 )
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( 0.0, 0.0, 0.0 )
    }

    OrbitCameraController { camera: camera }

    CuboidMesh {
        id: cuboidMesh
        xExtent:  2
        yExtent:  1
        zExtent:  1
    }

    Transform {
        id: cuboidTranslation
        translation: Qt.vector3d(0, 0, 0)
    }

    Entity {
        id: cuboidEntity
        components: [ cuboidMesh, testMaterial, cuboidTranslation ]
    }

    MetalRoughMaterial {
        id: testMaterial
        baseColor: TextureLoader {
            source: "qrc:/assets/textures/checkers.png"
        }

        metalness:0.0
        roughness: 1.0
        textureScale :1
    }
}

我知道如何在纯opengl(没有Qt3D)中通过改变顶点数据的纹理坐标来做到这一点。如果这是前进的方向,我怀疑我将不得不制作自己的定制网格。有人可以确认这是要走的路吗?或者对于这个用例还有其他解决方案吗?

感谢您花时间阅读本文。欢迎每一个帮助、建议,甚至是纯粹的 opengl 解决方案。

最佳答案

是的,您可以更改几何中的纹理坐标,但我认为编写自定义着色器更容易,它可以从计算中获取正确的纹理坐标。例如,您可以从 SimpleMaterial 着色器开始,修改它以显示您想要的网格。我有类似的片段着色器代码:

#version 150 core

uniform vec3 boxSize;//all model
uniform vec2 wallSectionSize;//x y - size of cell inside this model
varying highp vec3 pos;

void main() {
    vec3 pt = pos.xyz;
    float x = pt.x;
    float y = pt.y;
    float z = pt.z;
    bool side = false;
    if(x==0 || x==boxSize.x) {
        x = z;
        side = true;
    } else if(y==0 || y==boxSize.y) {
        y = z;
    }
    //b == block number
    const int nbx = int(x/wallSectionSize.x);
    const int nby = int(y/wallSectionSize.y);//floor number from 0
    //coordinates in this block umber
    float bx = x - nbx * wallSectionSize.x;
    float by = y - nby * wallSectionSize.y;
    if(nbx % 2)
        //fragColor = texture2D(...);
        fragColor = vec4(1,1,0,0);
    else
        fragColor = vec4(1,0,1,0);
}

关于qt - Qt3D中网格尺寸变化时如何保持纹理纵横比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57339329/

相关文章:

android - 什么在 Android 上表现更好?使用 Java 或 C++ 编写的应用程序

c++ - 在调用槽上绘制小部件

c++ - QT with MSVC2015 触发多个编译错误

c - 在C中绘制像素

c++ - 将 QList<customobj *> 暴露给 QML

c++ - Qt 沿着圆形路径移动文本

c++ - 为什么我需要 FreeGLUT 来编译和链接一个 GLFW 程序

c - 带结构的指针

qt - 通过 C++ 被动使用 QtQuick/QML

javascript - 在 QML 中创建一个新的 javascript 对象