简体   繁体   中英

How to make geometry retain its size regardless of the size of the renderer - Plane changes size depending on screen size

在此处输入图像描述

Visual helper and source code Im adding a codepen of the issue. And a GIF showing exactly what im confused by. Codepen: https://codepen.io/carelesscourage/pen/bGMWjNg

My expectation: I want the plane to be the same size reguardles of screensize.

 //WebGl renderer function useWebGl(root = document.body) { const renderer = new THREE.WebGLRenderer({ alpha: true }) renderer.setClearColor( 0x009900, 1 ) renderWindow(renderer) root.appendChild( renderer.domElement ) onResize(() => renderWindow(renderer)) return { WebGl: renderer } } function renderWindow(renderer) { const { height, width } = windowDimensions() renderer.setSize( width / 2, height / 2 ) } //ThreeJS Engine function initEngine() { const scene = new THREE.Scene() const camera = getCamera() const { WebGl } = useWebGl() function everyFrame(callback = () => {}) { callback() WebGl.render( scene, camera ) requestAnimationFrame(() => everyFrame(callback)) } return {scene, everyFrame} }

###everything bellow this line is from the initial post. Ive fixed some other issues and simpyfied the codepen down to the exact issue im wanting help with. So the text above this line is the actual issue, and bellow this line is just for the sake of keeping the record

在此处输入图像描述

Context: Ultimatley my goal is to make a plane in three.js that matches/overlaps an HTML element and sticks to it. But I dont expect anyone to do all that work for me. The only think im asking for right now is how to make the size and position of the plane be consistent across screen sizes. And in fact, we could probably limit this issue to just the size.

Issue: If the plane is 10px from the left on one screensize it should remain 10px from the left on all other screen sizes. Right now, instead of getting that im getting the plane jumping all over the place. Its not just a resize update issue, if you refresh the page every time you try to change the window size you will still see that the plane is in random places and at random sizes(as demonstrated in the gif). In the code im setting the size of the plane with the size of the html image. But even if I set the size statically, the plane still randomly changes size on diffirent screen sizes.

Reguarding position: In the code im basically telling the plane to move to the top left edge of the canvas, and then offset back to the position of the HTML element based on that elements position from the top right of the screen. Which works. But only for my fullscreen desktop view. When the window changes size suddenly the offset isnt accurate anymore. Why? Sometimes the plane even changes size.

My expextation: I expected the plane to be the same size reguardles of screensize?

My best guess: The issue is not related to the way im offseting the position of the plane. I know this because you can dissable all of that and you still get the plane moving around in size and position on diffirent screen sizes.Since dissabeling all code related to position and size still doesnt get rid of the issue of the plane changing size im assuming the issue has to be related to the way im dealing with he camera. Im using an orthographic camera though it should be noted that the same issue is also present when using the perspective camera.

If my guess is right the problem should be with this part of the code:

 function windowDimensions() { const height = window.innerHeight const width = window.innerWidth const aspect = width / height; return { height, width, aspect} } function cameraDimensions(aspect, viewSize = 1000) { const caps = viewSize / 2 const sides = aspect*viewSize / 2 return { caps, sides } } function getCamera() { const { aspect } = windowDimensions() const { caps, sides } = cameraDimensions(aspect) //const camera = new THREE.PerspectiveCamera( 75, aspect, 0.1, 1000 ) const camera = new THREE.OrthographicCamera( -sides, sides, caps, -caps, -1000, 1000 ) window.addEventListener('resize', () => { updateCamera(camera) }) camera.position.z = 500; return camera } function updateCamera(camera) { const { aspect } = windowDimensions() const { caps, sides } = cameraDimensions(aspect) camera.left = -sides, camera.right = sides, camera.top = caps, camera.bottom = -caps, camera.updateProjectionMatrix(); }

I figured out what the issue was. Ill describe how I solved it here for any future visitors. The problem is this code right here.

 function cameraDimensions(aspect, viewSize = 1000) { const caps = viewSize / 2 const sides = aspect*viewSize / 2 return { caps, sides } } export function getCamera() { const { aspect } = windowDimensions() const { caps, sides } = cameraDimensions(aspect) //const camera = new THREE.PerspectiveCamera( 75, aspect, 0.1, 1000 ) const camera = new THREE.OrthographicCamera( -sides, sides, caps, -caps, -1000, 1000 ) window.addEventListener('resize', () => { updateCamera(camera) }) camera.position.z = 500; return camera }

Or, more spesifically the way i was gettting top, bottom and sides for the OrthographicCamera in this function right here.

 function cameraDimensions(aspect, viewSize = 1000) { const caps = viewSize / 2 const sides = aspect*viewSize / 2 return { caps, sides } }

This way of calculating the camera works fine if you want your geometry to scale up and down with the render. But for what I was trying to do, ironically, I needed to set the values using the window size. Like this:

 const cameraDimensions = (aspect, viewSize = 1000) => ({ caps: window.innerHeight / 2, sides: window.innerWidth / 2 })

Big thanks to Darkmatter on the three.js discord that made a codepen for me to dig through to find the solution. Heres his codepen

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM