当前位置:网站首页>◰ GL shadow map core steps

◰ GL shadow map core steps

2022-04-23 16:41:00 itzyjr

The first round : Render the scene from the light angle
1. Create a custom framebuffer

glGenFramebuffers(1, &shadowBuffer);

2. Create and bind shadow textures , Set shadow map and parameters

glGenTextures(1, &shadowTex);
glBindTexture(GL_TEXTURE_2D, shadowTex);
// specify a two-dimensional texture image
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32,
		     screenW, screenH, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
// may reduce shadow border artifacts
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

3. Bind frame buffer

glBindFramebuffer(GL_FRAMEBUFFER, shadowBuffer);

4. Attach the depth information to the shadow texture attachment of the frame buffer
If the image of the texture object is attached to the frame buffer ,OpenGL Will perform “ Render to texture ”, That is, the depth information is in the shadow texture , In this way, the depth information in the texture can be used to judge whether the point is in the shadow .

// attach a level of a texture object as a logical buffer of a framebuffer object
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadowTex, 0);

5. Disable color buffering ( That is, disable color output )

// GL_NONE:No color buffers are written
glDrawBuffer(GL_NONE);

6. Enable depth testing

glEnable(GL_DEPTH_TEST);

7. Draw two objects in light space ( One obscures the other )

glDrawArrays(..one.);
glDrawArrays(..two.);

8. Vertex shader Ⅰ: The normal output passes through the illumination space MVP Coordinates after matrix transformation .
  Fragment Shader Ⅰ: Do nothing .
Because the depth test is performed after the fragment shader ,Alpha test -> Template testing -> Depth testing . Therefore, it must be output normally MVP Coordinates after matrix transformation . Because you don't need to paint , So fragment shaders 1 Nothing to do .

//  Vertex shader Ⅰ
gl_Position = shadowMVP * vec4(vertPos, 1.0);

//  Fragment Shader Ⅰ
void main(void) {
    }

The second round : Render the scene from the camera's perspective
1. Interrupt frame buffer
Since our frame buffer is not the default frame buffer , Rendering instructions will have no effect on the visual output of the window . For this reason , Rendering to a different frame buffer is called off screen rendering (Off-screen Rendering). Ensure that all rendering operations have visual effects in the main window , We need to activate again [ Default frame buffer ], Bind it to 0.

//  Switch back to the default frame buffer 
glBindFramebuffer(GL_FRAMEBUFFER, 0);

2. Activate #0 Texture cells and bind shadow textures
At this point, the texture with depth information is copied to the shadow texture unit .

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, shadowTex);

3. Enable color buffer ( Color output is enabled )

// GL_FRONT:Only the front left and front right color buffers are written
glDrawBuffer(GL_FRONT);

4. Build two MVP Matrix as a unified variable : One is camera space MVP matrix , A light space BMVP matrix .
5. Draw two objects in camera space ( One obscures the other )
6. Vertex shader Ⅱ:

[out] shadow_coord = shadowBMVP * vec4(vertPos, 1.0);
[out] gl_Position = proj_matrix * mv_matrix * vec4(vertPos, 1.0);

Fragment Shader Ⅱ:

in vec4 shadow_coord;
layout(binding = 0) uniform sampler2DShadow shadowTex;
main() {
    
	// 0: In the shadow ,1: Not in the shadow 
	float inShadow = textureProj(shadowTex, shadow_coord);
}

版权声明
本文为[itzyjr]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231639280838.html