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.
