how can we adjust the mapping in shaders to view applied texture correctly on the mesh far away from the camera ?
texture was correctly applied as per the image aspect, but due to distance it looks too small. how can we setup as it look like the original ratio without changing the distance ?
tile textures are in mm so converted accordingly in meter units
function loadTextureAndSetRepeat({ element }) {
let surfaceData = element.userData;
const currentTexture = tilesData[2];
const imageUrls = currentTexture.imgUrl;
const firstImageUrl = imageUrls[0]
loadImage(firstImageUrl)
.then((firstImage) => {
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
canvas.width = firstImage.width;
canvas.height = firstImage.height;
context.drawImage(firstImage, 0, 0, canvas.width, canvas.height);
const texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.anisotropy = renderer.capabilities.getMaxAnisotropy();
const shaderMaterial = new THREE.ShaderMaterial({
vertexShader: vshader,
fragmentShader: fshader,
uniforms: {
u_texture: { value: texture },
planeSize: { value: new THREE.Vector2(surfaceData.height, surfaceData.width) },
textureSize: { value: new THREE.Vector2(0.6, 0.6) },
groutThickness: { value: 0.02 }, // Adjust as needed for the grout thickness
},
side: THREE.DoubleSide // Set the material to render on both sides
});
element.material = shaderMaterial;
element.material.needsUpdate = true;
renderer.render(scene, camera);
})
.catch((error) => {
console.error("Error loading image:", error);
});
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "anonymous";
img.onload = () => resolve(img);
img.onerror = reject;
img.src = url;
});
}
}
shaders code :
//vshaders
export default `
uniform vec2 planeSize; // Plane dimensions (width, height)
uniform vec2 textureSize; // Texture original dimensions (width, height)
varying vec2 vUv;
void main() {
// Calculate the scaling factor to maintain the texture's original size
vec2 scale = planeSize / textureSize;
// Adjust uv coordinates
vUv = uv * scale;
// Standard vertex position calculation
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`
//fshaders
export default `
precision highp float; // Ensure high precision for floating-point operations
uniform sampler2D u_texture; // Renamed to avoid conflict
uniform float groutThickness; // Uniform for grout thickness
varying vec2 vUv;
void main() {
// Calculate adjusted uv coordinates for grout space
vec2 adjustedUv = mod(vUv, 1.0 - groutThickness);
// Determine if the current fragment is within a grout line
bool isGrout = adjustedUv.x > (1.0 - groutThickness) || adjustedUv.y > (1.0 - groutThickness);
// Default color (texture sample)
vec4 color = texture2D(u_texture, adjustedUv); // Use renamed uniform here
// If within grout area, color it differently
if (isGrout) {
color = vec4(1, 0, 0, 1.0); // red color for grout
}
// Assign the final color to the fragment
gl_FragColor = color;
}
`