I’m testing the current status of Qt3D. I’m very fond of the MetalRoughMaterial, but I can’t seem to handle this simple use case in Qt3D: I would like to use textures that repeat to fill the face they are on.
Desired result:
What I get is this (see code below):
In case you’re wondering, I made 2 cubes next to one another to make the 2nd image, but I don’t consider this a real solution…)
I have been experimenting with WrapMode, Qtexture, textureScale but can’t find a solution in Qt3D yet.
I noticed that when I change textureScale, this repeats the texture on all faces. But on the small faces we get the same amount of images as in the longer ones. Is there a way to change this for x, y and z differently?
code:
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
}
}
I know how to do it in pure opengl(without Qt3D) by altering texturecoordinates of vertex data. If that is the direction to go I suspect I will have to make my own custom Mesh. Can somebody confirm this is the way to go? Or are there other solutions for this use case?
Thanks for your time reading this. Every help, suggestion is welcome, even the pure opengl solutions.
Yes, you can change texture coordinates in geometry, but I think it's easier to write custom shader, which gets proper texture coordinates from computations. For example, you can start with SimpleMaterial shader, modify it to display grid like you want. I had similar code for fragment shader:
#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);
}