2016年4月22日更新:没什么新鲜事,我决定对此进行检查,并发布快速代码更新。Firefox仍然可以按预期运行,IE完全不运行,Chrome 50.0.2661.87 m仍然表现与去年相同。下面的小提琴链接和代码已更新,以反映最新的工作版本(在Firefox中)。
背景: 我正在将画布+ HTML元素渲染为PNG。当然,这意味着创建一个临时SVG,该SVG将HTML托管为外部对象。
整个过程是元素的分层。我有一个背景,一层元素,画布和另一层元素。您可以在下面的代码段中看到它的外观。
我本可以通过两种方式来解决这个问题:
将包括图像在内的所有内容都写到一个SVG中,然后将其渲染到画布上。
编写两个SVG,一个用于背景和图像后面的项目,另一个用于图像前面的项目,然后绘制背面SVG,图像,然后将正面SVG绘制到目标画布。
我选择了选项1,因为它看起来简单明了。
问题: SVG绘制顺序应该遵循DOM顺序,但对于Chrome(38和Canary)而言,它的作用就像是在渲染本机对象之后又渲染了foreignObjects ,完全覆盖了本机对象。(该代码在Firefox中按预期工作,而在IE11中却失败了。)那么,谁是正确的?这是Chrome,Firefox中的错误,还是它们都无法正确处理?还是我错过了一些用户错误?
谢谢!
function putAnImageInTheCanvas() {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var svgNS = svg.namespaceURI;
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
svg.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
svg.setAttribute('height', '310');
svg.setAttribute('width', '310');
svg.setAttribute('version', '1.1');
var svgRect = document.createElementNS(svgNS, 'rect');
svgRect.setAttribute('x', '125');
svgRect.setAttribute('y', '25');
svgRect.setAttribute('height', '250');
svgRect.setAttribute('width', '50');
svgRect.setAttribute('fill', 'rgb(0,255,255)');
svg.appendChild(svgRect);
var dataSrc = 'data:image/svg+xml;base64,' + btoa(svg.outerHTML);
var img = document.createElement('img');
img.setAttribute('src', dataSrc);
var c = document.getElementById('myCanvas');
var ctx = c.getContext("2d");
img.addEventListener('load', function() …
Run Code Online (Sandbox Code Playgroud)我试图将对数深度缓冲区与正交摄影机配合使用,并遇到一些有趣的结果。我在这里构造了一个示例:http : //jsfiddle.net/TheJim01/05up96m0/
左侧的渲染器(红色结)使用标准的线性深度缓冲区(1
to 1000
)。选择“透视”或“正交”将使用选定的相机类型重新渲染场景,并且两者都可以正常工作。
右侧的渲染器(绿色结)使用对数深度缓冲区(1e-6
to 1e27
)。与左图示例一样,选择相机将使用该相机重新渲染场景。但是在这种情况下,只有Perspective相机可以正常工作。选择“正交”时,结为“统一”。看起来几乎根本没有考虑深度缓冲区。
我使用错了吗,还是这里发生了其他事情?
var WIDTH = 250,
HEIGHT = 250,
BACKGROUND = 0xcccccc;
var gl1 = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: false
}),
gl2 = new THREE.WebGLRenderer({
antialias: true,
logarithmicDepthBuffer: true
}),
scene1 = new THREE.Scene(),
scene2 = new THREE.Scene(),
s1pCam = new THREE.PerspectiveCamera(
28,
WIDTH / HEIGHT,
1,
1000
),
s1oCam = new THREE.OrthographicCamera(-1 * (WIDTH / HEIGHT),
1 * (WIDTH / HEIGHT),
1, -1,
1,
1000), …
Run Code Online (Sandbox Code Playgroud)我在VSCode 1.19.2中编辑一个独立的JavaScript文件.我没有设置项目,也没有jsconfig.json
控制它.
我在空编辑器中输入以下代码:
var scene = new THREE
Intellisense开始启动并提供自动完成列表.
当我按下"." (希望我的代码成为THREE.
),IntelliSense将此作为一个标志,它给了我正确的答案,并将我的代码更改为:
var scene = new HTMLHRElement.
完整的字符串" THREE
"甚至不在列表中,但IntelliSense似乎使用了一些怪异的正则表达式来预测用户实际尝试输入的内容 - 字母都在应用符号中,但它们都被分割了在不同的情况下.
对我来说,这是反直觉的(更不用提沮丧溢于言表,因为我键入此字符串很多),但一切到目前为止,我发现是别人问了这个功能.所以,我正在寻找一个适合我的解决方案.
有没有办法关闭"完全点上",或者可能是类似的设置强制只在选项卡上进行IntelliSense自动完成?也可以随意纠正我的术语,以免妨碍我找到正确的答案.
让我们说我正在渲染神奇女侠驾驶她的Invisible Jet.喷射器由多个网格组成,并且大部分是透明的.在透明网格重叠的地方,它变得更不透明.我希望没有重叠,透明部分仍然是阴影,但材料丢弃了其他碎片后面的透明碎片,好像神奇女侠坐在一个透明的外壳里面.
也许放置它的好方法是我想渲染透明网格,如不透明网格,但仍然允许它们是透明的.
举个例子,这里是普通女性驾驶她的大多数可见车:http://jsfiddle.net/TheJim01/e6ccfo24/
我已经完成了深度测试和编写的不同排列,并尝试了所有各种深度测试功能.我也尝试了不同的混合设置(我看到了几个建议THREE.NoBlending
,但这不是我想要的,因为我失去了透明度).如果我必须为此编写一个自定义着色器,我会走那条路,但我不知道从哪里开始.
HTML:
<script>
// INITIALIZE
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight,
FOV = 35,
NEAR = 1,
FAR = 1000;
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
document.getElementById('host').appendChild(renderer.domElement);
var stats= new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0';
document.body.appendChild(stats.domElement);
var camera = new THREE.PerspectiveCamera(FOV, WIDTH / HEIGHT, NEAR, FAR);
camera.position.z = 250;
var trackballControl = new THREE.TrackballControls(camera, renderer.domElement);
trackballControl.rotateSpeed = 5.0; // need to speed it up …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用html2canvas.js渲染一个THREE.js场景+一些重叠的HTML元素.它大部分时间都有效,但不是所有时间.
在失败的情况下,HTML元素被渲染(背景,叠加等),但没有别的.THREE.js场景就像它完全是空的一样,即使它明显有数据.我可以说它通常不适用于较大的模型,但只能在渲染的早期.它最终适用于所有情况,但较大型号需要大约30秒.好像我必须给缓冲区一些时间来稳定.
html2canvas按照您的预期处理THREE.js画布 - 它只是用于drawImage
将THREE.js画布绘制到最终由库返回的新画布上.
否则,我会尽量确保没有其他东西忙于画布,就像这个小提琴一样:http://jsfiddle.net/TheJim01/k6dto5sk/63/(以下js代码)
正如您所看到的,我正在尝试阻止渲染循环,并且当我想捕获场景时再执行一次渲染.但即使所有这些预防措施似乎都没有帮助.
有没有更好的方法从THREE.js画布中获取图像?我可以手动执行该部分,然后将THREE.js画布替换为获取的图像,只需要足够长的时间让html2canvas完成它的工作,然后将THREE.js画布交换回来.我宁愿不这样做如果用户制作大量快照(图像资源,图像资源无处不在......),那么我就不会混淆DOM.
无论如何,这是代码.欢迎任何想法或建议.谢谢!
var hostDiv, scene, renderer, camera, root, controls, light, shape, theta, aniLoopId, animating;
function snap() {
animating = false;
cancelAnimationFrame(aniLoopId);
renderer.render(scene, camera);
// html2canvas version:
/*
var element = document.getElementById('scenePlusOverlays');
// the input buttons represent my overlays
html2canvas( element, function(canvas) {
// I'd convert the returned canvas to a PNG
animating = true;
animate();
});
*/
// This is basically what html2canvas …
Run Code Online (Sandbox Code Playgroud) 我是three.js的初学者,也将它用于BIM项目,当我加载~ 25mb的gltf文件时,我几乎无法移动整个对象,stats.js监视器在最大gltf文件时显示0~2的fps:https:/ /github.com/xeolabs/xeogl/tree/master/examples/models/gltf/schependomlaan im使用三个js和vuejs
//package.json
"stats.js": "^0.17.0",
"three": "^0.109.0",
Run Code Online (Sandbox Code Playgroud)
import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
this.scene = new THREE.Scene();
this.stats = new Stats();
this.stats.showPanel( 0, 1, 2 ); // 0: fps, 1: ms, 2: mb, 3+: custom
let div = document.createElement('div')
div.appendChild(this.stats.dom)
div.style.position = 'absolute';
div.style.top = 0;
div.style.left = 0;
document.getElementsByClassName('gltfViewer')[0].appendChild( div …
Run Code Online (Sandbox Code Playgroud) three.js ×4
html5-canvas ×2
javascript ×2
bim ×1
canvas ×1
frame-rate ×1
gltf ×1
html2canvas ×1
svg ×1
vue.js ×1