【发布时间】:2013-04-14 00:45:32
【问题描述】:
此问题与此question 有关。 answer 展示了一种非常好的方法来挤出有孔的多边形(参见the excellent live example)。答案的主要学习是three.js(r58)中的路径不能有多个moveTo命令并且它必须在路径的开头,这意味着路径必须被moveTos打破,以便moveTo开始总是一条新路。
在three.js 中拉伸意味着使用可能的斜角将2D 路径转换为3D 形状。它适用于挤压文本以制作 3D 字母和单词,但也可用于挤压自定义路径。
现在有两个问题:
- 如何处理具有多个孔多边形和多个非孔多边形的多边形?
- 如何将纹理添加到生成的整体形状中?
我在http://jsbin.com/oqomuj/1/edit 中做了一个 SVG 的例子:
使用此路径生成图像:
路径>并将此路径转换为单个顶点数组:
var lower_house_material = [{x:57.11,y:271.77},{x:57.11,y:218.33},{x:41.99,y:218.63},{x:105.49,y:165.77},{x:138.42,y :193.18},{x:138.42,y:172.2},{x:152.53,y:172.2},{x:152.53,y:204.93},{x:168.99,y:218.63},{x:153.21,y :218.63},{x:153.21,y:271.77}]; var lower_house_hole_1 = [{x:74.14,y:264.13},{x:105.49,y:264.13},{x:105.49,y:232.8},{x:74.14,y:232.8}]; var lower_house_hole_2 = [{x:115.35,y:250.7},{x:135.96,y:250.7},{x:135.96,y:232.61},{x:115.35,y:232.61}]; var upper_house_material = [{x:56.11,y:145.77},{x:56.11,y:92.33},{x:40.99,y:92.63},{x:104.49,y:39.77},{x:137.42,y :67.18},{x:137.42,y:46.2},{x:151.53,y:46.2},{x:151.53,y:78.93},{x:152.53,y:79.76},{x:155.55,y :77.23},{x:159.5,y:74.52},{x:168.65,y:69.81},{x:176.46,y:66.93},{x:188.04,y:64.16},{x:200.63,y :62.7},{x:213.65,y:62.7},{x:226.05,y:64.1},{x:234.83,y:66.06},{x:245.65,y:69.73},{x:252.87,y :73.27},{x:259.12,y:77.35},{x:262.63,y:80.33},{x:265.6,y:83.47},{x:268.01,y:86.76},{x:269.84,y :90.17},{x:271.08,y:93.68},{x:271.76,y:99.08},{x:271.04,y:104.64},{x:269.75,y:108.2},{x:267.87,y :111.63},{x:265.42,y:114.91},{x:262.44,y:118.01},{x:258.96,y:120.92},{x:255.02,y:123.63},{x:245.86,y :128.34},{x:238.06,y:131.22},{x:226.48,y:133.99},{x:213.88,y:135.45},{x:200.63,y:135.45},{x:188.04,y :133.99},{x:176.46,y:131.22},{x:168.65,y:128.34},{x:159.5,y:123.63},{x:155.55,y:120.92},{x:152.21,y :118.12},{x:152.21,y:145.77}]; var upper_house_hole_1 = [{x:73.14,y:138.13},{x:104.49,y:138.13},{x:104.49,y:106.8},{x:73.14,y:106.8}]; var upper_house_hole_2 = [{x:114.35,y:124.7},{x:134.96,y:124.7},{x:134.96,y:106.61},{x:114.35,y:106.61}]; var upper_house_hole_3 = [{x:207.26,y:117.33},{x:210.57,y:117.26},{x:216.87,y:116.53},{x:222.66,y:115.15},{x:227.8,y :113.18},{x:233.11,y:110},{x:236.34,y:106.99},{x:238.51,y:103.64},{x:239.42,y:100.48},{x:239.42,y :97.67},{x:238.51,y:94.51},{x:236.34,y:91.16},{x:233.11,y:88.15},{x:227.8,y:84.97},{x:222.66,y :83},{x:216.87,y:81.62},{x:210.57,y:80.89},{x:203.94,y:80.89},{x:197.65,y:81.62},{x:191.86,y :83},{x:186.71,y:84.97},{x:181.41,y:88.15},{x:178.18,y:91.16},{x:176.01,y:94.51},{x:175.1,y :97.67},{x:175.1,y:100.48},{x:176.01,y:103.64},{x:178.18,y:106.99},{x:181.41,y:110},{x:186.71,y :113.18},{x:191.86,y:115.15},{x:197.65,y:116.53},{x:203.94,y:117.26}];问题是,如何在 three.js 中将这种类似结构转换为 3D 对象,以便可以使用 THREE.ExtrudeGeometry( shape, extrusionSettings ) 将其挤出,然后将其作为一个整体纹理化?
我可以检查路径数据以了解哪个洞属于哪个多边形并将所有这些都作为单独的形状处理,但因为我想在所有形状中使用一个纹理图像,我认为首选方式是将所有材质多边形作为一种形状处理,将孔多边形作为另一种形状处理,并使用以下内容:
var shape = [lower_house_material,upper_house_material]; shape.holes = [lower_house_hole_1,lower_house_hole_2,upper_house_hole_1,upper_house_hole_2,upper_house_hole_3]; var 3d_geometry = THREE.ExtrudeGeometry(形状,挤压设置);所以3d_geometry 应该在最后一个网格,我可以通过这种方式向其附加纹理:
其中一个纹理可能是这样的(256x256px):
并应用纹理:
而且因为网格是挤压出来的,所以上面还有3D厚度,但是你得到了纹理的概念。
我知道 y 坐标必须翻转,但这是一项微不足道的任务,不是我的问题的重点,但如果 three.js 有现成的裁剪 y 的功能,那会很有帮助。
我花了好几个小时来检查three.js 源代码、示例和documentation,但是因为其中最常见的词是“todo”,所以没有多大帮助。而且我是three.js的新手,我认为这对于一些有经验的three.js用户来说可能是微不足道的任务。
更新:为了确保孔多边形始终表现良好,这意味着孔多边形始终完全位于材质多边形内,并且在材质多边形或孔洞中没有重复的顶点或自相交多边形和所有材质多边形都有 CW 缠绕顺序和孔 CCW。
更新:合并几何不是为由一个纹理设置的整个挤压多边形设置纹理的解决方案:http://jsfiddle.net/C5dga。纹理在所有单独的形状上重复,因此在这种情况下合并几何没有真正的意义。解决方案可能在它们被挤出之前合并形状中找到,但尚未找到解决方案。
【问题讨论】:
-
这就是 SVG 过滤器的发明目的。我不熟悉它们的 three.js 语法,但基本上,您使用 feImage 拉入纹理,然后对源图形执行 feComposite operator="in"。
-
感谢您的评论。确实,支持过滤器的浏览器可以在 SVG 中产生类似的效果,但在这个问题中,我对在 three.js 中对 3D 形状进行纹理化以在浏览器的 webGL 引擎中渲染输出感兴趣。
标签: svg three.js textures polygon