diff --git a/.vs/shader3/v14/.suo b/.vs/shader3/v14/.suo index d4c6565..1beb327 100644 Binary files a/.vs/shader3/v14/.suo and b/.vs/shader3/v14/.suo differ diff --git a/main.cpp b/main.cpp index 6a17b52..e752322 100644 --- a/main.cpp +++ b/main.cpp @@ -117,7 +117,7 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ //init projective texture program GPUProgram projectedTextureProgram; projectedTextureProgram.AttachShader(GL_VERTEX_SHADER, "res/shader/projector.vs"); - projectedTextureProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/projector.fs"); + projectedTextureProgram.AttachShader(GL_FRAGMENT_SHADER, "res/shader/projector_shadow.fs"); projectedTextureProgram.Link(); projectedTextureProgram.DetectAttribute("pos"); @@ -131,6 +131,23 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ projectedTextureProgram.DetectUniform("U_ProjectorMatrix"); projectedTextureProgram.DetectUniform("U_ProjectorNoTransScaleMatrix"); + //init projective texture program2 + GPUProgram projectedTextureProgram2; + projectedTextureProgram2.AttachShader(GL_VERTEX_SHADER, "res/shader/projector.vs"); + projectedTextureProgram2.AttachShader(GL_FRAGMENT_SHADER, "res/shader/projector_shadow2.fs"); + projectedTextureProgram2.Link(); + + projectedTextureProgram2.DetectAttribute("pos"); + projectedTextureProgram2.DetectAttribute("texcoord"); + projectedTextureProgram2.DetectUniform("M"); + projectedTextureProgram2.DetectUniform("V"); + projectedTextureProgram2.DetectUniform("P"); + projectedTextureProgram2.DetectUniform("U_ShadowMap"); + projectedTextureProgram2.DetectUniform("U_MainTexture"); + projectedTextureProgram2.DetectUniform("U_ProjectiveTexture"); + projectedTextureProgram2.DetectUniform("U_ProjectorMatrix"); + projectedTextureProgram2.DetectUniform("U_ProjectorNoTransScaleMatrix"); + //init 3d model ObjModel obj, quad, sphere; @@ -148,7 +165,7 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glm::mat4 model = glm::translate(6.0f, 0.0f, -6.0f) * glm::rotate(-30.0f, 1.0f, 1.0f, 1.0f); - glm::mat4 quadModel = glm::translate(6.0f, -1.5f, -6.0f) * glm::rotate(-90.0f, 1.0f, 0.0f, 0.0f) * glm::scale(10.0f, 10.0f, 10.0f); + glm::mat4 quadModel = glm::translate(6.0f, -1.5f, -6.0f) * glm::rotate(-90.0f, 1.0f, 0.0f, 0.0f) * glm::scale(20.0f, 20.0f, 20.0f); glm::mat4 sphereModel = glm::translate(0.0f, 0.0f, 0.0f) * glm::scale(0.3f, 0.3f, 0.3f); @@ -156,7 +173,7 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glm::mat4 projectionMatrix = glm::perspective(50.0f, (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f); glm::mat4 projectorViewMatrix = glm::lookAt(glm::vec3(0.0f, 4.0f, 0.0f), glm::vec3(6.0f, -1.0f, -6.0f), glm::vec3(0.0f, 1.0f, 0.0f)); - glm::mat4 projectorProjectionMatrix = glm::perspective(50.0f, (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f); + glm::mat4 projectorProjectionMatrix = glm::perspective(20.0f, (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f); glm::mat4 projectorMatrix = glm::translate(0.5f, 0.5f, 0.5f)*glm::scale(0.5f, 0.5f, 0.5f) * projectorProjectionMatrix * projectorViewMatrix; glm::mat4 projectorNoTransScaleMatrix = projectorProjectionMatrix * projectorViewMatrix; @@ -175,6 +192,11 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ projectiveTextureFbo.AttachDepthBuffer("depth", viewportWidth, viewportHeight); projectiveTextureFbo.Finish(); + FBO projectiveTextureFbo2; + projectiveTextureFbo2.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGBA, viewportWidth, viewportHeight); + projectiveTextureFbo2.AttachDepthBuffer("depth", viewportWidth, viewportHeight); + projectiveTextureFbo2.Finish(); + FBO depthFbo; depthFbo.AttachColorBuffer("color", GL_COLOR_ATTACHMENT0, GL_RGB, viewportWidth, viewportHeight); depthFbo.AttachDepthBuffer("depth", viewportWidth, viewportHeight); @@ -199,13 +221,13 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniformMatrix4fv(depthProgram.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(projectorViewMatrix)); obj.Bind(depthProgram.GetLocation("pos"), depthProgram.GetLocation("texcoord"), depthProgram.GetLocation("normal")); obj.Draw(); - glCullFace(GL_BACK); glUniformMatrix4fv(depthProgram.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(quadModel)); quad.Bind(depthProgram.GetLocation("pos"), depthProgram.GetLocation("texcoord"), depthProgram.GetLocation("normal")); quad.Draw(); depthFbo.Unbind(); + glCullFace(GL_BACK); /*ԭͼfbo*/ originalFbo.Bind(); @@ -227,6 +249,8 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ originalFbo.Unbind(); /*ͶӰfbo*/ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); projectiveTextureFbo.Bind(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glUseProgram(projectedTextureProgram.mProgram); @@ -257,6 +281,43 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ quad.Draw(); projectiveTextureFbo.Unbind(); + glDisable(GL_BLEND); + + + /*ͶӰfbo ´øÒõÓ°*/ + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + projectiveTextureFbo2.Bind(); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glUseProgram(projectedTextureProgram2.mProgram); + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("P"), 1, GL_FALSE, glm::value_ptr(projectionMatrix)); + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("V"), 1, GL_FALSE, glm::value_ptr(viewMatrix)); + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(model)); + + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("U_ProjectorMatrix"), 1, GL_FALSE, glm::value_ptr(projectorMatrix)); + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("U_ProjectorNoTransScaleMatrix"), 1, GL_FALSE, glm::value_ptr(projectorNoTransScaleMatrix)); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, mainTexture); + glUniform1i(projectedTextureProgram2.GetLocation("U_MainTexture"), 0); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, projectiveTexture); + glUniform1i(projectedTextureProgram2.GetLocation("U_ProjectiveTexture"), 1); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, depthFbo.GetBuffer("depth")); + glUniform1i(projectedTextureProgram2.GetLocation("U_ShadowMap"), 2); + + obj.Bind(projectedTextureProgram2.GetLocation("pos"), projectedTextureProgram2.GetLocation("texcoord"), projectedTextureProgram2.GetLocation("normal")); + obj.Draw(); + + glUniformMatrix4fv(projectedTextureProgram2.GetLocation("M"), 1, GL_FALSE, glm::value_ptr(quadModel)); + quad.Bind(projectedTextureProgram2.GetLocation("pos"), projectedTextureProgram2.GetLocation("texcoord"), projectedTextureProgram2.GetLocation("normal")); + quad.Draw(); + + projectiveTextureFbo2.Unbind(); + glDisable(GL_BLEND); MSG msg; while (true) @@ -292,6 +353,12 @@ INT WINAPI WinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance, _ glUniform1i(depthRenderProgram.GetLocation("U_MainTexture"), 0); fsq.DrawToRightBottom(depthRenderProgram.GetLocation("pos"), depthRenderProgram.GetLocation("texcoord")); + glUseProgram(originalProgram.mProgram); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, projectiveTextureFbo2.GetBuffer("color")); + glUniform1i(originalProgram.GetLocation("U_MainTexture"), 0); + fsq.DrawToLeftBottom(originalProgram.GetLocation("pos"), originalProgram.GetLocation("texcoord")); + glFlush(); SwapBuffers(dc); } diff --git a/res/shader/projector_shadow.fs b/res/shader/projector_shadow.fs new file mode 100644 index 0000000..9b4d9a9 --- /dev/null +++ b/res/shader/projector_shadow.fs @@ -0,0 +1,29 @@ + +uniform sampler2D U_ShadowMap; +uniform sampler2D U_ProjectiveTexture; +uniform sampler2D U_MainTexture; + +varying vec2 V_Texcoord; +varying vec3 V_WorldPos; +varying vec4 V_ProjectCoord; +varying vec4 V_ProjectorSpaceFragPos; + +float CalculateShadow(){ + vec3 fragPos = V_ProjectorSpaceFragPos.xyz / V_ProjectorSpaceFragPos.w; + fragPos = fragPos * 0.5 + vec3(0.5); + + float depthInShadowMap = texture2D(U_ShadowMap, fragPos.xy).r; + float currentDepth = fragPos.z; + float shadow = (currentDepth - 0.001) > depthInShadowMap ? 1.0 : 0.0; + return shadow; +} + +void main() +{ + if(V_ProjectCoord.z > 0){ + float shadow = CalculateShadow(); + gl_FragColor = vec4(texture2D(U_MainTexture, V_Texcoord).rgb, textureProj(U_ProjectiveTexture, V_ProjectCoord).a); + } else { + gl_FragColor = texture2D(U_MainTexture, V_Texcoord); + } +} \ No newline at end of file diff --git a/res/shader/projector_shadow2.fs b/res/shader/projector_shadow2.fs new file mode 100644 index 0000000..a8033a8 --- /dev/null +++ b/res/shader/projector_shadow2.fs @@ -0,0 +1,33 @@ + +uniform sampler2D U_ShadowMap; +uniform sampler2D U_ProjectiveTexture; +uniform sampler2D U_MainTexture; + +varying vec2 V_Texcoord; +varying vec3 V_WorldPos; +varying vec4 V_ProjectCoord; +varying vec4 V_ProjectorSpaceFragPos; + +float CalculateShadow(){ + vec3 fragPos = V_ProjectorSpaceFragPos.xyz / V_ProjectorSpaceFragPos.w; + fragPos = fragPos * 0.5 + vec3(0.5); + + float depthInShadowMap = texture2D(U_ShadowMap, fragPos.xy).r; + float currentDepth = fragPos.z; + float shadow = (currentDepth - 0.001) > depthInShadowMap ? 1.0 : 0.0; + return shadow; +} + +void main() +{ + if(V_ProjectCoord.z > 0){ + vec4 color = textureProj(U_ProjectiveTexture, V_ProjectCoord); + if(color.a == 0.0){ + gl_FragColor = texture2D(U_MainTexture, V_Texcoord); + } else { + gl_FragColor = vec4(0.0,0.0,0.0,textureProj(U_ProjectiveTexture, V_ProjectCoord).a); + } + } else { + gl_FragColor = texture2D(U_MainTexture, V_Texcoord); + } +} \ No newline at end of file diff --git a/shader3.vcxproj b/shader3.vcxproj index 2a4b0a6..886a1f7 100644 --- a/shader3.vcxproj +++ b/shader3.vcxproj @@ -85,6 +85,8 @@ + + diff --git a/shader3.vcxproj.filters b/shader3.vcxproj.filters index 455e138..d3e99f2 100644 --- a/shader3.vcxproj.filters +++ b/shader3.vcxproj.filters @@ -67,5 +67,11 @@ src + + src + + + src + \ No newline at end of file