指导大佬:傲慢なる木竜王「温馨」
一、应用场景
视频孪生场景,例如下图:

二、实现机理
三、实现代码
https://playground.babylonjs.com/#FYMCXF#2
var createScene = function () {
// This creates a basic Babylon Scene object (non-mesh)
var scene = new BABYLON.Scene(engine);
// This creates and positions a free camera (non-mesh)
var camera = new BABYLON.ArcRotateCamera("camera1", 1, 1, 5, new BABYLON.Vector3(0, 0, 0), scene);
// This targets the camera to scene origin
camera.setTarget(BABYLON.Vector3.Zero());
// This attaches the camera to the canvas
camera.attachControl(canvas, true);
// This creates a light, aiming 0,1,0 - to the sky (non-mesh)
var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
// Default intensity is 1. Let's dim the light a small amount
light.intensity = 0.7;
// // Our built-in 'sphere' shape.
// var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);
// // Move the sphere upward 1/2 its height
// sphere.position.y = 1;
// // Our built-in 'ground' shape.
// var ground = BABYLON.MeshBuilder.CreateGround("ground", { width: 25, height: 25 }, scene);
let virtualCamera = new BABYLON.FreeCamera("", new BABYLON.Vector3(2, 3, 2), scene)
virtualCamera.fov = 0.8
virtualCamera.target = new BABYLON.Vector3(0, 0, 0)
let gizmo = new BABYLON.GizmoManager(scene)
gizmo.positionGizmoEnabled = true
gizmo.rotationGizmoEnabled = true
gizmo.enableAutoPicking = false
gizmo.attachToNode(camera)
let tex = new BABYLON.VideoTexture("vidtex", "textures/babylonjs.mp4", scene);
let shaderMaterial = new BABYLON.ShaderMaterial("", scene, "custom", {
uniforms: ["worldViewProjection", "world", "projector"],
samplers: ["tex"]
})
let matrix = new BABYLON.Matrix()
shaderMaterial.onBindObservable.add(e => {
matrix.copyFrom(virtualCamera.getViewMatrix(true))
matrix = matrix.multiply(virtualCamera.getProjectionMatrix(true))
shaderMaterial.setMatrix("projector", matrix)
shaderMaterial.setTexture("tex", tex)
})
BABYLON.AppendSceneAsync(Assets.meshes.clothFolds.path, scene).then(e => {
scene.meshes.forEach(mesh => {
mesh.material = shaderMaterial
})
})
return scene;
};
BABYLON.Effect.ShadersStore['customVertexShader'] = `
precision highp float;
attribute vec3 position;
uniform mat4 worldViewProjection;
uniform mat4 world;
uniform mat4 projector;
varying vec4 uv;
void main() {
vec4 p = vec4(position, 1.);
uv = projector * world * p;
gl_Position = worldViewProjection * p;
}
`;
BABYLON.Effect.ShadersStore['customFragmentShader'] = `
precision highp float;
uniform sampler2D tex;
varying vec4 uv;
void main() {
vec3 vuv = ((uv.xyz/uv.w) + 1.)*0.5;
vec3 color = texture(tex, vuv.xy).xyz;
gl_FragColor = vec4(color, 1.);
if(vuv.x > 1. || vuv.x < 0. || vuv.y > 1. || vuv.y < 0.){
gl_FragColor.xyz = vec3(vuv);
// discard;
}
}
`;