# 拼图和代码片段
# JS:渲染回调
参数是回调函数
app.renderCallbacks.push(function(){
//拼图中的函数
v3d.puzzles.procedures.myfunc();
});
2
3
4
参考:https://www.soft8soft.com/docs/api/en/extras/App.html#renderCallbacks (opens new window)
# JS:编译回调
用于添加后期处理效果或雾效,改善性能,v3d 3.2新增。
app.compileCallbacks.push(function(){
app.scene.fog = new v3d.FogExp2(0xefd1b5, 0.0025);
});
2
3
参考:https://www.soft8soft.com/docs/api/en/extras/App.html#compileCallbacks (opens new window)
# JS:雾效
第一个参数支持CSS颜色输入方式,第二个参数是强度
v3d 3.4版新增addfog拼图
app.scene.fog = new v3d.FogExp2(0xefd1b5, 0.0025);
app.scene.fog = new v3d.FogExp2('blue’, 0.02);
2
参考:https://www.soft8soft.com/docs/api/en/scenes/FogExp2.html (opens new window)
# JS:禁用渲染和降低帧率
用于提高性能
app.disableRendering();
app.enableRendering();
app.setFrameRateDivider(2); // enables maximum 30 FPS instead of 60
2
3
参考:https://www.soft8soft.com/docs/api/en/extras/App.html#setFrameRateDivider (opens new window)
# JS:控制阴影开关
app.renderer.shadowMap.enabled = false;
# JS:判断物体是否被遮挡
v3d 3.4后可以通过raycast拼图实现。
var obj = app.scene.getObjectByName(obj);
var raycaster = new v3d.Raycaster(app.camera.position, obj.position.sub(app.camera.position).normalize());
var intersects = raycaster.intersectObjects(app.scene.children);
console.log(intersects);
if (intersects.length > 0) {
return true;
} else {
return false;
};
2
3
4
5
6
7
8
9
参考:https://www.soft8soft.com/docs/api/en/core/Raycaster.html (opens new window)
# JS:获取鼠标点击位置
注意返回的pos坐标(左手坐标)与拼图坐标(右手坐标)不一致,需要转换。
这段代码不计算mesh与相机之间是否存在遮挡物体。
v3d 3.4后可以通过raycast拼图实现。
var raycaster = new v3d.Raycaster();
var mesh = app.scene.getObjectByName("nav_mesh");
var mouse = new v3d.Vector2();
function onClick(event) {
// 计算鼠标在屏幕空间的位置
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
// 更新鼠标和相机的射线
raycaster.setFromCamera(mouse, app.camera);
// 计算与射线相交的物体
var intersects = raycaster.intersectObject(mesh);
if (intersects.length > 0) {
var pos = intersects[0].point;
// console.log(pos);
}
}
function onTouch(event) {
var touch = event.touches[0]; //获取第一个触点
mouse.x = (touch.pageX / window.innerWidth) * 2 - 1; //页面触点X坐标
mouse.y = -(touch.pageY / window.innerHeight) * 2 + 1; //页面触点Y坐标
//记录触点初始位置
raycaster.setFromCamera(mouse, app.camera);
// 计算与射线相交的物体
var intersects = raycaster.intersectObject(mesh);
if (intersects.length > 0) {
var pos = intersects[0].point;
// console.log(pos);
}
}
window.addEventListener('click', onClick, {
passive: true
});
window.addEventListener('touchstart', onTouch, {
passive: true
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# JS:从外部调用v3d应用的变量、函数
自定义的代码一般放在v3d自动生成的app.js里面的runcode()函数内部,这样当v3d应用加载完成,会直接执行该函数下的代码。但是,如果想在单独的js文件中编写代码,还要访问v3d内部的变量、函数,这种情况就有些复杂了。
在main.js中:
// 对verge3d的app.js做事件监听
v3d._customEvents = new v3d.EventDispatcher();
v3d._customEvents.addEventListener('onload', function(event) {
// 还可以调用拼图定义的函数
v3d.puzzles.procedures.myProcedures();
// 获取场景中的第一个物体的名称
var obj = v3d.apps[0].scene.children[0].name;
});
2
3
4
5
6
7
8
在app.js中:
function runCode(app) {
// 运行到此处时v3d应用已加载完成,发送加载事件
if (v3d._customEvents) {
v3d._customEvents.dispatchEvent({ type: 'onload' });
}
}
2
3
4
5
6
参考:https://www.soft8soft.com/topic/calling-procedures-from-js/ (opens new window)
# JS:从父级访问iframe中的v3d变量
v3d_variable是iframe内的v3d应用暴露出来的全局变量,要从父级获取它,代码如下:
setTimeout(function(){
window.frames['child'].contentWindow.v3d_variable
},2000)
2
3
这里需要用延迟加载的方法,等iframe下的v3d应用加载完成后,再去访问。
# JS:线框材质透明度
lineObj.material.transparent = true; //开启材质透明
lineObj.material.opacity = 0.5; //透明度
lineObj.material.lineWidth = 2; //线框宽度
2
3
参考:https://www.soft8soft.com/docs/api/en/extras/objects/MeshLineMaterial.html (opens new window)
# JS:改变轮廓颜色
v3d 3.2可通过材质编译回调函数添加后期处理效果
v3d.apps[0].postprocessing.outlinePass.visibleEdgeColor = new v3d.Vector4(0,0,1,1) // blue
# JS:改变动画播放速度
使用 play animation 拼图控制动画速度时,无法在动画播放过程中改变速度,可以自定义一个函数:
function prepareExternalInterface(app) {
app.ExternalInterface.setAnimationSpeed = function(animName, speed) {
var action = v3d.SceneUtils.getAnimationActionByName(app, animName);
if (action) {
action.timeScale = speed;
}
}
}
2
3
4
5
6
7
8
# JS: HTML虚拟摇杆
使用nipplejs.js (opens new window)实现虚拟摇杆
注意 dynamic模式下需要为zone指定宽高100%
Verge3D runcode()下面加入以下代码:
// joystick
var joystick = nipplejs.create({
zone: document.getElementById('left'),
mode: 'static', //mode: 'semi','dynamic'
position: {
right: '100px',
bottom: '100px'
},
color: 'skyBlue',
size: 100
});
var dir;
joystick.on("move", function (evt, data) {
dir = data.direction.angle;
}).on("end", function(evt, data){
dir = "none";
})
//every frame
app.renderCallbacks.push(function() {
v3d.puzzles.procedures.playerMove(dir);
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# JS:重力感应功能
// 开启和关闭陀螺仪重力感应
var flag;
var gyro_button = document.getElementById('gyro_button');
var orientationControls = new v3d.DeviceOrientationControls( app.camera );
gyro_button.addEventListener('click', function(){
flag = !flag;
if (flag){
app.controls = orientationControls;
}else{
app.enableControls();
}
}, false);
2
3
4
5
6
7
8
9
10
11
12
13
# JS:清除V3D缓存
默认V3D是开启缓存的,想要清除,可以使用如下代码:
v3d.Cache.clear()
# JS:选择被遮挡的物体
如果想忽略当前物体而选择其背后的物体,可以使用如下代码:
var myObj = app.scene.getObjectByName('myObj');
myObj.raycast = function() {};
2
使该物体重新可选择,使用代码:
var myObj = app.scene.getObjectByName('myObj');
delete myObj.raycast;
2
# 拼图:适配屏幕
# 拼图:为一组物体实现可拖动
# 拼图:高清屏显示设置
# 拼图:XR控制器
以下方法已由get controller prop拼图实现。
webXR控制器名称为:XR_CONTROLLER webXR注视点光标名称为:XR_CONTROLLER_RETICLE 设置新的VR注视点光标时需要将光标的模型父子约束到XR控制器上,并且Y轴位置约束到XR注视点上。
# 拼图:使用文本代替组选择器
名为Collection 1的组在代码中表示为:
['GROUP','Collection 1']
因此,在拼图中可以通过GROUP+组名构成的列表来代替组选择器——
# 拼图:HTML事件属性
以下案例可通过get event property拼图获取事件目标的属性值(JS中的事件代理,根据冒泡机制实现)。 html
<ul>
<li id="btn1" value="1">按钮</li>
<li id="btn2" value="2">按钮</li>
<li id="btn3" value="3">按钮</li>
<li id="btn4" value="4">按钮</li>
</ul>
2
3
4
5
6
# 拼图:增加/移除类.class
利用文本类的replace with拼图移除类
利用create text拼图增加类
← GLSL 详解(高级篇) 拾色器 →