Pointers on modern OpenGL shadow cubemapping?

女生的网名这么多〃 提交于 2019-12-01 02:22:05

I hope to provide an answer to some of your questions, but first some definitions are required:

What is a cubemap?

It is a map from a direction vector to a pair of [face, 2d coordinates on that face], obtained by projecting the direction vector on an hypothetical cube.

What is an OpenGL cubemap texture?

It is a set of six "images".

What is a GLSL cubemap sampler?

It is a sampler primitive from which cubemap sampling can be done. This mean that it is sampled using a direction vector instead of the usual texture coordinates. The hardware then project the direction vector on an hypothetical cube and use the resulting [face, 2d texture coordinate] pair to sample the right "image" at the right 2d position.

What is a GLSL shadow sampler?

It is a sampler primitive that is bounded to a texture containing NDC-space depth values and, when sampled using the shadow-specific sampling functions, return a "comparison" between a NDC-space depth (in the same space of the shadow map, obviously) and the NDC-space depth stored inside the bounded texture. The depth to compare against is specified as an additional element in the texture coordinates when calling the sampling function. Note that shadow samplers are provided for ease of use and speed, but it is always possible to do the comparison "manually" in the shader.


Now, for your questions:

OpenGL simply renders [...] to the cubemap, right?

No, OpenGL render to a set of targets in the currently bounded framebuffer.

In the case of cubemaps, the usual way to render in them is:

  • to create them and attach each of their six "images" to the same framebuffer (at different attachment points, obviously)
  • to enable only one of the target at a time (so, you render in each cubemap face individually)
  • to render what you want in the cubemap face (possibly using face-specific "view" and "projection" matrices)

Point-light shadow maps

In addition to everything said about cubemaps, there are a number of problems in using them to implement point-light shadow mapping and so the hardware depth comparison is rarely used.

Instead, what is common pratice is the following:

  • instead of writing NDC-space depth, write radial distance from the point light
  • when querying the shadow map (see sample code at bottom):
    • do not use hardware depth comparisons (use samplerCube instead of samplerCubeShadow)
    • transform the point to be tested in the "cube space" (that do not include projection at all)
    • use the "cube-space" vector as the lookup direction to sample the cubemap
    • compare the radial distance sampled from the cubemap with the radial distance of the tested point

Sample code

// sample radial distance from the cubemap
float radial_dist = texture(my_cubemap, cube_space_vector).x;

// compare against test point radial distance
bool shadowed = length(cube_space_vector) > radial_dist;
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!