One thing that's sort of annoyed me about ZDoom's otherwise really-nifty skybox implementation (where you make 3D level geometry that appears everywhere there's sky visible in the map,
not to be confused with OpenGL skyboxes) is that they're completely and utterly static; no matter how you're moving in a map, they appear to be infinitely far away and do not move along with the non-sky level geometry in any convincing fashion. I'd like to change that to something a bit more like the Source Engine's implementation (or
SRB2's, if you'd rather a more
Doom-centric analogy), where there's a bit of parallax to work with.
I've put a bit of thought as to how such a thing could be accomplished without breaking older maps that use the skybox functionality as it currently is. What I'm thinking is there'd be a related Actor to SkyboxViewpoint - SkyboxAnchor, let's call it. It works like so:
- A map maker creates their skybox outside the main level geometry, and places a SkyboxViewpoint in there, as currently.
- They then place a SkyboxAnchor inside the actual level's geometry where they'd want that skybox's parallax to be centered around.
- Next, they tie the newly-placed SkyboxAnchor to its corresponding SkyboxViewpoint, presumably either with a matching TID or a Thing argument that'd serve the same purpose (I'm not sure which would be considered preferable, code-wise).
- After that, they'd put in a Thing argument that specifies the parallax scale - presumably value n in this parameter would translate to a 1/n scale, if only because trying to define the proper decimal values in GZDB tends to truncate it to three decimal places, even though AFAIK UDMF itself supports much larger than that.
After that setup, when rendering the skybox in-game, there would be an offset applied away from the position defined by the relevant SkyboxViewpoint, calculated using the offset between the client's current camera position (whether that's the player's position, the chasecam's position, a security camera that's in current use or whatever's relevant at that particular tic) and the position defined by the corresponding SkyboxAnchor, and scaled according to the SkyboxAnchor's parameter.
As for how this would be backwards compatible, it's pretty simple: if the SkyboxAnchor Thing isn't present, as it wouldn't be for any map using a SkyboxViewpoint prior to this feature, then the current implementation is used as-is, verbatim, with no fuss. The player moves in the level, the skybox doesn't move accordingly. Along that line, the default behavior would presumably be the fallback for these scenarios as well (although appropriate warnings would presumably be raised):
- The SkyboxAnchor's scale parameter is set to 0 or undefined.
- More than one SkyboxAnchor is defined for a single SkyboxViewpoint.
To give an example how this could be used in an actual map: you could make a city stage seem larger than it actually is, by placing geometry for buildings into the skybox that'd move along with the player as if they were actually put into the map, even though they're actually in the skybox, out of reach. As it is, if a mapper attempted this, the buildings would be the same distance away from the player no matter where in the map they were looking at the building from. Another example: adding rolling hills outside the boundaries of the map to give the impression of the area around the map rolling off into the horizon (as opposed to just using Line_Horizon for a perfectly flat plane).