gpt4 book ai didi

javascript - 如何为 BufferGeometry 面添加纹理。?

转载 作者:数据小太阳 更新时间:2023-10-29 05:27:45 25 4
gpt4 key购买 nike

我创建了一个 bufferGeometry ,它由 5 个平面 (100x25) 组成,每个平面有两个三 Angular 形。

enter image description here


function createGeometry() {
var geometry = new THREE.PlaneGeometry(100, 25, 1);
return geometry;
}

function createScene() {

var bufferGeometry = new THREE.BufferGeometry();
var radius = 125;
var count = 5;

var positions = [];
var normals = [];
var colors = [];

var vector = new THREE.Vector3();
var color = new THREE.Color( 0xffffff );
var heartGeometry = createGeometry();
var geometry = new THREE.Geometry();

var step = 0;
for ( var i = 1, l = count; i <= l; i ++ ) {

geometry.copy( heartGeometry );

const y = i * 30
geometry.translate(-100, y, 0);

// color.setHSL( ( i / l ), 1.0, 0.7 );

geometry.faces.forEach( function ( face ) {
positions.push( geometry.vertices[ face.a ].x );
positions.push( geometry.vertices[ face.a ].y );
positions.push( geometry.vertices[ face.a ].z );
positions.push( geometry.vertices[ face.b ].x );
positions.push( geometry.vertices[ face.b ].y );
positions.push( geometry.vertices[ face.b ].z );
positions.push( geometry.vertices[ face.c ].x );
positions.push( geometry.vertices[ face.c ].y );
positions.push( geometry.vertices[ face.c ].z );

normals.push( face.normal.x );
normals.push( face.normal.y );
normals.push( face.normal.z );
normals.push( face.normal.x );
normals.push( face.normal.y );
normals.push( face.normal.z );
normals.push( face.normal.x );
normals.push( face.normal.y );
normals.push( face.normal.z );

colors.push( color.r );
colors.push( color.g );
colors.push( color.b );
colors.push( color.r );
colors.push( color.g );
colors.push( color.b );
colors.push( color.r );
colors.push( color.g );
colors.push( color.b );

});
}
bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );


var material = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
side: THREE.FrontSide
});

var mesh = new THREE.Mesh( bufferGeometry, material );
scene.add( mesh );

}

现在不用为每个平面着色我如何向每个平面添加文本。假设我只想在每个平面的中心显示 1、2、3、4、5。

我知道必须执行以下操作才能添加纹理。

  • 从 Canvas 生成纹理
  • 使用 map:texture 将 Material 更改为 Shader Material
  • uv 添加到 bufferGeometry。

但是uv和texture有什么关系。

我有纹理创建功能

//not sure for each character or one texture as a single texture
function createTexture(ch){

var fontSize = 20;
var c = document.createElement('canvas');
c.width = 100;
c.height = 25;
var ctx = c.getContext('2d');
ctx.font = fontSize+'px Monospace';
ctx.fillText(ch, c.width/2, c.height/2);

var texture = new THREE.Texture(c);
texture.flipY = false;
texture.needsUpdate = true;

return texture;
}

完整 DEMO Code

编辑

我正在考虑将性能作为此实验的高优先级。我们可以为每个文本添加每个网格,但这会增加屏幕中的网格数量并降低性能。我正在寻找在我的示例中使用单个网格的任何想法

我找到的最接近的是 this ,但我不明白他们使用的确切技术。

最佳答案

您必须复制 .faceVertexUvs 的第一个 uv channel 属性形式 THREE.Geometry ,类似于您对顶点坐标和法向量所做的:

for ( var i = 1, l = count; i <= l; i ++ ) {

geometry.copy( heartGeometry );

const y = i * 30
geometry.translate(-100, y, 0);

geometry.faces.forEach( function ( face ) {
let f = [face.a, face.b, face.c];
for (let i=0; i < 3; ++i) {
positions.push( ...geometry.vertices[f[i]].toArray() );
normals.push( ...face.normal.toArray() );
colors.push( ...color.toArray() );
}
} );

geometry.faceVertexUvs[0].forEach( function ( faceUvs ) {
for (let i=0; i < 3; ++i) {
uv.push( ...faceUvs[i].toArray() );
}
} );
}

如果你想为一个几何体定义多个纹理,那么你必须使用多个 THREE.Material s 一个 THREE.Mesh .

.addGroup 定义组(参见 THREE.BufferGeometry) .每个组将一系列顶点与 Material 相关联。

var bufferGeometry = new THREE.BufferGeometry();
bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
bufferGeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv, 2 ) );

let materials = []
let v_per_group= positions.length / 3 / count;
for ( var i = 0; i < count; i ++ ) {
bufferGeometry.addGroup(i * v_per_group, v_per_group, i);

let material = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
side: THREE.FrontSide,
map : createTexture("button" + (i+1))
});
materials.push(material);
}

var mesh = new THREE.Mesh( bufferGeometry, materials );
scene.add( mesh );

var camera, scene, renderer, controls, stats;
init();
animate();


function init() {
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 45.0, window.innerWidth / window.innerHeight, 100, 1500.0 );
camera.position.z = 480.0;
scene.add( camera );
controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.minDistance = 100.0;
controls.maxDistance = 800.0;
controls.dynamicDampingFactor = 0.1;

scene.add( new THREE.AmbientLight( 0xffffff, 1 ) );

createScene();
//stats = new Stats();
//document.body.appendChild( stats.dom );
window.addEventListener( 'resize', onWindowResize, false );
}

function createGeometry() {
var geometry = new THREE.PlaneGeometry(100, 25, 1);
return geometry;
}

function createTexture(ch){

var fontSize = 20;
var c = document.createElement('canvas');
c.width = 128;
c.height = 32;
var ctx = c.getContext('2d');

ctx.beginPath();
ctx.rect(0, 0, 128, 32);
ctx.fillStyle = "white";
ctx.fill();

ctx.fillStyle = "black";
ctx.font = fontSize+'px Monospace';
ctx.fillText(ch, 20, 24);

var texture = new THREE.Texture(c);
texture.flipY = true;
texture.needsUpdate = true;

return texture;
}

function createScene() {

var radius = 125;
var count = 5;

var vector = new THREE.Vector3();
var color = new THREE.Color( 0xffffff );
var heartGeometry = createGeometry();
var geometry = new THREE.Geometry();

var positions = [];
var normals = [];
var colors = [];
var uv = [];

for ( var i = 1, l = count; i <= l; i ++ ) {

geometry.copy( heartGeometry );

const y = i * 30
geometry.translate(-100, y, 0);

geometry.faces.forEach( function ( face ) {
let f = [face.a, face.b, face.c];
for (let i=0; i < 3; ++i) {
positions.push( ...geometry.vertices[f[i]].toArray() );
normals.push( ...face.normal.toArray() );
colors.push( ...color.toArray() );
}
} );

geometry.faceVertexUvs[0].forEach( function ( faceUvs ) {
for (let i=0; i < 3; ++i) {
uv.push( ...faceUvs[i].toArray() );
}
} );
}

var bufferGeometry = new THREE.BufferGeometry();
bufferGeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ) );
bufferGeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ) );
bufferGeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( colors, 3 ) );
bufferGeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( uv, 2 ) );

let materials = []
let v_per_group = positions.length / 3 / count;
for ( var i = 0; i < count; i ++ ) {
bufferGeometry.addGroup(i * v_per_group, v_per_group, i);

let material = new THREE.MeshBasicMaterial({
vertexColors: THREE.VertexColors,
side: THREE.FrontSide,
map : createTexture("button" + (i+1))
});
materials.push(material);
}

var mesh = new THREE.Mesh( bufferGeometry, materials );
scene.add( mesh );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
controls.update();
//stats.update();
renderer.render( scene, camera );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>

关于javascript - 如何为 BufferGeometry 面添加纹理。?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55472178/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com