Three.js中使用MarkPass(掩码)的高级效果组合器
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Three.js中使用MarkPass(掩码)的高级效果组合器相关的知识,希望对你有一定的参考价值。
参考技术A 可以对指定的scene运行后期效果。(1)创建一个作为背景图片的场景。
(2)创建一个场景,里面包含一个看起来像地球的球体。
(3)创建一个场景,里面包含一个看起来像火星的球体。
(4)创建EffectComposer对象,用于将这三个场景渲染到一个图片中。
(5)在渲染为火星的球体上应用彩色效果。
(6)在渲染为地球的球体上应用褐色效果。
1、 我们直接使用场景的背景属性来添加星光背景图片。还有一种可选方式也可以同于添加背景图片,那就是利用THREE.OrthoGraphicCamera(正交摄像机)。因为THREE.OrthoGraphicCamera不会根据物体距离摄像机的距离来缩放物体,所以可以添加一个正对摄像机的THREE.PlaneGeometry几何体,然后在上面添加图片。
2、场景渲染时候需要将渲染器改为组合器的渲染器,并且需要将WebGLRenderer中autoClear设置为false
在three.js中使用正交相机进行不精确的光线投射
【中文标题】在three.js中使用正交相机进行不精确的光线投射【英文标题】:Imprecise raycast with orthographic camera in three.js 【发布时间】:2019-10-14 09:20:03 【问题描述】:我正在使用 three.js 库开发 CAD 绘图的 2d 查看器,对于这个项目,我需要能够单击场景中的对象来执行一些操作。
使用正交相机,three.js 光线投射并不像我预期的那样精确。
这里的代码和一个小提琴,正是我的意思 https://jsfiddle.net/toriphes/a0o7td1u/
var camera, scene, renderer, square, raycaster;
init();
animate();
function init()
output = document.getElementById('output');
raycaster = new THREE.Raycaster();
// Renderer.
renderer = new THREE.WebGLRenderer();
//renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Add renderer to page
document.body.appendChild(renderer.domElement);
// Create camera.
var aspect = window.innerWidth / window.innerHeight;
var d = 20;
camera = new THREE.OrthographicCamera(-window.innerWidth / 2, window.innerWidth / 2, window.innerHeight / 2, -window.innerHeight / 2, 1, 1000);
camera.position.z = 10;
camera.position.x = 25;
camera.position.y = 25;
camera.zoom = 10
camera.updateProjectionMatrix()
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableRotate = false
controls.target.x = camera.position.x;
controls.target.y = camera.position.y;
controls.update();
// Create scene.
scene = new THREE.Scene();
var points = [
new THREE.Vector2(10, 10),
new THREE.Vector2(40, 10),
new THREE.Vector2(40, 40),
new THREE.Vector2(10, 40),
new THREE.Vector2(10, 10)
]
var shape = new THREE.Shape(points);
var geometry = new THREE.Geometry().setFromPoints(points);
var square = new THREE.Line(geometry, new THREE.LineBasicMaterial(
color: 0xFF0000
));
scene.add(square)
document.addEventListener('mousemove', findIntersections, false);
function animate()
requestAnimationFrame(animate);
renderer.render(scene, camera);
function updateMousePosition(event)
return new THREE.Vector3(
(event.clientX - renderer.domElement.offsetLeft) /
renderer.domElement.clientWidth *
2 -
1,
-(
(event.clientY - renderer.domElement.offsetTop) /
renderer.domElement.clientHeight
) *
2 +
1,
0
);
function findIntersections(e)
var mouseposition = updateMousePosition(e);
raycaster.setFromCamera(mouseposition, camera);
const intersects = raycaster.intersectObjects(scene.children);
output.innerHTML = intersects.length > 0 ?
'Intersect: TRUE' :
'Intersect: FALSE';
如果你在红色方块附近通过鼠标,你可以看到交叉点在悬停边缘之前触发。
我做错了什么?
【问题讨论】:
【参考方案1】:线的交点检测取决于Raycaster
的.linePrecision
属性。
例如
raycaster.linePrecision = 0.1;
const intersects = raycaster.intersectObjects(scene.children);
必须根据场景的比例设置参数。 0.1 的值是一个经验值,它为您的示例提供了良好的结果。遗憾的是,文档中没有提供更多信息(也许我忽略了一些东西,但我没有找到)。
【讨论】:
linePrecision = 0.1
似乎适用于我的项目。有更多关于它的文档会很有用。
很棒的提示。我使用值 0.01,这给了我想要的准确性。但大概这意味着光线投射器必须比使用值 0.1 时多做 10x10=100 倍的工作。 |是的,offical docs 中没有提到 linePrecision 属性。但是提到了params
对象,其中threshold
是光线投射器在与各种对象相交时的精度,以世界单位为单位。它解释了为什么当线对象的默认阈值为 1 时有时很难选择网格对象。 以上是关于Three.js中使用MarkPass(掩码)的高级效果组合器的主要内容,如果未能解决你的问题,请参考以下文章
如何让 three.js 在 React Native 中运行(没有 WebView)?