small-projects/cpp-voxel-engine/a

75 lines
2.7 KiB
Plaintext
Raw Normal View History

2025-04-06 04:20:54 +00:00
static void computeLightSpace(glm::mat4 view, glm::mat4 proj,
glm::vec3 lightDir,
glm::mat4 out[3]){
glm::mat4 inv = glm::inverse(proj*view);
glm::vec4 corners[8] = {
{-1,-1,-1,1},{1,-1,-1,1},{1,1,-1,1},{-1,1,-1,1},
{-1,-1, 1,1},{1,-1, 1,1},{1,1, 1,1},{-1,1, 1,1}
};
for(int i=0;i<3;i++){
glm::mat4 lightView = glm::lookAt(-lightDir*100.0f,glm::vec3(0),glm::vec3(0,1,0));
glm::vec3 mn(FLT_MAX), mx(-FLT_MAX);
for(auto &c: corners){
glm::vec4 wc = inv * c; wc/=wc.w;
glm::vec4 lc = lightView * wc;
mn = glm::min(mn,glm::vec3(lc));
mx = glm::max(mx,glm::vec3(lc));
}
out[i] = glm::ortho(mn.x,mx.x,mn.y,mx.y,-mx.z-50.0f,-mn.z+50.0f) * lightView;
}
}
void VoxelGame::render(glm::mat4 const& view, glm::mat4 const& proj){
computeLightSpace(view,proj,lightDir,lightSpaceMat);
// 1) depth passes
for(int i=0;i<NUM_CASCADES;i++){
glViewport(0,0,SHADOW_MAP_SIZE,SHADOW_MAP_SIZE);
glBindFramebuffer(GL_FRAMEBUFFER,depthFBO[i]);
glClear(GL_DEPTH_BUFFER_BIT);
glUseProgram(depthProg);
glUniformMatrix4fv(glGetUniformLocation(depthProg,"uLightSpace"),
1,GL_FALSE,glm::value_ptr(lightSpaceMat[i]));
renderScene(depthProg);
}
glBindFramebuffer(GL_FRAMEBUFFER,0);
// 2) main pass
glViewport(0,0,screenW,screenH);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glUseProgram(mainProg);
glUniformMatrix4fv(glGetUniformLocation(mainProg,"uView"),
1,GL_FALSE,glm::value_ptr(view));
glUniformMatrix4fv(glGetUniformLocation(mainProg,"uProj"),
1,GL_FALSE,glm::value_ptr(proj));
for(int i=0;i<NUM_CASCADES;i++){
char buf[32]; sprintf(buf,"uLightSpace[%d]",i);
glUniformMatrix4fv(glGetUniformLocation(mainProg,buf),
1,GL_FALSE,glm::value_ptr(lightSpaceMat[i]));
}
glUniform1fv(glGetUniformLocation(mainProg,"cascadeSplit"),
NUM_CASCADES,cascadeSplits);
glUniform3fv(glGetUniformLocation(mainProg,"lightDir"),
1,glm::value_ptr(lightDir));
glUniform3fv(glGetUniformLocation(mainProg,"viewPos"),
1,glm::value_ptr(cameraPos));
// bind textures
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,textureDirt);
glUniform1i(glGetUniformLocation(mainProg,"uTexDirt"),0);
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D,textureGrass);
glUniform1i(glGetUniformLocation(mainProg,"uTexGrass"),1);
for(int i=0;i<NUM_CASCADES;i++){
glActiveTexture(GL_TEXTURE2+i);
glBindTexture(GL_TEXTURE_2D,depthTex[i]);
char buf[32]; sprintf(buf,"uShadowMap[%d]",i);
glUniform1i(glGetUniformLocation(mainProg,buf),2+i);
}
renderScene(mainProg);
}