@cawoodm –
Somehow I managed to make the original JSFiddle to show perfect pixel alignment. It appears Windows is messing up how canvases are rendered. There are 4 lines changed, all marked by comments. Line PB-1
is removed, lines PB-2
,-3
,-4
are added.
PB-3
is the magic. If you Windows is set to zoom 100%, use scale(1,1)
; if the zoom is 125%, then use scale(0.8,0.8)
, for zoom 150%, use scale(0.6667,0.6667)
and so on for zoom X% use scale factors 100/X. The zoom factor is found in the Windows display settings. My setting was 125%, so the scale factor is 0.8 for me.
The final result is this:
Here is the code:
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({ antialias: false });
//PB-1 renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
renderer.domElement.style.imageRendering = 'pixelated'; //PB-2
renderer.domElement.style.transform = "scale(0.8,0.8)"; //PB-3
window.addEventListener("resize", onWindowResize, false);
scene.add(new THREE.AmbientLight(0x101010));
let viewBlock = 320 / 2;
aspect = window.innerWidth / window.innerHeight;
camera = new THREE.OrthographicCamera(-viewBlock * aspect, viewBlock * aspect, viewBlock, -viewBlock, 1000, -1000);
camera.position.set(0, 0, 100);
// Matrix of 64x48 "bloxels" each 5x5 pixels
const color = new THREE.MeshStandardMaterial({ color: 0x33dd33 });
let W = 5;
let H = 5;
let X = 320 / W;
let Y = 240 / H;
for (let x = -X / 2; x < X / 2; x++) {
for (let y = -Y / 2; y < Y / 2; y++) {
const box = new THREE.Mesh(new THREE.BoxGeometry(W * 0.8, H * 0.8, 2), color[0]);
box.position.set(W / 2 + x * W, H / 2 + y * H, 0);
scene.add(box);
}
}
}
function onWindowResize() {
camera.left = window.innerWidth / -2;
camera.right = window.innerWidth / 2;
camera.top = window.innerHeight / 2;
camera.bottom = window.innerHeight / -2;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
onWindowResize(); // PB-4
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
– Pavel
PS. Instead of BoxGeometry
you can use PlaneGeometry
to reduce 6 times the amount of triangles. Or, better, use Points
with size 4 and turned off sizeAtenuation
.