Add PCF shadows
This commit is contained in:
parent
cbec151054
commit
0d48e6ee37
@ -41,6 +41,8 @@
|
||||
<None Include="shaders\shader_9_1.vert" />
|
||||
<None Include="shaders\shader_8_sun.frag" />
|
||||
<None Include="shaders\shader_8_sun.vert" />
|
||||
<None Include="shaders\shader_depth.frag" />
|
||||
<None Include="shaders\shader_depth.vert" />
|
||||
<None Include="shaders\test.frag" />
|
||||
<None Include="shaders\test.vert" />
|
||||
</ItemGroup>
|
||||
|
@ -109,5 +109,11 @@
|
||||
<None Include="shaders\test.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_depth.frag">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
<None Include="shaders\shader_depth.vert">
|
||||
<Filter>Shader Files</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,4 +1,4 @@
|
||||
#version 430 core
|
||||
#version 430 core
|
||||
|
||||
float AMBIENT = 0.03;
|
||||
float PI = 3.14;
|
||||
@ -38,6 +38,25 @@ in vec3 sunDirTS;
|
||||
|
||||
in vec3 test;
|
||||
|
||||
// wektor przechowujący punkt widzenia światła
|
||||
in vec4 sunSpacePos;
|
||||
|
||||
// mapa przechowująca wartość cieni
|
||||
uniform sampler2D shadowMap;
|
||||
|
||||
// zmienne przechowujące szerokość i wysokość mapy cieni
|
||||
uniform float shadowMapWidth;
|
||||
uniform float shadowMapHeight;
|
||||
|
||||
// zmienne do PCF - Percentage Closer Filtering
|
||||
|
||||
// promień pixeli - np. 2 oznacza badanie na szerokość 5 bo 2 + 1 + 2
|
||||
const int pcfCount = 8;
|
||||
|
||||
// ilość wszystkich pixeli - (2 * promień + 1) ^ 2
|
||||
const float totalTexels = (pcfCount * 2.0 + 1.0) * (pcfCount * 2.0 + 1.0);
|
||||
|
||||
|
||||
float DistributionGGX(vec3 normal, vec3 H, float roughness){
|
||||
float a = roughness*roughness;
|
||||
float a2 = a*a;
|
||||
@ -98,6 +117,41 @@ vec3 PBRLight(vec3 lightDir, vec3 radiance, vec3 normal, vec3 V){
|
||||
return (kD * color / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
// metoda obliczająca cień za pomocą PCF
|
||||
|
||||
float calculateShadow(vec4 lightPos, sampler2D Shadow_Map){
|
||||
// ujednorodnienie pozycji światła
|
||||
vec3 _lightPos = lightPos.xyz/lightPos.w;
|
||||
|
||||
// skalowanie z wartości (-1, 1) do wartości (0, 1)
|
||||
_lightPos = _lightPos * 0.5 + 0.5;
|
||||
|
||||
// ustalenie wielości texeli
|
||||
double TexelWidth = 1.0/shadowMapWidth;
|
||||
double TexelHeight = 1.0/shadowMapHeight;
|
||||
|
||||
vec2 TexelSize = vec2(TexelWidth, TexelHeight);
|
||||
|
||||
// zmienna przechowująca wartość cienia
|
||||
float shadowSum = 0.0;
|
||||
|
||||
// algorytm PCF
|
||||
for (int y = -pcfCount ; y <= pcfCount ; y++) {
|
||||
for (int x = -pcfCount ; x <= pcfCount ; x++) {
|
||||
// liczymi wartości (x, y) z przesunięciem
|
||||
vec2 Offset = vec2(x, y) * TexelSize;
|
||||
|
||||
// sprawdzenie wartości z dpeth map oraz przypisanie odpowiedniej wartości dla shadow
|
||||
float shadow = _lightPos.z > texture(Shadow_Map, _lightPos.xy + Offset).r + 0.001 ? 1.0 : 0.0;
|
||||
|
||||
// dodanie wartości do shadow
|
||||
shadowSum += shadow;
|
||||
}
|
||||
}
|
||||
|
||||
// zwrócenie średniej wartości cieni z wszystkich pixeli wokół
|
||||
return ((shadowSum/totalTexels)/lightPos.w);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
@ -125,9 +179,12 @@ void main()
|
||||
attenuatedlightColor = angle_atenuation*spotlightColor/pow(length(spotlightPos-worldPos),2);
|
||||
ilumination=ilumination+PBRLight(spotlightDir,attenuatedlightColor,normal,viewDir);
|
||||
|
||||
//sun
|
||||
ilumination=ilumination+PBRLight(sunDir,sunColor,normal,viewDir);
|
||||
// obliczanie cienia
|
||||
float shadow = calculateShadow(sunSpacePos, shadowMap);
|
||||
|
||||
//sun
|
||||
// zaaplikowanie cienia do koloru światła.
|
||||
ilumination = ilumination + PBRLight(sunDir,sunColor * (1.0 - shadow), normal, viewDir);
|
||||
|
||||
outColor = vec4(vec3(1.0) - exp(-ilumination*exposition),1);
|
||||
//outColor = vec4(roughness,metallic,0,1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#version 430 core
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
@ -8,6 +8,7 @@ layout(location = 4) in vec3 vertexBitangent;
|
||||
|
||||
uniform mat4 transformation;
|
||||
uniform mat4 modelMatrix;
|
||||
uniform mat4 lightVP;
|
||||
|
||||
out vec3 vecNormal;
|
||||
out vec3 worldPos;
|
||||
@ -22,6 +23,9 @@ out vec3 lightDirTS;
|
||||
out vec3 spotlightDirTS;
|
||||
out vec3 sunDirTS;
|
||||
|
||||
out vec4 sunSpacePos;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
|
||||
@ -40,4 +44,7 @@ void main()
|
||||
spotlightDirTS = TBN*SL;
|
||||
sunDirTS = TBN*sunDir;
|
||||
|
||||
// przeliczanie pozycji światła
|
||||
sunSpacePos = lightVP * modelMatrix * vec4(vertexPosition, 1);
|
||||
|
||||
}
|
||||
|
5
cw 9/shaders/shader_depth.frag
Normal file
5
cw 9/shaders/shader_depth.frag
Normal file
@ -0,0 +1,5 @@
|
||||
#version 430 core
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
13
cw 9/shaders/shader_depth.vert
Normal file
13
cw 9/shaders/shader_depth.vert
Normal file
@ -0,0 +1,13 @@
|
||||
#version 430 core
|
||||
|
||||
layout(location = 0) in vec3 vertexPosition;
|
||||
layout(location = 1) in vec3 vertexNormal;
|
||||
layout(location = 2) in vec2 vertexTexCoord;
|
||||
|
||||
uniform mat4 viewProjectionMatrix;
|
||||
uniform mat4 modelMatrix;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = viewProjectionMatrix * modelMatrix * vec4(vertexPosition, 1.0);
|
||||
}
|
@ -43,6 +43,7 @@ GLuint program;
|
||||
GLuint programSun;
|
||||
GLuint programTest;
|
||||
GLuint programTex;
|
||||
GLuint programDepth;
|
||||
|
||||
Core::Shader_Loader shaderLoader;
|
||||
|
||||
@ -53,6 +54,10 @@ glm::vec3 sunPos = glm::vec3(-4.740971f, 2.149999f, 0.369280f);
|
||||
glm::vec3 sunDir = glm::vec3(-0.93633f, 0.351106, 0.003226f);
|
||||
glm::vec3 sunColor = glm::vec3(0.9f, 0.9f, 0.7f)*5;
|
||||
|
||||
// macierz light view point - punkt widzenia światła
|
||||
glm::mat4 lightVP = glm::ortho(-4.f, 2.5f, -2.f, 5.f, 1.0f, 30.0f) * glm::lookAt(sunPos, sunPos - sunDir, glm::vec3(0, 1, 0));
|
||||
|
||||
|
||||
glm::vec3 cameraPos = glm::vec3(0.479490f, 1.250000f, -2.124680f);
|
||||
glm::vec3 cameraDir = glm::vec3(-0.354510f, 0.000000f, 0.935054f);
|
||||
|
||||
@ -151,19 +156,76 @@ void drawObjectPBR(Core::RenderContext& context, glm::mat4 modelMatrix, glm::vec
|
||||
glUniform3f(glGetUniformLocation(program, "spotlightPos"), spotlightPos.x, spotlightPos.y, spotlightPos.z);
|
||||
glUniform3f(glGetUniformLocation(program, "spotlightColor"), spotlightColor.x, spotlightColor.y, spotlightColor.z);
|
||||
glUniform1f(glGetUniformLocation(program, "spotlightPhi"), spotlightPhi);
|
||||
|
||||
|
||||
glUniform1f(glGetUniformLocation(program, "shadowMapWidth"), SHADOW_WIDTH);
|
||||
glUniform1f(glGetUniformLocation(program, "shadowMapHeight"), SHADOW_HEIGHT);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glUniformMatrix4fv(glGetUniformLocation(program, "lightVP"), 1, GL_FALSE, (float*)&lightVP);
|
||||
|
||||
Core::DrawContext(context);
|
||||
|
||||
}
|
||||
|
||||
void renderShadowapSun() {
|
||||
|
||||
// metoda inicjalizująca mapę głębokości
|
||||
void initDepthMap() {
|
||||
glGenFramebuffers(1, &depthMapFBO);
|
||||
|
||||
glGenTextures(1, &depthMap);
|
||||
glBindTexture(GL_TEXTURE_2D, depthMap);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT,
|
||||
SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
// metoda renderująca obiekt na mapie głębokości
|
||||
void drawObjectDepth(Core::RenderContext& context, glm::mat4 modelMatrix, glm::mat4 viewProjectionMatrix) {
|
||||
glUniformMatrix4fv(glGetUniformLocation(programDepth, "modelMatrix"), 1, GL_FALSE, (float*)&modelMatrix);
|
||||
glUniformMatrix4fv(glGetUniformLocation(programDepth, "viewProjectionMatrix"), 1, GL_FALSE, (float*)&viewProjectionMatrix);
|
||||
Core::DrawContext(context);
|
||||
}
|
||||
|
||||
// renderowanie mapy głębokości
|
||||
void renderShadowapSun(glm::mat4 lightViewPointMatrix) {
|
||||
float time = glfwGetTime();
|
||||
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
|
||||
//uzupelnij o renderowanie glebokosci do tekstury
|
||||
|
||||
|
||||
|
||||
//ustawianie przestrzeni rysowania
|
||||
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
|
||||
//bindowanie FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
|
||||
//czyszczenie mapy głębokości
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
//ustawianie programu depth
|
||||
glUseProgram(programDepth);
|
||||
|
||||
// umieszczenie w mapie wszystkich modeli które mają rzucać cień
|
||||
drawObjectDepth(models::bedContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::chairContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::deskContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::doorContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::drawerContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::marbleBustContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::materaceContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::pencilsContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::planeContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::roomContext, glm::mat4(), lightViewPointMatrix);
|
||||
drawObjectDepth(models::windowContext, glm::mat4(), lightViewPointMatrix);
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
glViewport(0, 0, WIDTH, HEIGHT);
|
||||
@ -175,7 +237,9 @@ void renderScene(GLFWwindow* window)
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
float time = glfwGetTime();
|
||||
updateDeltaTime(time);
|
||||
renderShadowapSun();
|
||||
|
||||
// wywołanie funkcji renderowania depth mapy
|
||||
renderShadowapSun(lightVP);
|
||||
|
||||
//space lamp
|
||||
glUseProgram(programSun);
|
||||
@ -265,11 +329,17 @@ void init(GLFWwindow* window)
|
||||
{
|
||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||
|
||||
// enable testowania mapy głębokości
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
|
||||
program = shaderLoader.CreateProgram("shaders/shader_9_1.vert", "shaders/shader_9_1.frag");
|
||||
programTest = shaderLoader.CreateProgram("shaders/test.vert", "shaders/test.frag");
|
||||
programSun = shaderLoader.CreateProgram("shaders/shader_8_sun.vert", "shaders/shader_8_sun.frag");
|
||||
|
||||
// program odpowiadający za generowanie mapy głębokości
|
||||
programDepth = shaderLoader.CreateProgram("shaders/shader_depth.vert", "shaders/shader_depth.frag");
|
||||
|
||||
loadModelToContext("./models/sphere.obj", sphereContext);
|
||||
loadModelToContext("./models/spaceship.obj", shipContext);
|
||||
|
||||
@ -289,6 +359,9 @@ void init(GLFWwindow* window)
|
||||
loadModelToContext("./models/window.obj", models::windowContext);
|
||||
loadModelToContext("./models/test.obj", models::testContext);
|
||||
|
||||
// inicjalizacja mapy głębokości
|
||||
initDepthMap();
|
||||
|
||||
}
|
||||
|
||||
void shutdown(GLFWwindow* window)
|
||||
|
Loading…
Reference in New Issue
Block a user