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_9_1.vert" />
|
||||||
<None Include="shaders\shader_8_sun.frag" />
|
<None Include="shaders\shader_8_sun.frag" />
|
||||||
<None Include="shaders\shader_8_sun.vert" />
|
<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.frag" />
|
||||||
<None Include="shaders\test.vert" />
|
<None Include="shaders\test.vert" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -109,5 +109,11 @@
|
|||||||
<None Include="shaders\test.vert">
|
<None Include="shaders\test.vert">
|
||||||
<Filter>Shader Files</Filter>
|
<Filter>Shader Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
|
<None Include="shaders\shader_depth.frag">
|
||||||
|
<Filter>Shader Files</Filter>
|
||||||
|
</None>
|
||||||
|
<None Include="shaders\shader_depth.vert">
|
||||||
|
<Filter>Shader Files</Filter>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -1,4 +1,4 @@
|
|||||||
#version 430 core
|
#version 430 core
|
||||||
|
|
||||||
float AMBIENT = 0.03;
|
float AMBIENT = 0.03;
|
||||||
float PI = 3.14;
|
float PI = 3.14;
|
||||||
@ -38,6 +38,25 @@ in vec3 sunDirTS;
|
|||||||
|
|
||||||
in vec3 test;
|
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 DistributionGGX(vec3 normal, vec3 H, float roughness){
|
||||||
float a = roughness*roughness;
|
float a = roughness*roughness;
|
||||||
float a2 = a*a;
|
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;
|
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()
|
void main()
|
||||||
{
|
{
|
||||||
@ -125,9 +179,12 @@ void main()
|
|||||||
attenuatedlightColor = angle_atenuation*spotlightColor/pow(length(spotlightPos-worldPos),2);
|
attenuatedlightColor = angle_atenuation*spotlightColor/pow(length(spotlightPos-worldPos),2);
|
||||||
ilumination=ilumination+PBRLight(spotlightDir,attenuatedlightColor,normal,viewDir);
|
ilumination=ilumination+PBRLight(spotlightDir,attenuatedlightColor,normal,viewDir);
|
||||||
|
|
||||||
//sun
|
// obliczanie cienia
|
||||||
ilumination=ilumination+PBRLight(sunDir,sunColor,normal,viewDir);
|
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(vec3(1.0) - exp(-ilumination*exposition),1);
|
||||||
//outColor = vec4(roughness,metallic,0,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 = 0) in vec3 vertexPosition;
|
||||||
layout(location = 1) in vec3 vertexNormal;
|
layout(location = 1) in vec3 vertexNormal;
|
||||||
@ -8,6 +8,7 @@ layout(location = 4) in vec3 vertexBitangent;
|
|||||||
|
|
||||||
uniform mat4 transformation;
|
uniform mat4 transformation;
|
||||||
uniform mat4 modelMatrix;
|
uniform mat4 modelMatrix;
|
||||||
|
uniform mat4 lightVP;
|
||||||
|
|
||||||
out vec3 vecNormal;
|
out vec3 vecNormal;
|
||||||
out vec3 worldPos;
|
out vec3 worldPos;
|
||||||
@ -22,6 +23,9 @@ out vec3 lightDirTS;
|
|||||||
out vec3 spotlightDirTS;
|
out vec3 spotlightDirTS;
|
||||||
out vec3 sunDirTS;
|
out vec3 sunDirTS;
|
||||||
|
|
||||||
|
out vec4 sunSpacePos;
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
|
worldPos = (modelMatrix* vec4(vertexPosition,1)).xyz;
|
||||||
@ -40,4 +44,7 @@ void main()
|
|||||||
spotlightDirTS = TBN*SL;
|
spotlightDirTS = TBN*SL;
|
||||||
sunDirTS = TBN*sunDir;
|
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 programSun;
|
||||||
GLuint programTest;
|
GLuint programTest;
|
||||||
GLuint programTex;
|
GLuint programTex;
|
||||||
|
GLuint programDepth;
|
||||||
|
|
||||||
Core::Shader_Loader shaderLoader;
|
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 sunDir = glm::vec3(-0.93633f, 0.351106, 0.003226f);
|
||||||
glm::vec3 sunColor = glm::vec3(0.9f, 0.9f, 0.7f)*5;
|
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 cameraPos = glm::vec3(0.479490f, 1.250000f, -2.124680f);
|
||||||
glm::vec3 cameraDir = glm::vec3(-0.354510f, 0.000000f, 0.935054f);
|
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, "spotlightPos"), spotlightPos.x, spotlightPos.y, spotlightPos.z);
|
||||||
glUniform3f(glGetUniformLocation(program, "spotlightColor"), spotlightColor.x, spotlightColor.y, spotlightColor.z);
|
glUniform3f(glGetUniformLocation(program, "spotlightColor"), spotlightColor.x, spotlightColor.y, spotlightColor.z);
|
||||||
glUniform1f(glGetUniformLocation(program, "spotlightPhi"), spotlightPhi);
|
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);
|
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();
|
float time = glfwGetTime();
|
||||||
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
|
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);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
glViewport(0, 0, WIDTH, HEIGHT);
|
glViewport(0, 0, WIDTH, HEIGHT);
|
||||||
@ -175,7 +237,9 @@ void renderScene(GLFWwindow* window)
|
|||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
float time = glfwGetTime();
|
float time = glfwGetTime();
|
||||||
updateDeltaTime(time);
|
updateDeltaTime(time);
|
||||||
renderShadowapSun();
|
|
||||||
|
// wywołanie funkcji renderowania depth mapy
|
||||||
|
renderShadowapSun(lightVP);
|
||||||
|
|
||||||
//space lamp
|
//space lamp
|
||||||
glUseProgram(programSun);
|
glUseProgram(programSun);
|
||||||
@ -265,10 +329,16 @@ void init(GLFWwindow* window)
|
|||||||
{
|
{
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
|
||||||
|
// enable testowania mapy głębokości
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
|
||||||
program = shaderLoader.CreateProgram("shaders/shader_9_1.vert", "shaders/shader_9_1.frag");
|
program = shaderLoader.CreateProgram("shaders/shader_9_1.vert", "shaders/shader_9_1.frag");
|
||||||
programTest = shaderLoader.CreateProgram("shaders/test.vert", "shaders/test.frag");
|
programTest = shaderLoader.CreateProgram("shaders/test.vert", "shaders/test.frag");
|
||||||
programSun = shaderLoader.CreateProgram("shaders/shader_8_sun.vert", "shaders/shader_8_sun.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/sphere.obj", sphereContext);
|
||||||
loadModelToContext("./models/spaceship.obj", shipContext);
|
loadModelToContext("./models/spaceship.obj", shipContext);
|
||||||
@ -289,6 +359,9 @@ void init(GLFWwindow* window)
|
|||||||
loadModelToContext("./models/window.obj", models::windowContext);
|
loadModelToContext("./models/window.obj", models::windowContext);
|
||||||
loadModelToContext("./models/test.obj", models::testContext);
|
loadModelToContext("./models/test.obj", models::testContext);
|
||||||
|
|
||||||
|
// inicjalizacja mapy głębokości
|
||||||
|
initDepthMap();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shutdown(GLFWwindow* window)
|
void shutdown(GLFWwindow* window)
|
||||||
|
Loading…
Reference in New Issue
Block a user