Log*_*og0 9 html javascript webgl ios three.js
我正在尝试THREE.Texture
使用HTML5画布对象更新“ .image”属性。这可以在笔记本电脑上的Chromium(MacOSX)上使用。但是,iPhone Safari和iPhone Chrome均不起作用。根本原因是什么?如何解决?
在Safari中使用Web Inspector时,出现以下错误消息:
WebGL:INVALID_VALUE:texImage2D:无画布。
我使用以下代码更新材质,以确保在更新之前完全绘制了画布:
material.map.image = loaded_canvas[curr_id]; // loaded_canvas stores canvas that has been completed loaded already, drawn by Image() objects.
material.map.needsUpdate = true;
Run Code Online (Sandbox Code Playgroud)
这是材料的使用方式:
var geometry = new THREE.SphereGeometry(100.0, 32, 32);
var material = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture(image_path),
side: THREE.BackSide,
});
Run Code Online (Sandbox Code Playgroud)
奇怪的是,如果我THREE.ImageUtils.loadTexture
用来加载图像,它可以正常工作。但是,我的用例是必须使用canvas对象(画布上的多个图像)。
谢谢。
根据Texture
docs, .image 属性更像是通过该TextureLoader.load()
方法创建的图像元素的“getter”。如果您想使用元素创建纹理<canvas>
,可以new THREE.Texture(canvas);
使用下面的代码片段演示的方式创建它。纹理创建发生在makeCanvasTexture()
函数中:
function makeCanvasTexture() {\r\n // Create canvas context\r\n var canvas = document.createElement("canvas");\r\n var context = canvas.getContext("2d");\r\n canvas.width = 32;\r\n canvas.height = 32;\r\n\r\n // Draw radial gradient\r\n var grad = context.createRadialGradient(16, 16, 6, 16, 16, 16);\r\n grad.addColorStop(0, "rgba(255, 150, 0, 1.0");\r\n grad.addColorStop(0.5, "rgba(255, 0, 150, 1.0");\r\n grad.addColorStop(1, "rgba(0, 150, 255, 1.0)");\r\n context.fillStyle = grad;\r\n context.fillRect(0, 0, 32, 32);\r\n\r\n // Use canvas to create texture\r\n var canvasTexture = new THREE.Texture(canvas);\r\n canvasTexture.needsUpdate = true;\r\n\r\n return canvasTexture;\r\n}\r\n\r\n// Boilerplate Three.js setup\r\nvar camera, scene, renderer;\r\nrenderer = new THREE.WebGLRenderer({antialias: true});\r\nrenderer.setSize(window.innerWidth, window.innerHeight);\r\ndocument.body.appendChild(renderer.domElement);\r\nscene = new THREE.Scene();\r\nscene.background = new THREE.Color(0xe1e1e1);\r\ncamera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 100);\r\ncamera.position.set(0, 30, -30);\r\ncamera.lookAt(0, 0, 0);\r\n\r\nconst ambient = new THREE.DirectionalLight(0xddeeff, 1);\r\nambient.position.set(0, 1, 1);\r\n\r\n// Using canvas as material map texture:\r\nconst floor = new THREE.Mesh(\r\n new THREE.BoxBufferGeometry(20, 0.25, 20),\r\n new THREE.MeshBasicMaterial({map: makeCanvasTexture()})\r\n);\r\n\r\nscene.add(ambient, floor);\r\n\r\nfunction animate(t) {\r\n\t// Animate mesh\r\n floor.rotation.z += Math.sin(t * 0.001) * 0.1;\r\n\trenderer.render(scene, camera);\r\n\trequestAnimationFrame(animate);\r\n}\r\n\r\nanimate(0);
Run Code Online (Sandbox Code Playgroud)\r\n<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
Run Code Online (Sandbox Code Playgroud)\r\n请记住,WebGL 纹理大小受到限制,具体取决于每个设备的显卡功能,因此如果您尝试创建违反此限制的画布,则会出现错误。您可以访问https://webglreport.com/查看当前设备的限制并查看右侧的“最大纹理大小”读数来我的是8192px\xc2\xb2。
\n\n\n\n同样,您可以按照本文档页面中的THREE.WebGLRenderer.capabilities.maxTextureSize
说明以编程方式访问此信息编程方式访问此信息,以便您可以使用此数字来防止画布大小超出设备的限制。
这可能是通过 d3-x3d 上的此提交修复的,修复 #14 texImage2D:没有画布。与此(已关闭)问题相关,INVALID_VALUE: texImage2D: no canvas。
如果问题仍然存在,这可能与每个浏览器对其最大支持的画布尺寸/区域的限制有关。
请参阅另一篇文章中的答案,以查找每个浏览器的上述限制。
超过大多数浏览器上的最大长度/宽度/面积会导致画布无法使用。(它会忽略任何绘制命令,即使在可用区域也是如此。)
- Brandon Gano
不幸的是,从已投票的答案中没有给出 Safari 的数据,但您可以在其下面查找评论,例如:
iPhone 6 Plus 上的 iOS 9.3.1 Safari 仅限于 16777216 像素的区域(例如 4096 x 4096)
- matb33
或者像这样查看该帖子的其他答案
因此,任何 5242880 (5 x 1024 x 1024) 像素的大小变化都可以在大内存设备上运行,否则为 3145728 像素。
5 兆像素画布示例(宽 x 高):
Run Code Online (Sandbox Code Playgroud)Any total <= 5242880 -------------------- 5 x 1048576 ~= 5MP (1048576 = 1024 x 1024) 50 x 104857 ~= 5MP 500 x 10485 ~= 5MP
等等..
最大的方形画布是(“MiB”= 1024x1024 字节):
Run Code Online (Sandbox Code Playgroud)device < 256 MiB device >= 256 MiB iPhone 6 [not confirmed] ----------------- ----------------- --------------------- <= 3145728 pixels <= 5242880 pixels <= 16 x 1024 x 1024 p 1773 x 1773 2289 x 2289 4096 x 4096
- dcbarans
另一个可能的因素是客户端的显卡。