Qt3D中网格尺寸变化时如何保持纹理纵横比
How to keep texture aspect ratio when the mesh dimensions change in Qt3D
我正在测试 Qt3D 的当前状态。我非常喜欢 MetalRoughMaterial,但我似乎无法在 Qt3D 中处理这个简单的用例:我想使用重复的纹理来填充它们所在的面。
想要的结果:
我得到的是这个(见下面的代码):
如果你想知道,我制作了两个并排的立方体来制作第二张图片,但我不认为这是一个真正的解决方案......)
我一直在试验 WrapMode、Qtexture、textureScale,但在 Qt3D 中找不到解决方案。
我注意到当我更改 textureScale 时,这会在所有面上重复纹理。但在小脸上,我们得到的图像数量与长脸上的图像数量相同。有没有办法改变 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);
}
如果您的立方体在所有方向上均匀增长,您也可以使用 textureScale
属性。在您的示例中,立方体的缩放比例不相等,您可以使用 textureTransform
矩阵。我还创建了同时使用方法和着色器的示例:
https://github.com/neurocod/Whosebug/tree/master/texture-sapect-ratio
我正在测试 Qt3D 的当前状态。我非常喜欢 MetalRoughMaterial,但我似乎无法在 Qt3D 中处理这个简单的用例:我想使用重复的纹理来填充它们所在的面。
想要的结果:
我得到的是这个(见下面的代码):
如果你想知道,我制作了两个并排的立方体来制作第二张图片,但我不认为这是一个真正的解决方案......)
我一直在试验 WrapMode、Qtexture、textureScale,但在 Qt3D 中找不到解决方案。
我注意到当我更改 textureScale 时,这会在所有面上重复纹理。但在小脸上,我们得到的图像数量与长脸上的图像数量相同。有没有办法改变 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);
}
如果您的立方体在所有方向上均匀增长,您也可以使用 textureScale
属性。在您的示例中,立方体的缩放比例不相等,您可以使用 textureTransform
矩阵。我还创建了同时使用方法和着色器的示例:
https://github.com/neurocod/Whosebug/tree/master/texture-sapect-ratio