Describe the bug?
Non-16:9 video (e.g. a 1920×800 / 2.40:1 clip) is stretched vertically to fill the fixed 16:9 media-player screen. There's no letterboxing and no aspect correction, so a cinemascope source looks squashed. This is a rendering/geometry behaviour with a code-level root cause (see Additional Context), not a runtime error, so there's no crash or log output to attach.
Steps to Reproduce
- Open the
MediaPlayerStreaming (or MediaPlayerMultiChannelStreaming) prefab.
- Load any source whose aspect isn't 16:9 — e.g. a 1920×800 clip.
- Watch the 3D screen: the image fills the whole quad and is vertically stretched.
- Optional: select the screen's
BasisVideoMaterialOutput in the Inspector at runtime and switch AspectMode to FitInside — it still doesn't letterbox.
The expected behavior
The video keeps its correct proportions on the screen: either letterboxed with black bars on the fixed 16:9 quad, or the screen resized to the source aspect. A 16:9 source should look exactly as it does today (full screen, no bars).
Screenshots
A screenshot of the stretched 1920×800 output can be attached here if useful.
Build Info
Not environment-specific — reproducible on developer and any current build. Diagnosed against developer HEAD; the relevant code is in com.basis.mediaplayer (paths cited below).
Log Files
None. The stretch is a rendering/geometry behaviour and produces no errors or warnings on the Video log tag.
Additional Context
Root cause. The screen is a fixed 16:9 quad (VideoScreen16x9, ~14.464 × 8.136 = 1.778:1, generated by Editor/BasisVideoScreenMeshGenerator.cs), and the material output maps the video onto it with no shape correction:
BasisVideoMaterialOutput has an AspectMode, but it defaults to Original (no correction) and applies its result purely as a texture scale/offset (material.SetTextureScale/SetTextureOffset, i.e. _BaseMap_ST, at Runtime/Rendering/BasisVideoMaterialOutput.cs:259-260).
- The material is stock URP/Unlit (
Materials/MediaPlayer.mat), and the output texture is created with TextureWrapMode.Clamp (Runtime/Native/BasisNativeVideoSource.cs:399,423). A texture scale/offset can only crop or zoom within the source; it can't introduce black bars, and clamp smears anything sampled outside [0,1] rather than rendering it black.
- The
FitInside branch in BasisVideoOutputMath.GetAspectUv (:66-80) also returns a scale ≤ 1, so even when it's selected it crops toward the centre rather than fitting-with-bars. Switching AspectMode to FitInside at runtime therefore doesn't letterbox (confirmed in-editor).
So there's no code path today that makes a non-16:9 source display at correct proportions on the 3D screen.
Suggested fix. Two workable approaches, depending on whether the screen should stay a fixed size.
- A. Letterbox with black bars (screen stays fixed). Invert the
FitInside math so the sampled region scales > 1 (leaving room outside [0,1] for the bars), and make out-of-range render black — either a small custom unlit video shader with a border check (any(uv < 0 || uv > 1) outputs black), or TextureWrapMode.Border with a black border colour. A custom shader is the more reliable route across the D3D external-texture and Vulkan RenderTexture paths, and it would also give somewhere to implement the BASIS_PROJ_* (equirect / VR180 / fisheye) keywords, which are currently set in C# but consumed by no shader.
- B. Fit the quad to the source aspect (screen resizes). Drive the screen mesh's
localScale from the decoded width/height (already surfaced as BasisMediaPlayer.VideoSize) so the quad takes the video's shape. No shader or wrap-mode change, works on every backend, no smearing — the trade-off is that the screen's in-world footprint changes with content.
I'd lean towards A with a small dedicated video shader (a fixed screen is nicer in VR, and it revives the projection keywords), but B is the lighter change if a resizing screen is acceptable. Happy to put up a PR for whichever you'd prefer.
For context, #948 fixes a separate, narrower Windows-only issue (a thin top strip from the coded macroblock pad); this one is the aspect/stretch behaviour and is unrelated.
Describe the bug?
Non-16:9 video (e.g. a 1920×800 / 2.40:1 clip) is stretched vertically to fill the fixed 16:9 media-player screen. There's no letterboxing and no aspect correction, so a cinemascope source looks squashed. This is a rendering/geometry behaviour with a code-level root cause (see Additional Context), not a runtime error, so there's no crash or log output to attach.
Steps to Reproduce
MediaPlayerStreaming(orMediaPlayerMultiChannelStreaming) prefab.BasisVideoMaterialOutputin the Inspector at runtime and switchAspectModetoFitInside— it still doesn't letterbox.The expected behavior
The video keeps its correct proportions on the screen: either letterboxed with black bars on the fixed 16:9 quad, or the screen resized to the source aspect. A 16:9 source should look exactly as it does today (full screen, no bars).
Screenshots
A screenshot of the stretched 1920×800 output can be attached here if useful.
Build Info
Not environment-specific — reproducible on
developerand any current build. Diagnosed againstdeveloperHEAD; the relevant code is incom.basis.mediaplayer(paths cited below).Log Files
None. The stretch is a rendering/geometry behaviour and produces no errors or warnings on the
Videolog tag.Additional Context
Root cause. The screen is a fixed 16:9 quad (
VideoScreen16x9, ~14.464 × 8.136 = 1.778:1, generated byEditor/BasisVideoScreenMeshGenerator.cs), and the material output maps the video onto it with no shape correction:BasisVideoMaterialOutputhas anAspectMode, but it defaults toOriginal(no correction) and applies its result purely as a texture scale/offset (material.SetTextureScale/SetTextureOffset, i.e._BaseMap_ST, atRuntime/Rendering/BasisVideoMaterialOutput.cs:259-260).Materials/MediaPlayer.mat), and the output texture is created withTextureWrapMode.Clamp(Runtime/Native/BasisNativeVideoSource.cs:399,423). A texture scale/offset can only crop or zoom within the source; it can't introduce black bars, and clamp smears anything sampled outside [0,1] rather than rendering it black.FitInsidebranch inBasisVideoOutputMath.GetAspectUv(:66-80) also returns a scale ≤ 1, so even when it's selected it crops toward the centre rather than fitting-with-bars. SwitchingAspectModetoFitInsideat runtime therefore doesn't letterbox (confirmed in-editor).So there's no code path today that makes a non-16:9 source display at correct proportions on the 3D screen.
Suggested fix. Two workable approaches, depending on whether the screen should stay a fixed size.
FitInsidemath so the sampled region scales > 1 (leaving room outside [0,1] for the bars), and make out-of-range render black — either a small custom unlit video shader with a border check (any(uv < 0 || uv > 1)outputs black), orTextureWrapMode.Borderwith a black border colour. A custom shader is the more reliable route across the D3D external-texture and Vulkan RenderTexture paths, and it would also give somewhere to implement theBASIS_PROJ_*(equirect / VR180 / fisheye) keywords, which are currently set in C# but consumed by no shader.localScalefrom the decoded width/height (already surfaced asBasisMediaPlayer.VideoSize) so the quad takes the video's shape. No shader or wrap-mode change, works on every backend, no smearing — the trade-off is that the screen's in-world footprint changes with content.I'd lean towards A with a small dedicated video shader (a fixed screen is nicer in VR, and it revives the projection keywords), but B is the lighter change if a resizing screen is acceptable. Happy to put up a PR for whichever you'd prefer.
For context, #948 fixes a separate, narrower Windows-only issue (a thin top strip from the coded macroblock pad); this one is the aspect/stretch behaviour and is unrelated.