Lunacy’s space texture is unlike anything I’ve seen in a Source game before. I knew
it was different the moment I saw it, but couldn’t put my finger on it.
There are such things as ‘2D skyboxes’. These were used back in the days of Half Life
1, and in CS:GO to draw stuff that’s so far in the distance that it shouldn’t move
when you do. Stuff like stars, or planets. But the stars and the Earth in Lunacy DO move!
So it’s not your usual 2D skybox. When stuff moves in the distance, it’s often
the 3D skybox. So I visited that in this map by noclipping out of the world. There are
some buildings. There’s some hills and mountains. There’s Lollywood. And behind that is a
big dome of painted on sky. And behind that there is a 2D version of the stars but it
doesn’t move trust me I checked. Turns out Lunacy is using a completely new
technique, built into the dome’s texture itself!
Well I say new, but it’s just a cubemap image with added parallax. But for Source,
that’s new! To get it to work you literally have to add
a line to the texture file called ‘moondome’. From now on. Forever. In Source. Which I’m
fine with. Why should you care about all this? Well,
for a start it’s a really cool effect. Even though I know it’s just a 2D image being
distorted, it still fools me into thinking it’s 3D! I tried changing the amount of
parallax- you can see here a ‘normal’ amount of parallax, where it moves a bit when
I do. But I coated other bits of this room in different parallax amounts and you can
see that as the parallax value gets higher, it moves faster and appears closer. Until
the effect gets big enough that it looks about as close as if it was a painted-on wall, at
which point the parallax effect becomes useless. So we’ve established the limits of the effect.
But can it be used for more than just distant scenery? What if we were to add this effect
to other bits of the level as well- most notably, reflections?
Traditionally, Source has used cubemaps for reflections. If you have a reflective window
and run about looking at it, the reflection shown won’t change. It kind of gives away
that it’s a static image. Source CAN do proper reflections, like in water- but because
that’s like a whole new world being reflected, it limits this to just 1 being shown at a
time.
Every mapper will try at least once to get around this limit by adding water to more
than one surface. BUT IT WON’T WORK! Try to add more than this and it messes up. But
I still try it from time to time… just to make sure. So despite how tempting it is,
you can’t just coat every reflective surface in very small water. So what else can you
do for reflections? Proper raytracing would do it! But that would
slow everybody’s PCs down and it’s not too suitable for a competitive game (Or a
VR one COUGH). Screen-space reflections do a good job at
botching it, but they only reflect what’s shown on-screen, so they won’t show what’s
behind you- which is bad for reflections in windows and stuff, and can be more distracting
than there being no reflection at all. So unfortunately, we’ll just have to stick
to good old fashioned cubemaps- these are pre-drawn pictures of certain places in the
level. They won’t show people, and they won’t update even if the room changes what
it looks like. But this parallax effect, if done right, can
help to give the illusion that it’s a reflection. If they changed all cubemaps in a level to
these (and did them well), it would make the reflections look a lot better, without slowing
it down that much! I messed about with it a bit to see what I
could get away with. And the answer, in its current state, is… Not that much. Also,
it seems like you’re limited to 1 a level since the reflections are based around Source’s
0,0,0 coordinates- so reflections get increasingly skewed looking, the further away from this
point they are. Unless your map is perfectly positioned, and happens to be a spherical
room, it won’t ever properly match up. Here’s my first attempt. If you wonder why
the sky is black… that’s because that’s actually the floor. To get the reflection
to show what’s upwards, rather than downwards, I had to build an upside-down version of the
map and to put the cubemap there instead! Like I’ve said, this trick is pretty limited
in its current state. Now it looks a bit better. But the moment
we move from the starting position it bends and skews in a way we know just isn’t right!
Remember, it’s just a sphere showing a flat image so there’s only so much you can do
with it. At a GLANCE, as long the reflection is bumpy and blurred enough, it could look
good enough, but as a mirror finish the limitations are too obvious.
So I reduced the amount of parallax. Annoyingly you’ll have to adjust this for each and
every reflection to ensure it moves at a similar speed to the room. This looks a lot better,
but where the reflection meets the ground still splays out wayyy too much.
So I changed where the map was relative to the 0,0,0 point. There was a 50-50 chance
of choosing the right direction, so of course I got it wrong and ended up with even worse
skew. Though I’ve got to admit, it looks pretty cool when I move to the corner. In
fact… it flips around so it’s upside down again. Maybe I didn’t need to build an upside
down level. But moving the level the other way didn’t
work either. The only thing that made it look better was to leave a gap between it and what
it was meant to be reflecting. As you can see from here, it looks pretty good! It doesn’t
stop the distortion, but makes it harder to see.
I tried decorating the walls with mirrors as well. But they didn’t work. Seems like
they’ll need a separate cubemap in a different position.
…But this didn’t work either! They all seem to use the same cubemap, even when told
NOT to. And they all reflect from 0,0,0, and I wish that they didn’t ☹ I bet this stuff
could easily be fixed on Valve’s end. This was the best I could manage. You know
how I did it? Botching. Lots of botching. There’s no science here- merely nice looking
mistakes, and plenty of fun surprises along the way! Just don’t get too close to it
or it will give away its secrets. And last I did it to a large open environment,
just to show you how it mutilates 3D stuff. SO THOSE ARE MY ATTEMPTS! But there are people
who have made better use than I have of them. A video by BMCha dating wayyyy back to 2013
shows how well it can work when properly scaled and shaped to the room it’s meant to be
reflecting. It’s just a shame Source has never seen it properly implemented like this.
There is an article in the Valve wiki discussing the technique and how it could be used to
improve reflections by following the player’s position instead of remaining fixed.
And there’s this cool paper about it from 2012 showing how they could be blended together
to make for a half-decent effect. By comparison, Source 1 jumps between them depending on which
one you’re closer to. And, last but not least… there might be
hope for the future. With Source 1, because of Lunacy. But also with Source 2! Half-Life
Alyx looks to be the first BIG game for VR, with cutting-edge graphics and everything.
But how are they going to manage all this while maintaining the 90+ FPS VR requires,
whilst also having reflections that look acceptable? As I’ve already said, raytracing is too
demanding. SSR too limiting. Cubemaps… too Source 1. But parallax corrected cubemaps?
Maybe. I’ve just got my hands on VR. And in Valve’s
free showcase, The Lab, there’s a robot demonstration powered by Source 2. In the
corner, you’ll see this reflective glass surface. Peer into it and you’ll see what
APPEARS to be an accurate reflection of the room! If you didn’t know any better you
might have thought it was raytraced. But look closely and you’ll realise that the reflection
is NOT actually showing a proper room. What should be 3D walls are fake and 2D. Look,
there’s a robot painted onto the ceiling! I think Source 2- and by extension, Half-Life:
Alyx, will use parallax-corrected cubemaps for reflections. And it can do this fast enough
for VR, but well enough that, at a glance, it might actually look decent enough. I guess
come March next year, we’ll know for sure. And you know that I’ll spend a stupid amount
of time staring into the puddle here to work out how they did it.