diff --git a/.vs/grk-project/v16/.suo b/.vs/grk-project/v16/.suo index f6a7f80..a098aaa 100644 Binary files a/.vs/grk-project/v16/.suo and b/.vs/grk-project/v16/.suo differ diff --git a/.vs/grk-project/v16/Browse.VC.db b/.vs/grk-project/v16/Browse.VC.db index e57426c..9e4f8b1 100644 Binary files a/.vs/grk-project/v16/Browse.VC.db and b/.vs/grk-project/v16/Browse.VC.db differ diff --git a/cw 9/grk-cw9.vcxproj b/cw 9/grk-cw9.vcxproj index 7520a32..57e4d21 100644 --- a/cw 9/grk-cw9.vcxproj +++ b/cw 9/grk-cw9.vcxproj @@ -43,6 +43,10 @@ + + + + diff --git a/cw 9/grk-cw9.vcxproj.filters b/cw 9/grk-cw9.vcxproj.filters index a20ee76..95082df 100644 --- a/cw 9/grk-cw9.vcxproj.filters +++ b/cw 9/grk-cw9.vcxproj.filters @@ -127,5 +127,9 @@ Shader Files + + + + \ No newline at end of file diff --git a/cw 9/shaders/shader_blur.frag b/cw 9/shaders/shader_blur.frag index 5fb620e..967af0d 100644 --- a/cw 9/shaders/shader_blur.frag +++ b/cw 9/shaders/shader_blur.frag @@ -1,32 +1,18 @@ -#version 330 core -out vec4 FragColor; - -in vec2 TexCoords; +#version 430 core +layout (location = 0) out vec3 gPosition; +layout (location = 1) out vec3 gNormal; +layout (location = 2) out vec3 gAlbedo; -uniform sampler2D image; - -uniform bool horizontal; -uniform float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); +in vec2 TexCoords; +in vec3 FragPos; +in vec3 Normal; void main() -{ - vec2 tex_offset = 1.0 / textureSize(image, 0); // gets size of single texel - vec3 result = texture(image, TexCoords).rgb * weight[0]; // current fragment's contribution - if(horizontal) - { - for(int i = 1; i < 5; ++i) - { - result += texture(image, TexCoords + vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; - result += texture(image, TexCoords - vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; - } - } - else - { - for(int i = 1; i < 5; ++i) - { - result += texture(image, TexCoords + vec2(0.0, tex_offset.y * i)).rgb * weight[i]; - result += texture(image, TexCoords - vec2(0.0, tex_offset.y * i)).rgb * weight[i]; - } - } - FragColor = vec4(result, 1.0); +{ + // store the fragment position vector in the first gbuffer texture + gPosition = FragPos; + // also store the per-fragment normals into the gbuffer + gNormal = normalize(Normal); + // and the diffuse per-fragment color + gAlbedo.rgb = vec3(0.95); } \ No newline at end of file diff --git a/cw 9/shaders/shader_blur.vert b/cw 9/shaders/shader_blur.vert index 93b0300..7e73bf3 100644 --- a/cw 9/shaders/shader_blur.vert +++ b/cw 9/shaders/shader_blur.vert @@ -1,14 +1,27 @@ #version 430 core -layout(location = 0) in vec3 vertexPosition; -layout(location = 1) in vec3 vertexNormal; -layout(location = 2) in vec2 vertexTexCoord; - +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec2 aTexCoords; +out vec3 FragPos; out vec2 TexCoords; +out vec3 Normal; + +uniform bool invertedNormals; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; void main() { - gl_Position = vec4(vertexPosition, 1.0); - TexCoords = vertexTexCoord; + vec4 viewPos = view * model * vec4(aPos, 1.0); + FragPos = viewPos.xyz; + TexCoords = aTexCoords; + + mat3 normalMatrix = transpose(inverse(mat3(view * model))); + Normal = normalMatrix * (invertedNormals ? -aNormal : aNormal); + + gl_Position = projection * viewPos; } diff --git a/cw 9/shaders/shader_geometrypass.frag b/cw 9/shaders/shader_geometrypass.frag new file mode 100644 index 0000000..28d4cf0 --- /dev/null +++ b/cw 9/shaders/shader_geometrypass.frag @@ -0,0 +1,48 @@ +#version 330 core +out vec4 FragColor; + +in vec2 tc; + +uniform sampler2D color; +uniform sampler2D highlight; + +float rescale_z(float z){ + float n = 0.05; + float f = 20.; + return (2*n*f/(z*(n-f)+n+f))/f; +} +float weight[5] = float[] (0.227027, 0.1945946, 0.1216216, 0.054054, 0.016216); + +vec4 blur() +{ + vec2 tex_offset = 1.0 / textureSize(color, 0); // gets size of single texel + vec3 result = texture(highlight, tc).rgb * weight[0]; // current fragment's contribution + bool horizontal = true; + if(horizontal) + { + for(int i = 1; i < 5; ++i) + { + result += texture(highlight, tc + vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; + result += texture(highlight, tc - vec2(tex_offset.x * i, 0.0)).rgb * weight[i]; + } + } + else + { + for(int i = 1; i < 5; ++i) + { + result += texture(highlight, tc + vec2(0.0, tex_offset.y * i)).rgb * weight[i]; + result += texture(highlight, tc - vec2(0.0, tex_offset.y * i)).rgb * weight[i]; + } + } + return vec4(result, 1.0); +} + +void main() +{ + //float depthValue = texture(depthMap, tc).r; + //FragColor = vec4(vec3(rescale_z(depthValue)+0.5), 1.0); + //FragColor = vec4(vec3((depthValue)+0.5), 1.0); + + FragColor = vec4(texture(highlight, tc).rgb+texture(color, tc).rgb,1); + //FragColor = vec4( (texture(color, tc)-0.98)*50); +} \ No newline at end of file diff --git a/cw 9/shaders/shader_geometrypass.vert b/cw 9/shaders/shader_geometrypass.vert new file mode 100644 index 0000000..64c558f --- /dev/null +++ b/cw 9/shaders/shader_geometrypass.vert @@ -0,0 +1,14 @@ +#version 430 core + +layout(location = 0) in vec3 vertexPosition; +layout(location = 1) in vec3 vertexNormal; +layout(location = 2) in vec2 vertexTexCoord; + + +out vec2 tc; + +void main() +{ + tc = vertexTexCoord; + gl_Position = vec4(vertexPosition, 1.0); +} diff --git a/cw 9/src/room.hpp b/cw 9/src/room.hpp index 56a0c26..9236968 100644 --- a/cw 9/src/room.hpp +++ b/cw 9/src/room.hpp @@ -78,6 +78,8 @@ std::vector faces = GLuint depthMapFBO; GLuint depthMap; +GLuint gBuffer; + GLuint depthMapShipFBO; GLuint depthMapShip; @@ -90,6 +92,7 @@ GLuint programTex; GLuint programDepth; GLuint programSkybox; GLuint programBlur; +GLuint programGeometryPass; Core::Shader_Loader shaderLoader; @@ -110,6 +113,8 @@ unsigned int colorBuffers[2]; unsigned int pingpongFBO[2]; unsigned int pingpongBuffer[2]; +unsigned int gPosition, gNormal, gAlbedo; + GLuint VAO,VBO; float aspectRatio = 1.f; @@ -396,6 +401,66 @@ void renderShadowapSun(GLuint depthFBO, glm::mat4 light) { glViewport(0, 0, WIDTH, HEIGHT); } +void initgBuffer() +{ + glGenFramebuffers(1, &gBuffer); + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + // position color buffer + glGenTextures(1, &gPosition); + glBindTexture(GL_TEXTURE_2D, gPosition); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, WIDTH, HEIGHT, 0, GL_RGB, 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_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + // normal color buffer + glGenTextures(1, &gNormal); + glBindTexture(GL_TEXTURE_2D, gNormal); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, WIDTH, HEIGHT, 0, GL_RGBA, GL_FLOAT, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, gNormal, 0); + // color + specular color buffer + glGenTextures(1, &gAlbedo); + glBindTexture(GL_TEXTURE_2D, gAlbedo); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_TEXTURE_2D, gAlbedo, 0); + + unsigned int attachments[3] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2 }; + glDrawBuffers(3, attachments); +} + +void geometryPass() +{ + glBindFramebuffer(GL_FRAMEBUFFER, gBuffer); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)WIDTH / (float)HEIGHT, 0.1f, 50.0f); + glm::mat4 view = camera.GetViewMatrix(); + glm::mat4 model = glm::mat4(1.0f); + glUseProgram(programGeometryPass); + shaderGeometryPass.setMat4("projection", projection); + shaderGeometryPass.setMat4("view", view); + // room cube + model = glm::mat4(1.0f); + model = glm::translate(model, glm::vec3(0.0, 7.0f, 0.0f)); + model = glm::scale(model, glm::vec3(7.5f, 7.5f, 7.5f)); + shaderGeometryPass.setMat4("model", model); + shaderGeometryPass.setInt("invertedNormals", 1); // invert normals as we're inside the cube + renderCube(); + shaderGeometryPass.setInt("invertedNormals", 0); + // backpack model on the floor + model = glm::mat4(1.0f); + model = glm::translate(model, glm::vec3(0.0f, 0.5f, 0.0)); + model = glm::rotate(model, glm::radians(-90.0f), glm::vec3(1.0, 0.0, 0.0)); + model = glm::scale(model, glm::vec3(1.0f)); + shaderGeometryPass.setMat4("model", model); + backpack.Draw(shaderGeometryPass); + glBindFramebuffer(GL_FRAMEBUFFER, 0); + +} + void initDepthMap() { glGenFramebuffers(1, &depthMapFBO); @@ -640,6 +705,7 @@ void init(GLFWwindow* window) 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"); + programGeometryPass = shaderLoader.CreateProgram("shaders/shader_geometrypass.vert", "shaders/shader_geometrypass.frag"); programSun = shaderLoader.CreateProgram("shaders/shader_8_sun.vert", "shaders/shader_8_sun.frag"); programDepth = shaderLoader.CreateProgram("shaders/shader_shadowmapsun.vert", "shaders/shader_shadowmapsun.frag"); @@ -687,6 +753,8 @@ void init(GLFWwindow* window) loadModelToContext("./models/car/car.obj", models::carContext); loadModelToContext("./models/ceramic_vase_02_4k.obj", models::vaseContext); + initgBuffer(); + initDepthMap(); initDepthMapShip();