[x3d-public] My experience implementing shadow maps in freewrl

GPU Group gpugroup at gmail.com
Thu Jul 7 08:46:42 PDT 2022


MY EXPERIENCE IMPLEMENTING SHADOWMAPS IN FREEWRL

-Doug Sanden

A. LIGHT SHADOWS

We already had GeneratedCubeMapTexture and TextureProject implemented, and
I started with fuzzy notion to combine code snippets from each to generate
shadow maps and project them, and I would start with PointLight which needs
a cubemap for shadow casting like GeneratedCubeMapTexture provides. After a
few days of trying to make sense of stale spaghetti code and opengl errors
regarding mixing of cubemaps and texture2D, I started over fresh with
SpotLight shadow.

Spotlight shadow - made the frustum angle match the outer cone angle, and
shadowmap rendering frustum fardistance match the light radius.

DirectionalLight shadow - made the extent match the scene if global, or the
parent extent if local

Concept: USEs - a light can be DEF/USEd multiple times, from different
world locations, and each USE instance needs a separate entry sent to
shader. That applies also to shadow maps, and so combined the per-frame USE
list to include both USE instance of light and shadowmap

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_SpotLight_DEF_USE.x3dv

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_SpotLight_DEF_USE_screenshot.png

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_Directional_DEF_USE.x3dv

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_Directional_DEF_USE_screenshot.png

For PointLight I found old code in freewrl was still initializing cubemaps
as GL_TEXTURE2D, so I paused to update cubemap code around freewrl first,
before tackling PointLight shadow as a cubemap.

A design goal: to treat cubemaps as textures, including allowing a
MultiTexture to mix Texture2D and CubeMapTextures

Step 1. get all CubeMapTexture nodes using GL_TEXTURE_CUBE_MAP

Step 2. change main CPU/GPU multitexturing to allow intermingling of
cubemaps and texture2d

a) texture transforms and coordinates

I found GeneratedTextureCoordinates only applies to IFS IndexedFaceSet
nodes in freewrl, and to reach other builtin geometry to apply something
similar, I created a new node type GeneratedTextureTransform which has the
same fields.

In freewrl on CPU side we pair (TextureTransform,TextureCoordinates) by
indexes, and send the indexes of the pairings to vertex shader, and it does
the multiplying of whatever combination of TextureTransform and
TextureCoordinates the pairing specifies. Then the frag shader uses the
pair index to get the right TexCoord for a texture or multitexture stage.
So whether using GeneratedTextureCoordinate or GeneratedTextureTransform
for cubemap didn't seem to matter, since the one entry either way was
equivalent to a pairing.

x in the process I found freewrl didn't have all the
GeneratedTextureCoordinate methods implemented, such as NOISE, and didn't
find an x3d browser that did to use as benchmark, so guessed at what noise
meant.

http://dug9.users.sourceforge.net/web3d/tests/CubeMapTexture/cubemap_ttrans_teapot_screenshot.png

http://dug9.users.sourceforge.net/web3d/tests/CubeMapTexture/cubemap_ttrans_teapot.x3dv

b) frag shader - it needs to know which sampler type and we send it a
samplr = 0 for texture2D and 1 for textureCubeMap and so it looks in a
different sampler array with the index given:

if(samplr == 1)

  color = texture(textureUnitCube[tindex],TexCoord[cindex]);

else

  color = texture2D(texturUnit[tindex],TexCoord[cindex].xy);

Getting the CPU-side pairing code to generate good defaults when mixing 2D
and cube and giving no Texture Transform or GeneratedTextureTransform list
was fiddly to express the notions needed, but worked:

http://dug9.users.sourceforge.net/web3d/tests/CubeMapTexture/ImageCubeMap_multitex_mixed_2D_cube.mp4

http://dug9.users.sourceforge.net/web3d/tests/CubeMapTexture/ImageCubeMap_multitex_mixed_%202D_cube.x3dv

- the beachball texture on the left is 2D and defaults to 2D diffuse
texture mapping, the texture on the right is cubemap, and defaults to
reflection texture, so they should move differently relative to each other
as the sphere is examined.



Having warmed up with cubemap improvements, another attempt at PointLight
with cubemap shadowmap got results

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_PointlLight_DEF_USE.x3dv

http://dug9.users.sourceforge.net/web3d/tests/Lights/shadow_PointLight_DEF_USE_screenshot.png

B. TEXTURE PROJECTOR SHADOWS

Existential nausea - I thought I knew lights and textures were different,
but texture projectors blur the lines. What is a projector, something like
a mapping between fragment space and texture space, or excuse me with color
and intensity, and shadows, it could be called a MaterialProjector or
LightProjector. And mappings are like our (TexCoords, TextureTransform)
pairings, which also map between fragment and texture space.

After getting past the nausea, it seemed like the analogy between Lights
and Projectors was and using Lights as an analogy, much of the
infrastructure I could copy from Lights including depth texture sampling.

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Spot.x3dv

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_spot.png

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Parallel.x3dv

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Parallel.png



Using Lights as an analogy, there seemed to be one node missing from
TextureProjectors: ProjectorPoint.

So created that node type TextureProjectorPoint

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Point.x3dv

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Point.png

And a fun test scene with disco ball rotating ProjectorPoint:

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Point_disco.x3dv

http://dug9.users.sourceforge.net/web3d/tests/PTM/PTM_shadow_Point_disco.mp4



SUMMARY

- 3 months of refactoring / fixing and generalizing old spaghetti code

- NOT DONE: ComposedBackground, EnvironmentLight



/MY EXPERIENCE
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://web3d.org/pipermail/x3d-public_web3d.org/attachments/20220707/3dfa2643/attachment-0001.html>


More information about the x3d-public mailing list