Centring a video texture

Hi, I was looking for a way to play a video on a screen without needing to add my own plane and it was a success. Of course there was the issue of the video being stretched over the mesh rather than keeping it’s own aspect ratio. I thought of a way around this and implemented the following.

https://playground.babylonjs.com/#PF1F6B#1 (I’ve simplified this to work on a plane that we know the size of but the full version works on any mesh in a glb to use that surface)

Which looked like it was working great with my test video until I used a more colourful test video. Then I noticed all the coloured lines filling the empty space.

My question is; is this the right way to go about this and if it is how do I make the untextured bit a solid colour?

Thank you for your help :sweat_smile:

cc @carolhmj on this one :slight_smile:

Hi link2twenty,

I think this depends on what exactly you’re aiming for. Is your goal to render a specific video on a specific mesh? If so, probably the “right” way to go about it is to tailor that mesh to work for that video, setting the UVs so that it only samples from the video in the places you’re interested in. If, however, your goal is to be able to play arbitrary videos on arbitrary geometry with full control of the aspect ratio, you might need a custom shader.

These lines come from “UV clamping,” which is where, when the texture is sampled at a point outside itself (with U and/or V outside the [0, 1] range) it “clamps” the sample point back to the allowed range and returns that, essentially just returning the nearest color. If you turn off this behavior in the Inspector, you can see the texture switch to “UV wrapping,” where values outside the allowed range “wrap around” and repeat through the allowed range again.

This essentially is the core problem you’ll need to address to solve the arbitrary case: if your texture doesn’t cover the entire mesh, what do you do with the “out-of-bounds” pixels? Built-in options are clamping, wrapping, and mirroring; for anything else, you’ll probably need to write your own shader.

(Twenty minutes later…)

I was going to write, “Thankfully, this won’t be too complicated a shader to write…” But then I asked myself, “Is that true?” then looked into it some more, then realized that this shader could actually be made using Babylon 5.0’s new logic nodes in NME, and then…

Babylon.js Node Material Editor (babylonjs.com)

…I kind of got sidetracked and made a version of the shader. :upside_down_face: The vertex shader here is irrelevant; the relevant part is the three nodes “TopLeft,” “Scale,” and “OutOfBoundsColor,” which allow you to rescale the input texture (which in your case would be the video texture) to put it anywhere at any aspect ratio in the final render, then fill the remainder with an “out-of-bounds color” of your choice.

Hope this helps, and best of luck!

6 Likes

Thank you that works really well. I’ve lost the sheen that was on the screen from the original material but I think that’s ok :grinning:

1 Like

Here is the example PG with video texture on NME - https://playground.babylonjs.com/#8S19ZC#29

3 Likes

Another thread with corrected Node material - How to use emissive texture in Node material

1 Like

And here is the same PG modified to make the video fill available space.

2 Likes