75 lines
2.7 KiB
Plaintext
75 lines
2.7 KiB
Plaintext
|
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);
|
||
|
}
|
||
|
|