Я пытаюсь создать сцену, полную точек, каждая из которых имеет уникальную ширину и высоту.Тем не менее, я не могу понять, как попасть в вершинный шейдер, чтобы перемещать вершины для создания пользовательских размеров.Вот сцена:
// generate a scene object
var scene = new THREE.Scene();
scene.background = new THREE.Color(0xaaaaaa);
// generate a camera
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 10000);
camera.position.set(0, 1, -10);
// generate a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio); // <3 retina
renderer.setSize(window.innerWidth, window.innerHeight); // canvas size
document.body.appendChild(renderer.domElement);
// generate controls
var controls = new THREE.TrackballControls(camera, renderer.domElement);
// generate some lights
var ambientLight = new THREE.AmbientLight(0xeeeeee);
scene.add(ambientLight);
/**
* Add the points
**/
var BA = THREE.BufferAttribute;
var IBA = THREE.InstancedBufferAttribute;
var geometry = new THREE.InstancedBufferGeometry();
var n = 10000, // number of observations
rootN = n**(1/2),
cellSize = 20,
translations = new Float32Array(n * 3),
widths = new Float32Array(n),
heights = new Float32Array(n),
translationIterator = 0,
widthIterator = 0,
heightIterator = 0;
for (var i=0; i<n*3; i++) {
translations[translationIterator++] = (Math.random() * n) - (Math.random() * n);
translations[translationIterator++] = (Math.random() * n) - (Math.random() * n);
translations[translationIterator++] = (Math.random() * n) - (Math.random() * n);
widths[widthIterator++] = Math.random() * 20;
heights[heightIterator++] = Math.random() * 20;
}
// coordinates for template box
var size = 10,
verts = [
0, 0, 0, // lower left
size, 0, 0, // lower right
size, size, 0, // upper right
0, size, 0, // upper left
]
var positionAttr = new BA(new Float32Array(verts), 3),
translationAttr = new IBA(translations, 3, true, 1),
widthAttr = new IBA(widths, 1, true, 1),
heightAttr = new IBA(heights, 1, true, 1);
// we make two triangles but only use 4 distinct vertices in the object
// the second argument to THREE.BufferAttribute is the number of elements
// in the first argument per vertex
geometry.setIndex([0,1,2, 2,3,0])
geometry.addAttribute('position', positionAttr);
geometry.addAttribute('translation', translationAttr);
geometry.addAttribute('width', widthAttr);
geometry.addAttribute('height', heightAttr);
var material = new THREE.RawShaderMaterial({
vertexShader: document.getElementById('vertex-shader').textContent,
fragmentShader: document.getElementById('fragment-shader').textContent,
});
material.side = THREE.DoubleSide;
var mesh = new THREE.Mesh(geometry, material);
mesh.frustumCulled = false; // prevent the mesh from being clipped on drag
scene.add(mesh);
// render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
controls.update();
};
// draw some geometries
var geometry = new THREE.TorusGeometry(10, 3, 16, 100);
var material = new THREE.MeshNormalMaterial({ color: 0xffff00 });
render();
html, body { width: 100vw; height: 100vh; background: #000; }
body { margin: 0; overflow: hidden; }
canvas { width: 100vw; height: 100vh; }
<script src='https://cdnjs.cloudflare.com/ajax/libs/three.js/97/three.min.js'></script>
<script src='https://threejs.org/examples/js/controls/TrackballControls.js'></script>
<script type='x-shader/x-vertex' id='vertex-shader'>
precision highp float;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform vec3 cameraPosition;
attribute vec3 position; // sets the blueprint's vertex positions
attribute vec3 translation; // x y translation offsets for an instance
attribute float width;
attribute float height;
void main() {
// set point position
vec3 pos = position + translation;
vec4 projected = projectionMatrix * modelViewMatrix * vec4(pos, 1.0);
gl_Position = projected;
}
</script>
<script type='x-shader/x-fragment' id='fragment-shader'>
precision highp float;
void main() {
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
</script>
Мой вопрос: как я могу использовать атрибуты ширины и высоты, чтобы каждая точка имела заданные (относительные) пропорции, определяемые ее шириной изначения высоты?Могу ли я запросить индекс вершины, нарисованной в данном экземпляре?Любые предложения будут очень полезны!