【发布时间】:2020-08-06 11:26:41
【问题描述】:
概述:
- 我有一个带有定位透视相机和多个资产的场景,可以产生我想要的输出
- 我不想移动/更改相机的 fov,因为这需要我动态调整场景中的所有元素(请参阅调试相机视图图像)
- 我想要一个场景的“视图裁剪”,从全尺寸到更小的尺寸(并不总是相同的比例。查看生成的画布图像
我尝试过以下组合:
renderer.setScissor(0, 0, 320, 240)
renderer.setScissorTest(true)
renderer.setViewport(0, 0, 320, 240)
renderer.setSize(320, 240)
renderer.getContext().canvas.width = 320
renderer.getContext().canvas.height = 240
renderer.getContext().canvas.style.width = '320px'
renderer.getContext().canvas.style.height = '240px'
- 应用剪刀给了我想要看到的示例,因为只有那些项目被渲染,但整个视图仍然是相同的大小
- 应用视口会缩小整个图像,
- 相对于整个图像而不是我要裁剪的点调整画布裁剪。
我可以进行 blitting(将我想要的确切像素复制到单独的画布上,但我希望有另一种更简单的方法。
有什么想法吗?
我在这里添加了一个 codepen 示例: https://codepen.io/faysvas/pen/KKzPQpa
const makeCube = (scene, color, x) => {
const material = new THREE.MeshPhongMaterial({ color })
const cube = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material)
scene.add(cube)
cube.position.x = x
return cube;
}
const addSceneContents = (scene) => {
const light = new THREE.DirectionalLight(0xffffff, 1)
light.position.set(-1, 2, 4)
scene.add(light)
return [
makeCube(scene, 0x44aa88, 0),
makeCube(scene, 0x8844aa, -2),
makeCube(scene, 0xaa8844, 2)
]
}
const main = () => {
const canvas = document.querySelector("#c")
const renderer = new THREE.WebGLRenderer({ canvas })
renderer.setSize(512, 512, false)
const fov = 75
const aspect = 1
const near = 0.1
const far = 5
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
camera.position.z = 2
const scene = new THREE.Scene()
scene.background = new THREE.Color( 0xff0000 )
let cubes = addSceneContents(scene)
resizeTo320x240(renderer, canvas)
const render = (time) => {
time *= 0.001
cubes.forEach((cube, ndx) => {
const speed = 1 + ndx * 0.1
const rot = time * speed
cube.rotation.x = rot
cube.rotation.y = rot
})
renderer.render(scene, camera)
requestAnimationFrame(render)
}
requestAnimationFrame(render)
}
/*
This function should 'crop' from the whole scene without
distorting the perspective of the camera and ensuring the
canvas is 320x240
e.g. I want the canvas to be the same size and output of
red cropped view below. Eg, no black and the canvas (and
it's red contents) should be in the top left of the corner
of the screen
*/
const resizeTo320x240 = (renderer, canvas) => {
console.log('code goes here')
const desiredWidth = 320
const desiredHeight = 240
const currentSize = renderer.getSize(new THREE.Vector2())
const x = (currentSize.x / 2) - (desiredWidth/2)
const y = (currentSize.y / 2) - (desiredHeight/2)
renderer.setScissor(x, y, desiredWidth, desiredHeight)
renderer.setScissorTest(true)
//renderer.setViewport(x, y, desiredWidth, desiredHeight)
}
main()
html, body {
margin: 0;
height: 100%;
background-color: grey;
}
#c {
display: block;
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r119/three.min.js"></script>
<canvas id="c"></canvas>
【问题讨论】:
标签: three.js rendering viewport