有条件地渲染框架中的组件
conditonally render components in aframe
我有一个 aframe 场景,其中包含三个二十面体、一个复杂的粒子系统和一个融合场景中对象的光标。粒子可见时,场景运行太慢,因为光标试图融合每个粒子。我只需要它来融合三个二十面体。
所以,我正在尝试做以下两件事之一:
- 只告诉光标在二十面体上融合(如果它有助于提高性能,可能不会)
- 只有在所有二十面体都被融合/点击后才显示粒子系统。
我目前不知道如何做这两件事。这是我的场景:
<a-scene xrweb xrextras-tap-recenter xrextras-almost-there xrextras-loading xrextras-runtime-error>
<a-camera position="0 8 2">
<a-entity position="0 0 -3" geometry="primitive: ring; radiusInner: 0.25; radiusOuter: 0.3;" color="#CCCCCC"
material="shader: flat; opacity: 0.7" cursor="maxDistance: 10; fuse: true" events-cursor>
<a-animation begin="fusing" easing="ease-in" attribute="scale" fill="forwards" from="1 1 1" to="0.5 0.5 0.5"
dur="1500"></a-animation>
<a-animation begin="mouseleave" easing="ease-in" attribute="scale" fill="forwards" from="0.8 0.8 0.8" to="1 1 1"
dur="500"></a-animation>
</a-animation>
</a-entity>
</a-camera>
<!-- should only render this particle system after icosahedrons have been clicked -->
<a-entity position="0 2.25 -15"
particle-system="preset: dust; particleCount: 500; type: 2; rotationAngleSpread: .05; texture: ./images/debris.png; velocityValue: .5 0.15 .5;"
>
<a-entity rotation="0 0 0" animation="property: rotation; to: 360 0 0; loop: true; dur: 10000; easing: linear">
<a-icosahedron position="0 1 -4" radius="1.25" material="roughness: 0.8; metalness: 0.2; color: #D65C66;"
animation="property: rotation; to: 0 360 0; loop: true; dur: 10000; easing: linear" id="redOrb" events-red>
</a-icosahedron>
</a-entity>
<!--- 3 of these, hiding code for brevity-->
</a-scene>
这是处理是否已融合/点击二十面体的 javascript:
AFRAME.registerComponent('events-red', {
init: function () {
el.addEventListener('click', function(){
redClicked = true;
//when all 3 have been clicked, hide them, and show the particle system.
})
}
});
我试过了,但它不起作用(函数在正确的条件下触发,但屏幕上没有显示任何内容):
addParticleSystem = function(){
let particleSystem = document.createElement('a-entity');
particleSystem.setAttrbute('position','0 2.25 -15');
particleSystem.setAttribute('particle-system',"preset: dust; particleCount: 500; type: 2; rotationAngleSpread: .05; texture: ./images/debris.png; velocityValue: .5 0.15 .5;");
document.querySelector('a-scene').appendChild(particleSystem);
}
当你想 select 一些对象被融合(或点击)并排除其他对象时,你可以使用 raycaster 组件来实现,它与光标一起工作(或者没有它也可以工作,但用于融合, 与光标组件一起使用)。
<a-entity cursor raycaster="far: 20; interval: 1000; objects: .clickable"></a-entity>
然后在每个要包含在光线投射中的实体上,添加属性 class="clickable"
<a-box id="redBox" class="clickable" color="red"></a-box>
这是关于光线投射和游标的文档:
https://aframe.io/docs/0.9.0/components/cursor.html#fuse-based-cursor
我很惊讶粒子会参与光线投射,因为它们只是 gpu 实例。它们实际上不是场景中的 3D 实体,而是在显卡上生成并渲染为几何着色器。光线投射发生在所有几何体被发送到图形卡之前。
您是否测试过在粒子可见时打开和关闭光线投射,看看这是否会导致减速?
你的代码没有显示光标或光线投射,所以我不知道你是否在过滤实体,但你似乎没有在你的实体上使用 class 过滤器,所以看起来你没有过滤 raycaster。
我有一个 aframe 场景,其中包含三个二十面体、一个复杂的粒子系统和一个融合场景中对象的光标。粒子可见时,场景运行太慢,因为光标试图融合每个粒子。我只需要它来融合三个二十面体。
所以,我正在尝试做以下两件事之一:
- 只告诉光标在二十面体上融合(如果它有助于提高性能,可能不会)
- 只有在所有二十面体都被融合/点击后才显示粒子系统。
我目前不知道如何做这两件事。这是我的场景:
<a-scene xrweb xrextras-tap-recenter xrextras-almost-there xrextras-loading xrextras-runtime-error>
<a-camera position="0 8 2">
<a-entity position="0 0 -3" geometry="primitive: ring; radiusInner: 0.25; radiusOuter: 0.3;" color="#CCCCCC"
material="shader: flat; opacity: 0.7" cursor="maxDistance: 10; fuse: true" events-cursor>
<a-animation begin="fusing" easing="ease-in" attribute="scale" fill="forwards" from="1 1 1" to="0.5 0.5 0.5"
dur="1500"></a-animation>
<a-animation begin="mouseleave" easing="ease-in" attribute="scale" fill="forwards" from="0.8 0.8 0.8" to="1 1 1"
dur="500"></a-animation>
</a-animation>
</a-entity>
</a-camera>
<!-- should only render this particle system after icosahedrons have been clicked -->
<a-entity position="0 2.25 -15"
particle-system="preset: dust; particleCount: 500; type: 2; rotationAngleSpread: .05; texture: ./images/debris.png; velocityValue: .5 0.15 .5;"
>
<a-entity rotation="0 0 0" animation="property: rotation; to: 360 0 0; loop: true; dur: 10000; easing: linear">
<a-icosahedron position="0 1 -4" radius="1.25" material="roughness: 0.8; metalness: 0.2; color: #D65C66;"
animation="property: rotation; to: 0 360 0; loop: true; dur: 10000; easing: linear" id="redOrb" events-red>
</a-icosahedron>
</a-entity>
<!--- 3 of these, hiding code for brevity-->
</a-scene>
这是处理是否已融合/点击二十面体的 javascript:
AFRAME.registerComponent('events-red', {
init: function () {
el.addEventListener('click', function(){
redClicked = true;
//when all 3 have been clicked, hide them, and show the particle system.
})
}
});
我试过了,但它不起作用(函数在正确的条件下触发,但屏幕上没有显示任何内容):
addParticleSystem = function(){
let particleSystem = document.createElement('a-entity');
particleSystem.setAttrbute('position','0 2.25 -15');
particleSystem.setAttribute('particle-system',"preset: dust; particleCount: 500; type: 2; rotationAngleSpread: .05; texture: ./images/debris.png; velocityValue: .5 0.15 .5;");
document.querySelector('a-scene').appendChild(particleSystem);
}
当你想 select 一些对象被融合(或点击)并排除其他对象时,你可以使用 raycaster 组件来实现,它与光标一起工作(或者没有它也可以工作,但用于融合, 与光标组件一起使用)。
<a-entity cursor raycaster="far: 20; interval: 1000; objects: .clickable"></a-entity>
然后在每个要包含在光线投射中的实体上,添加属性 class="clickable"
<a-box id="redBox" class="clickable" color="red"></a-box>
这是关于光线投射和游标的文档:
https://aframe.io/docs/0.9.0/components/cursor.html#fuse-based-cursor
我很惊讶粒子会参与光线投射,因为它们只是 gpu 实例。它们实际上不是场景中的 3D 实体,而是在显卡上生成并渲染为几何着色器。光线投射发生在所有几何体被发送到图形卡之前。 您是否测试过在粒子可见时打开和关闭光线投射,看看这是否会导致减速?
你的代码没有显示光标或光线投射,所以我不知道你是否在过滤实体,但你似乎没有在你的实体上使用 class 过滤器,所以看起来你没有过滤 raycaster。