向ExtrudeGeometry添加纹理(Adding a Texture to ExtrudeGeometry)

编程入门 行业动态 更新时间:2024-10-19 21:31:51
向ExtrudeGeometry添加纹理(Adding a Texture to ExtrudeGeometry)

three.js v53

在JSFiddle的three.js v 53中,制作自定义形状,挤出它并应用纹理和线框显示挤出的面是整体,完整的正方形。

JSFiddle: 在 v53中挤出的自定义形状,具有完整的未分割挤出面

three.js v74

完全相同的代码但是three.js v 74将拉伸面分成三角形。

JSFiddle: 在v74中挤出的自定义形状,具有分段(成三角形)挤出面

问题1:如何在v74中消除分割成挤压面的三角形?

奖金问题2:如何消除我挤出的形状主面上的三角形分割(当我注意到three.js版本之间的挤压差异时,我原本试图解决的问题)

两者都让我的纹理化之旅更加艰难。 非常感谢。

两个JSFiddles的代码:

(有些代码是从另一个JS Fiddle那里借来的,但我再也找不到了它的信用)

/**** Create the texture as I can't use an image on my server *****/ var canvas = document.getElementById("texture"), context = canvas.getContext("2d"); canvas.width = 50; canvas.height = 50; context.strokeStyle = "#5588ff"; context.lineWidth = 2; context.moveTo(0, 10); context.lineTo(50, 10); context.moveTo(0, 20); context.lineTo(50, 20); context.moveTo(0, 30); context.lineTo(50, 30); context.moveTo(0, 40); context.lineTo(50, 40); context.stroke(); /***********/ var scene, camera, renderer, shape; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, 2, 1, 10000); camera.position.z = 200; scene.add(this.camera); var light = new THREE.AmbientLight(0xffffff); scene.add(light); renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true }); document.getElementById("scene").appendChild(renderer.domElement); renderer.setSize(document.getElementById("scene").scrollWidth, document.getElementById("scene").scrollHeight); var points = [] points.push(new THREE.Vector2(100, 0)); points.push(new THREE.Vector2(100, 60)); points.push(new THREE.Vector2(40, 90)); points.push(new THREE.Vector2(-40, 90)); points.push(new THREE.Vector2(-100, 60)); points.push(new THREE.Vector2(-100, 0)); // var path = new THREE.LineCurve3(new THREE.Vector3(45, 0, 0), new THREE.Vector3(-45, 0, 0)); var extrusionSettings = { steps: 1, bevelEnabled: false, amount: 90 }; shape = new THREE.Shape(points); var geometry = new THREE.ExtrudeGeometry(shape, extrusionSettings), texture = new THREE.Texture(canvas); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({ color: 0xFF00FF, map: texture }); // *** UVMapping stuff I copied off an example. I don't know what it's doing but the texture won't work without it. geometry.faceUvs = [ [] ]; geometry.faceVertexUvs = [ [] ]; for (var f = 0; f < geometry.faces.length; f++) { var faceuv = [ new THREE.Vector2(0, 1), new THREE.Vector2(1, 1), new THREE.Vector2(1, 0), new THREE.Vector2(0, 0) ]; geometry.faceUvs[0].push(new THREE.Vector2(0, 1)); geometry.faceVertexUvs[0].push(faceuv); } // add a wireframe to highlight the segmentation (or lack of in this v53 demo) mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, [material, new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: true, transparent: true })]); mesh.position.z = -50; mesh.position.y = -40; mesh.rotation.y = 0.8; mesh.rotation.z = 0.4; scene.add(mesh); animate = function() { requestAnimationFrame(animate); renderer.render(scene, camera); mesh.rotation.y += 0.02; mesh.rotation.x += 0.02; }; animate();

three.js v53

In three.js v 53 on JSFiddle, making a custom shape, extruding it and applying a texture and wireframe shows the extruded faces being whole, complete squares.

JSFiddle: custom shape extruded in v53 with complete, un-split extrusion faces

three.js v74

The exact same code but three.js v 74 splits the extrude faces into triangles.

JSFiddle: custom shape extruded in v74 with segmented (into triangles) extrusion faces

Question 1: how can I eliminate the segmentation into triangles of the extruded faces in v74?

Bonus Question 2: how can I eliminate the segmentation into triangles on the main face of my shape that I extrude (what I was originally trying to solve when I noticed the extrusion differences between three.js versions)

Both are making my texturing journey harder. Many thanks.

Code for both JSFiddles:

(Some code borrowed from another JS Fiddle but I can't find it again to credit)

/**** Create the texture as I can't use an image on my server *****/ var canvas = document.getElementById("texture"), context = canvas.getContext("2d"); canvas.width = 50; canvas.height = 50; context.strokeStyle = "#5588ff"; context.lineWidth = 2; context.moveTo(0, 10); context.lineTo(50, 10); context.moveTo(0, 20); context.lineTo(50, 20); context.moveTo(0, 30); context.lineTo(50, 30); context.moveTo(0, 40); context.lineTo(50, 40); context.stroke(); /***********/ var scene, camera, renderer, shape; scene = new THREE.Scene(); camera = new THREE.PerspectiveCamera(75, 2, 1, 10000); camera.position.z = 200; scene.add(this.camera); var light = new THREE.AmbientLight(0xffffff); scene.add(light); renderer = new THREE.WebGLRenderer({ antialias: true, alpha:true }); document.getElementById("scene").appendChild(renderer.domElement); renderer.setSize(document.getElementById("scene").scrollWidth, document.getElementById("scene").scrollHeight); var points = [] points.push(new THREE.Vector2(100, 0)); points.push(new THREE.Vector2(100, 60)); points.push(new THREE.Vector2(40, 90)); points.push(new THREE.Vector2(-40, 90)); points.push(new THREE.Vector2(-100, 60)); points.push(new THREE.Vector2(-100, 0)); // var path = new THREE.LineCurve3(new THREE.Vector3(45, 0, 0), new THREE.Vector3(-45, 0, 0)); var extrusionSettings = { steps: 1, bevelEnabled: false, amount: 90 }; shape = new THREE.Shape(points); var geometry = new THREE.ExtrudeGeometry(shape, extrusionSettings), texture = new THREE.Texture(canvas); texture.needsUpdate = true; var material = new THREE.MeshBasicMaterial({ color: 0xFF00FF, map: texture }); // *** UVMapping stuff I copied off an example. I don't know what it's doing but the texture won't work without it. geometry.faceUvs = [ [] ]; geometry.faceVertexUvs = [ [] ]; for (var f = 0; f < geometry.faces.length; f++) { var faceuv = [ new THREE.Vector2(0, 1), new THREE.Vector2(1, 1), new THREE.Vector2(1, 0), new THREE.Vector2(0, 0) ]; geometry.faceUvs[0].push(new THREE.Vector2(0, 1)); geometry.faceVertexUvs[0].push(faceuv); } // add a wireframe to highlight the segmentation (or lack of in this v53 demo) mesh = THREE.SceneUtils.createMultiMaterialObject(geometry, [material, new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: true, transparent: true })]); mesh.position.z = -50; mesh.position.y = -40; mesh.rotation.y = 0.8; mesh.rotation.z = 0.4; scene.add(mesh); animate = function() { requestAnimationFrame(animate); renderer.render(scene, camera); mesh.rotation.y += 0.02; mesh.rotation.x += 0.02; }; animate();

最满意答案

THREE.ExtrudeGeometry根据拉伸形状的坐标为您创建默认UV。 (查看拉伸形状的几何图形并检查为您计算的UV。)

自动生成的UV可能会超出[0,1]的正常范围。 你可以通过使用这样的模式来适应这种情况:

texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.offset.set( 0, 0.5 ); texture.repeat.set( 0.01, 0.01 );

更新小提琴: http : //jsfiddle.net/vxr3Ljf3/4/

或者,您可以指定自己的自定义UV生成器,如下所示:

var extrusionSettings = { steps: 1, bevelEnabled: false, amount: 90, UVGenerator: myUVGenerator };

将自定义UV生成器基于THREE.ExtrudeGeometry.WorldUVGenerator 。

three.js r.74

THREE.ExtrudeGeometry creates default UVs for you based on the coordinates of the extruded shape. (Look at the geometry of the extruded shape and inspect the UVs that are computed for you.)

The auto-generated UVs will likely be outside the normal range of [ 0, 1 ]. You can accommodate that by using a pattern like so:

texture.wrapS = texture.wrapT = THREE.RepeatWrapping; texture.offset.set( 0, 0.5 ); texture.repeat.set( 0.01, 0.01 );

Updated fiddle: http://jsfiddle.net/vxr3Ljf3/4/

Alternatively, you can specify your own custom UV generator like so:

var extrusionSettings = { steps: 1, bevelEnabled: false, amount: 90, UVGenerator: myUVGenerator };

Base your custom UV generator on THREE.ExtrudeGeometry.WorldUVGenerator.

three.js r.74

更多推荐

本文发布于:2023-08-06 05:30:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1444537.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:纹理   ExtrudeGeometry   Texture   Adding

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!