Three.js对象网格



我想用Three.js绘制一个网格,这样,给定一个对象中心和大小:

  1. 它根据对象大小动态调整粒度(网格线之间的空间(
  2. 轴线与对象无关

我已经实现了第一个需求。第二个很难解释,但用这个例子可能更容易理解:https://jsfiddle.net/rendoir/gua7qd0s

在这个演示中,你可以看到,如果你按下s,对象的大小会增加,网格也会增加。栅格分割会根据对象大小的大小顺序进行相应更改。

问题2(是网格的位置相对于对象的位置(它们具有相同的中心(。因此,网格总是与对象完美匹配
我想做的是打破这种错觉,让它看起来像网格存在于世界空间中,从世界原点开始,出现在物体后面
最简单的方法是开发一个网格,其大小可以从原点开始包含对象。然而,由于场景和相机将是静态的(本例中的情况并非如此(,我想要一个刚好足以容纳对象的网格(不需要从原点开始,因为对象可能离它很远(,并且分割的数量(网格线之间的粒度(仍随其大小而变化。

我知道第一个问题的当前解决方案可能与第二个问题冲突,所以我正在寻找想法,甚至现有的解决方案(如果有的话(。

注意:您可以假设对象始终是一个四边形。单击"c"还可以更改对象的中心。

主代码在Grid类中:

let divisions = getDivisions(size);
let step = size / divisions;
let halfSize = size / 2;
let vertices = [];
for ( let i = 0, k = - halfSize + step; i < divisions - 1; i ++, k += step ) {
vertices.push( - halfSize, k, 0, halfSize, k, 0 );
vertices.push( k, - halfSize, 0, k, halfSize, 0 );
}
// ...
lineSegments.position.set(this.center.x, this.center.y, this.center.z);

一个选项是:

let box = new THREE.Box3().setFromObject( theObject );
let sz = box.getSize(new THREE.Vector3())
let root = new THREE.Object3D();
let maxSz = Math.max(Math.max(sz.x,sz.y),sz.z)
root.scale.multiplyScalar( 1.0 / maxSz )
root.add( theObject )
scene.add(root);

现在,将始终缩放对象,使其最大轴大小为1。

Box3((.setFromObject确实很有用,但它可能会有一些成本,这取决于THREE需要做多少工作来确定对象的最终大小。所以,也许可以避免经常打电话给它。object.localToWorld和.worldToLocal也非常有用。。仅供参考。

也请注意。。http://madebyevan.com/shaders/grid/有一些很酷的方法来制作网格着色器。

您可以为此目的使用着色器。

相关论坛主题:

https://discourse.threejs.org/t/three-infinitegridhelper-anti-aliased/8377?u=prisoner849

https://discourse.threejs.org/t/how-to-achieve-this-material-effect-gif-image/1270?u=prisoner849

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setClearColor(0x888888);
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var geom = new THREE.PlaneBufferGeometry();
var mat = new THREE.ShaderMaterial({
vertexShader: `
varying vec4 vPos;
void main() {
vPos = modelMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * viewMatrix * vPos;
}
`,
fragmentShader: `
//http://madebyevan.com/shaders/grid/

#extension GL_OES_standard_derivatives : enable
varying vec4 vPos;
void main() {
vec2 coord = vPos.xy;
vec2 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord);
float line = min(grid.x, grid.y);
gl_FragColor = vec4(vec3(1.0 - min(line, 1.0)), 1.0);
}
`
});
var plane = new THREE.Mesh(geom, mat);
scene.add(plane);
var clock = new THREE.Clock();
renderer.setAnimationLoop(() => {
let t = clock.getElapsedTime();
let scale = 5 + (Math.sin(t) * 0.5 + 0.5) * 2;
plane.scale.set(scale, scale, 1);
plane.position.set(
Math.cos(t),
Math.sin(t),
0
);
renderer.render(scene, camera);
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

最新更新