Hey there dearest reader,
is there a way to show the same picture/ video on two or even more flat objects (i.e. Triangle, rectangle, circle, ect.)? Sounds easy enough, but I mean with a splitscreen to single screen effect like this for example. The simplest way is probably splitting the content, aye? So maybe a javascript video editor? Found nothing really satisfying so far, but maybe I am just searching with an unclear imagination of what I want. Therefor any suggestions are welcome.
Thanks & Greetings Orys
Hey there dearest OP.
If you can't fake it (having a big plane with the image + overlay a cross), then I'd try with using shaders.
A custom shader which will use the "top" or "bottom" side of the image could look like this:
<script src="https://aframe.io/releases/1.1.0/aframe.min.js"></script>
<script>
// register a custom component
AFRAME.registerComponent("foo", {
// we wanna pass a value "top" or "bottom"
schema: {
side: {
value: "top"
}
},
init: function() {
// vertex shader. we only want it to pass the UV to the frag shader
const vertexShader = `
varying vec2 vUv;
void main() {
vUv = uv;
gl_Position = projectionMatrix *
modelViewMatrix *
vec4(position,1.0);
}
`;
const fragmentShader = `
uniform bool top;
uniform sampler2D map;
varying vec2 vUv;
void main() {
// the top one is 1 - .5
// the bottom one .5 - 0
vec2 coords = vUv.xy;
coords.y = coords.y / 2.0; // stretch half of it.
if (top) {
coords.y += 0.5; // if top - apply offset
}
vec4 mapTexel = texture2D( map, coords );
gl_FragColor = mapTexel;
}
`
// wait until the entity is loaded
this.el.addEventListener("loaded", e => {
// grab the mesh
const mesh = this.el.getObject3D("mesh")
// load the texture
const texture = new THREE.TextureLoader().load('https://i.imgur.com/wjobVTN.jpeg');
// create a new shadermaterial with the defined shaders
const newMaterial = new THREE.ShaderMaterial({
uniforms: {
top: {
type: "b",
value: this.data.side === "top" ? true : false
},
map: {
type: "t",
value: texture
}
},
vertexShader: vertexShader,
fragmentShader: fragmentShader,
transparent: true
});
// apply the new material - get rid of the old one
const oldMaterial = mesh.material;
mesh.material = newMaterial
mesh.material.needsUpdate = true;
oldMaterial.dispose();
})
}
})
</script>
<a-scene>
<a-plane width="2" position="0 2.25 -3" foo="side: top"></a-plane>
<a-plane width="2" position="0 1 -3" foo="side: bottom"></a-plane>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
</a-scene>