We paint a looping 360° video on the inside of a sphere with VideoMaterial(avPlayer:): an AVQueuePlayer plus AVPlayerLooper, a ModelEntity with an inward-facing equirectangular mesh, inside a .mixed ImmersiveSpace. No shaders, no VideoPlayerComponent. We could not find an official Apple sample that puts a VideoMaterial on a 360° sphere; this is the plain pattern from the VideoMaterial(avPlayer:) reference and the one used in threads like 734081. On Apple Vision Pro hardware the video renders correctly. In the visionOS Simulator (27.0, 26.5 and earlier 26.x, Xcode 27.0) the whole frame has a strong purple/magenta cast. Audio and timing are fine.
The video (which we cannot share, so here is its metadata, image sample of issue on simulator provided below): MP4, HEVC Main, 8-bit 4:2:0, 3840x1920, tagged BT.2020 primaries, HLG transfer (ARIB STD-B67), BT.2020 non-constant matrix, both in the colr atom and in the SPS VUI. ffprobe -show_format -show_streams (trimmed):
[STREAM]
index=0
codec_name=hevc
profile=Main
codec_type=video
codec_tag_string=hvc1
width=3840
height=1920
pix_fmt=yuv420p
color_range=tv
color_space=bt2020nc
color_transfer=arib-std-b67
color_primaries=bt2020
r_frame_rate=30000/1001
avg_frame_rate=679200/22663
duration=37.771667
bit_rate=25030607
[SIDE_DATA]
side_data_type=Stereo 3D
type=2D
horizontal_field_of_view=360000/1000
[/SIDE_DATA]
[/STREAM]
[STREAM]
index=1
codec_name=aac
profile=LC
codec_type=audio
codec_tag_string=mp4a
sample_fmt=fltp
sample_rate=48000
channels=2
channel_layout=stereo
duration=37.758333
bit_rate=128176
[/STREAM]
[FORMAT]
nb_streams=2
format_name=mov,mp4,m4a,3gp,3g2,mj2
duration=37.778333
bit_rate=25160348
TAG:major_brand=mp42
TAG:minor_version=1
TAG:compatible_brands=isommp41mp42
[/FORMAT]
AVFoundation's view of the track, from CMFormatDescriptionGetExtension on the loaded video track:
primaries=ITU_R_2020
transfer=ITU_R_2100_HLG
matrix=ITU_R_2020
bitsPerComponent=8
The playback code, reduced to the essentials:
let item = AVPlayerItem(url: fileURL)
let looper = AVPlayerLooper(player: player, templateItem: item) // retained
player.actionAtItemEnd = .advance
let material = VideoMaterial(avPlayer: player)
let sphere = ModelEntity(
mesh: try equirectSphere(radius: 12), // lat/long grid, normals inward,
materials: [material] // UVs (u, 1 - v), inward winding
)
sphere.position = [0, 1.5, 0]
rootEntity.addChild(sphere) // rootEntity was added in RealityView { }
player.play()
What we have ruled out in a minimal sample project:
Apple's own 360° HLS example (360 Lighthouse, HEVC Main 10, 10-bit, BT.709 SDR) plays with correct colours in the same sphere, same code, same simulator session.
Rewriting our file's colr atom to BT.709 (three bytes, no re-encode) is honoured by AVFoundation (the track's CMFormatDescription then reports ITU_R_709_2 for primaries, transfer and matrix) but the tint stays.
So the remaining differences between the failing file and Apple's working stream are 8-bit Main vs 10-bit Main 10, HLG/BT.2020 in the bitstream VUI vs BT.709, and local MP4 vs HLS. The minimal sample project (without the video) is available on request.
Is this a known limitation of the simulator's VideoMaterial path with 8-bit HLG content, and is there a recommended way to get device-equivalent colour in the simulator? Feedback filed as FB24997147.
Here is a sample of the result on the simulator of a cement column, painted white, but rendered purple on simulator:
0
0
18