cpp, depth buffer, depth cubemap, Fragment Shader, geometry shader, light space transform, Oculus Rift, Oculus SDK for Windows, omnidirectional shadow map, OpenGL, point light, point shadows, Vertex Shader, virtual reality
The filthy old beggar put his hand into his rags and extracted a perfectly smooth ball. It had the number 8 on its surface. ‘Black magic!’ the wrinkly philosopher exclaimed.
He had lost his own marbles since my post Shadow mapping with C++
And now I fear I had pushed him over the edge by adding some point shadows to my virtual world.
The Learn OpenGL tutorial Point Shadows has the detail. I cranked open my C++ Microsoft Visual Studio application (with OpenGL and the Oculus SDK for Windows) and implemented some omnidirectional shadow mapping.
Then I put the Oculus Rift virtual reality headset on the old man in rags and he gawked, slack-jawed, at the shadow cast from the wooden container by the white light source above it:
And the light source has also cast a shadow from a cup on a shelf in the other direction:
The shadow is a bit blocky – could maybe do with some PCF (percentage-closer filtering) as explained in the tutorial.
Then the beggar strolled into a virtual room, where some pool balls fell from the ceiling and collided, casting shadows all over the place:
By recreating the cubemap in the depth buffer on every render cycle, we can obtain dynamic shadow mapping from a point light.
The old man tore the Rift headset from his bald head (save a few wisps of grey hair) and ran to the river screaming, ‘It bewitched, I tell you! What God you play upon my eyes!’
‘But it be only the addition of a geometry shader between the vertex and fragment shaders that cast such spell!’ I shouted after him, alas to no avail.
Next I pumped the light space transforms – that are used to create the depth cubemap – through the shaders used to render to the Rift headset. Now I can see what that white light source sees, when it creates the depth cubemap. Here’s the view from the light space’s right (when it’s filling the cubemap right surface):
And the left view:
The top view:
The bottom view:
The near view:
The far view:
As you can see, using a depth cubemap we can record the room from all angles and thus determine which objects are in shadow and which are not.
Note that I set the Y coordinates of “-1” on the light space transforms view matrices Up parameter to “1”, in order to see what that white light source sees.
I strolled down to the river and found the old man naked, washing his rags. He was muttering, ‘Must get the evil out of my soul!’
But I was puzzled. ‘How come you have that magic 8-ball?’ I said, pointing to the perfect sphere he was using to grind the dirt out of his clothes.
He looked at it with horror and threw it wildly across the sunlit stream, landing in a dark patch behind a small bush.
‘Ha, that’s directional shadow mapping, not point shadows!’ I laughed. But the beggar saw no humour in it. For he ran off towards town, legs kicking into the air, his clothes left in a sodden pile by the water. Like a faithful servant, I picked the rags up and followed my master.