gpt4 book ai didi

javascript - 使用 three.js 循环浏览 Material onclick

转载 作者:行者123 更新时间:2023-11-30 19:55:59 25 4
gpt4 key购买 nike

我是 three.js 的新手,我想了解如何通过点击循环浏览 Material 。 This example展示了我想要实现的目标,除了它在纹理而不是 Material 之间循环。

我想将 Material 放在一个数组中,然后能够单击 Canvas 来循环和循环这些 Material 。

上面例子的代码如下:

var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );

var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
camera.position.y = 5;
camera.position.x = 5;
camera.lookAt(new THREE.Vector3(0,0,0)); // Make the camera look at the point of origin

var renderer = new THREE.WebGLRenderer({antialias:true});
var devicePixelRatio = window.devicePixelRatio || 1; // To handle high pixel density displays

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(devicePixelRatio);

document.body.appendChild( renderer.domElement );

var render = function () {

requestAnimationFrame( render );
renderer.render(scene, camera);
};

// instantiate a texture loader
var loader = new THREE.TextureLoader();
//allow cross origin loading
loader.crossOrigin = '';

// The textures to use
var arr = [
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_gates.jpg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_crate1.jpg',
'https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/THREE_crate2.jpg'
];
var textureToShow = 0;

// Load the first texture
// var texture = loadTexture('https://s3-us-west-2.amazonaws.com/s.cdpn.io/259155/MarbleSurface.jpg');

// Instantiate the material we will be using
var material = new THREE.MeshBasicMaterial();
// Instantiate a geometry to use
var geometry = new THREE.BoxGeometry( 1, 1, 1 );
// Instatiate the mesh with the geometry and material
var cube = new THREE.Mesh( geometry, material );
cube.position.y = 0.5;

// Then load the texture
loader.load(arr[textureToShow], function(tex) {
// Once the texture has loaded
// Asign it to the material
material.map = tex;
// Update the next texture to show
textureToShow++;
// Add the mesh into the scene
scene.add( cube );
});

// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];

canvas.addEventListener("click", function() {

loader.load(arr[textureToShow], function(tex) {
// Once the texture has loaded
// Asign it to the material
material.map = tex;
// Update the next texture to show
textureToShow++;
// Have we got to the end of the textures array
if(textureToShow > arr.length-1) {
textureToShow = 0;
}
});
});

// Start rendering the scene
render();

这是我无法运行的代码:

        var container, stats;
var camera, scene, renderer;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var globalObject;

init();
animate();

function init() {
container = document.createElement('div');
document.body.appendChild(container);

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.z = 500;

//scene
scene = new THREE.Scene();

ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);

pointLight = new THREE.PointLight(0xff0000, 0.5);
pointLight.position.z = 2500;
scene.add(pointLight);

var pointLight2 = new THREE.PointLight(0xff6666, 1);
camera.add(pointLight2);

var pointLight3 = new THREE.PointLight(0x0000ff, 0.5);
pointLight3.position.x = -1000;
pointLight3.position.z = 1000;
scene.add(pointLight3);

//manager
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};

//materials
var path = "textures/cube/skybox/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];

var reflectionCube = new THREE.CubeTextureLoader().load(urls);

var material = new THREE.MeshStandardMaterial({
envMap: reflectionCube,
roughness: 0.1,
metalness: 1,
color: 0xfee6af,
});

var materialTwo = new THREE.MeshStandardMaterial({
envMap: reflectionCube,
roughness: 0.1,
metalness: 0,
color: 0xffff00,
});




//model
var loader = new THREE.OBJLoader(manager);
loader.load('logo97.obj', function(object) {
//store global reference to .obj
globalObject = object;

object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = material;
child.material.needsUpdate = true;
}
});

object.position.y = 0;
scene.add(object);
});

//render
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}

function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}

// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];

canvas.addEventListener("click", function() {

var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;

materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
child.material = materials[materialToShow];


});

//animate
function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
camera.position.x += (mouseX - camera.position.x) * .05;
camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}

最佳答案

你必须创建一个 THREE.Material 的数组小号:

例如

var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;

“点击”可以改变当前 Material THREE.Mesh通过更改属性 .material .

canvas.addEventListener("click", function() {

materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
mesh.material = materials[materialToShow];
});

当然,您必须向场景添加一些光(例如 THREE.AmbientLightTHREE.DirectionalLight ),以使不同 Material 的行为“可见”。

查看示例,其中我将建议的更改应用于您的原始代码。
我用了一个球体来表示 THREE.MeshPhongMaterial 的镜面高光.
我删除了纹理,当然你也可以应用纹理。

var scene = new THREE.Scene();
scene.background = new THREE.Color( 0xcccccc );

var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.y = 4;
camera.lookAt(new THREE.Vector3(0,0,0)); // Make the camera look at the point of origin

var renderer = new THREE.WebGLRenderer({antialias:true});
var devicePixelRatio = window.devicePixelRatio || 1; // To handle high pixel density displays

renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(devicePixelRatio);

document.body.appendChild( renderer.domElement );
window.onresize = resize;

var ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(1,2,-1.0);
scene.add( directionalLight );

var render = function () {

requestAnimationFrame( render );
renderer.render(scene, camera);
};

var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;

var geometry = new THREE.SphereGeometry( 1, 32, 16 );
var mesh = new THREE.Mesh( geometry, materials[materialToShow] );
scene.add( mesh );

// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];

canvas.addEventListener("click", function() {

materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;
mesh.material = materials[materialToShow];
});

function resize() {

var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}

// Start rendering the scene
render();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>


自从您使用了 THREE.OBJLoader ,您必须更改 .children.material根对象 globalObject ( Object3D )。当然 materialToShowmaterials 只需初始化一次:

var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
canvas.addEventListener("click", function() {

materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;

globalObject.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = materials[materialToShow];
child.material.needsUpdate = true;
}
});
});

查看示例,其中我将更改应用于您的原始代码,并进行了一些更改以使其在此处工作:

var container, stats;
var camera, scene, renderer;
var mouseX = 0,
mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
var globalObject;

init();
animate();

function init() {
container = document.createElement('div');
document.body.appendChild(container);

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 2000);
camera.position.y = 3;
camera.position.z = 3;

//scene
scene = new THREE.Scene();

ambientLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(ambientLight);

var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
directionalLight.position.set(0.5,2,-1.0);
scene.add( directionalLight );

pointLight = new THREE.PointLight(0xff0000, 0.5);
pointLight.position.z = 10;
scene.add(pointLight);

var pointLight2 = new THREE.PointLight(0xff6666, 1);
camera.add(pointLight2);

var pointLight3 = new THREE.PointLight(0x0000ff, 0.5);
pointLight3.position.x = -10;
pointLight3.position.z = 10;
scene.add(pointLight3);

//manager
var manager = new THREE.LoadingManager();
manager.onProgress = function(item, loaded, total) {
console.log(item, loaded, total);
};

//materials
/*
var path = "textures/cube/skybox/";
var format = '.jpg';
var urls = [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
];
*/

//var reflectionCube = new THREE.CubeTextureLoader().load(urls);

var material = new THREE.MeshStandardMaterial({
//envMap: reflectionCube,
roughness: 0.1,
metalness: 1,
color: 0xfee6af,
});

var materialTwo = new THREE.MeshStandardMaterial({
//envMap: reflectionCube,
roughness: 0.1,
metalness: 0,
color: 0xffff00,
});


makeTextFile = function (text) {
var data = new Blob([text], {type: 'text/plain'});
var textFile = window.URL.createObjectURL(data);
return textFile;
}
var textbox_obj = document.getElementById('plane_obj');
var obj_url = makeTextFile(textbox_obj.value);


//model
var loader = new THREE.OBJLoader(manager);
loader.load(obj_url, function(object) {
//store global reference to .obj
globalObject = object;

object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = material;
child.material.needsUpdate = true;
}
});

object.position.y = 0;
scene.add(object);
});

//render
renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);

document.addEventListener('mousemove', onDocumentMouseMove, false);
window.addEventListener('resize', onWindowResize, false);
}

function onWindowResize() {
windowHalfX = window.innerWidth / 2;
windowHalfY = window.innerHeight / 2;
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}

function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX) / 2;
mouseY = (event.clientY - windowHalfY) / 2;
}

// Click interaction
var canvas = document.getElementsByTagName("canvas")[0];

var materials = [
new THREE.MeshBasicMaterial( {color:'#b02030'} ),
new THREE.MeshLambertMaterial( {color:'#b02030'} ),
new THREE.MeshPhongMaterial( {color:'#b02030', shininess: 100 } ),
new THREE.MeshNormalMaterial(),
// ...
];
var materialToShow = 0;
canvas.addEventListener("click", function() {

materialToShow ++;
if ( materialToShow >= materials.length ) materialToShow = 0;

globalObject.traverse(function(child) {
if (child instanceof THREE.Mesh) {
child.material = materials[materialToShow];
child.material.needsUpdate = true;
}
});
});

//animate
function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
//camera.position.x += (mouseX - camera.position.x) * .05;
//camera.position.y += (-mouseY - camera.position.y) * .05;
camera.lookAt(scene.position);
renderer.render(scene, camera);
}
<textarea id="plane_obj" style="display:none;">
# Blender v2.77 (sub 0) OBJ File: 'Plane.blend'
# www.blender.org
mtllib Plane.mtl
o Plane

v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000

vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000

vn 0.0000 1.0000 0.0000

usemtl Material
s off
f 1/1/1 2/2/1 4/4/1 3/3/1
</textarea>

<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
<script src="https://rawgit.com/mrdoob/three.js/dev/examples/js/loaders/OBJLoader.js"></script>

关于javascript - 使用 three.js 循环浏览 Material onclick,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53992754/

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