Hi
@truckermudgeon.
Yes, I added a second step in the processing pipeline, which uses FFmpeg to transform the projection. Unfortunately the game engine doesn't seem to support different projection types. After recording the footage in OBS and editing it in DaVinci Resolve (export it with a high bitrate or in a lossless codec, like FFV1, since the output will now be an intermediate file and we don't want to loose too much information through re-encoding), I used the "v360" filter in FFmpeg to transform each "view" (monitor) in the video from rectilinear to equirectangular projection, using only one command:
Code: Select all
ffmpeg -i input.mp4 -filter_complex "[0:v]split=3[a][b][c];[a]crop=2560:1440:0:0,drawbox=x=0:y=0:w=1:h=1:color=black:t=fill,v360=flat:equirect:ih_fov=120:iv_fov=88.5:yaw=120:pitch=0:roll=0:w=7680:h=3840,crop=2560:3840:0:0[ll];[b]crop=2560:1440:2560:0,drawbox=x=0:y=0:w=1:h=1:color=black:t=fill,v360=flat:equirect:ih_fov=120:iv_fov=88.5:yaw=0:pitch=0:roll=0:w=7680:h=3840,crop=2560:3840:2560:0[ce];[c]crop=2560:1440:5120:0,drawbox=x=0:y=0:w=1:h=1:color=black:t=fill,v360=flat:equirect:ih_fov=120:iv_fov=88.5:yaw=-120:pitch=0:roll=0:w=7680:h=3840,crop=2560:3840:5120:0[rl];[ll][ce][rl]hstack=inputs=3[out]" -map "[out]" -map 0:a? -c:v hevc_nvenc -rc vbr -cq 14 -preset p6 output_360.mp4
So I basically recorded in 7680x1440 with 3 monitors (each 2560x1440), which have been combined with NVIDIA Surround to one virtual monitor. 120° degrees FOV for horizontal resolution per view (360° in total) and 90° vertically in multimon setup in ETS 2. FFmpeg is instructed to basically go through each frame of the input video, split it up into 3 "views" (each 2560x1440 in my case) and morph the projection for each view. The result is placed back at the same positions and written to the final output file. I then use Google's tool to inject the meta data and upload the video to YouTube, which automatically detects it as 360° video.
Some more explanations regarding the above command:
- The "v360" filter in FFmpeg unfortunatelly seems to work only on the CPU. So the projection morphing is done on the CPU, which is relatively slow (for this video, it took more than 5 hours to render 42 mins of video with 7680x3840 @ 60 fps as final output). In the command above I am telling FFmpeg to use my GPU to do the encoding (with H.265 / HEVC codec) with "-c:v hevc_nvenc -rc vbr -cq 14 -preset p6". The "-preset" parameter just specifies the compression efficiency, but doesn't change the bitrate. "-cq" specifies the bitrate. Usually 18 to 24 is fine. I went with 14 (the lower the better quality, but takes longer to encode) to preserve more information, since YouTube is always re-encoding everything again. If you prefer doing everything on the CPU, replace "-c:v hevc_nvenc -rc vbr -cq 14 -preset p6" with "-c:v libx265 -crf 22 -preset fast", which will use the software encoder on the CPU instead.
- The v360 filter morphs the view into an oval-like shape, which means that there will be a background with "new" pixels now. Unfortunatelly, the filter doesn't seem to have an option to set the background color for these pixels (or I didn't found it), which results in a weirdly flickering background. Here is a frame demonstrating it: [ external image ]. After testing around for a while, I realized that the background colors seems to be taken from the top left most pixel of each view (in the center view you can see that the background color is light blue, which comes from the sky color in the game). The solution is simple: Set the top left most pixel for each view always to black (a single pixel won't really be visible later). Luckely, we can tell FFmpeg to do that in the same command by using "drawbox" with a size of 1x1 and black as background color. Basically something like this: [ external image ] (the pixel here is obviously bigger for demonstration purposes
). This tricks the filter to take this one pixel and use it as the background color. The result: [ external image ]
If you want to test it with only a small portion of your video, you can use the parameters "-ss" (begin) and "-t" (duration) in the command. For example: "-ss 00:00:30 -t 00:00:15" begins at 30 seconds and processes 15 seconds from there.
Note: If you add overlays, like intro / outro / text, do it before morphing the projection in FFmpeg. After FFmpeg changed the projection, your overlays will look distorted, like this:
[ external image ]. This is correct, so do not try to manually fix it. YouTube later displays the video as a sphere (equirectangular projection), so all distortions basically cancel out again and straight lines appear straight again:
[ external image ].