diff --git a/assets/Shaders/anime/renderNormals.fs b/assets/Shaders/anime/renderNormals.fs new file mode 100644 index 00000000..59633e31 --- /dev/null +++ b/assets/Shaders/anime/renderNormals.fs @@ -0,0 +1,15 @@ +#version 330 core + +out vec4 FragColor; + + +in vec3 FragPos; +in vec3 Normal; + + +void main(){ + vec3 norm = normalize(Normal); + + + FragColor = vec4(norm,1.0); +} diff --git a/assets/Shaders/anime/renderNormals.vs b/assets/Shaders/anime/renderNormals.vs new file mode 100644 index 00000000..11cd314b --- /dev/null +++ b/assets/Shaders/anime/renderNormals.vs @@ -0,0 +1,63 @@ +//Vertex Shader +#version 330 core + + + +//input buffers +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 2) in vec4 aWeights; +layout (location = 3) in vec4 aIndex; + + +//coordinate space transformation matrices +uniform mat4 transform; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +//bone related variables +const int MAX_WEIGHTS = 4; +const int MAX_BONES = 100; +uniform mat4 bones[MAX_BONES]; +uniform int hasBones; +uniform int numBones; + + + +//output buffers +out vec3 Normal; +out vec3 FragPos; + + + + +void main() { + + + + //calculate bone transform + mat4 BoneTransform = (bones[int(aIndex[0])] * aWeights[0]); + BoneTransform = BoneTransform + (bones[int(aIndex[1])] * aWeights[1]); + BoneTransform = BoneTransform + (bones[int(aIndex[2])] * aWeights[2]); + BoneTransform = BoneTransform + (bones[int(aIndex[3])] * aWeights[3]); + + + //apply bone transform to position vectors + vec4 FinalVertex = BoneTransform * vec4(aPos, 1.0); + vec4 FinalNormal = BoneTransform * vec4(aNormal, 1.0); + + + //make sure the W component is 1.0 + FinalVertex = vec4(FinalVertex.xyz, 1.0); + FinalNormal = vec4(FinalNormal.xyz, 1.0); + + + //push frag, normal, and texture positions to fragment shader + FragPos = vec3(model * FinalVertex); + Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz; + + + //set final position with opengl space + gl_Position = projection * view * model * FinalVertex; +} \ No newline at end of file diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index c29eef6e..2ac5eb2f 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -148,6 +148,13 @@ public class RenderingEngine { static Framebuffer transparencyBuffer; static ShaderProgram oitCompositeProgram; + /* + render normals + */ + static Texture gameImageNormalsTexture; + static Framebuffer gameImageNormalsFramebuffer; + static ShaderProgram renderNormalsShader; + /* Perspective volumetrics */ @@ -296,6 +303,18 @@ public class RenderingEngine { volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, volumeDepthFrontfaceTexture); + // + //Game normals + // + /* + gameImageNormalsTexture; + static Framebuffer gameImageNormalsFramebuffer; + static ShaderProgram renderNormalsShader; + */ + gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColor(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, gameImageNormalsTexture); + renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/anime/renderNormals.vs", "Shaders/anime/renderNormals.fs"); + // //Transparency framebuffers // @@ -413,6 +432,8 @@ public class RenderingEngine { if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ renderGameContent(); renderDebugContent(); + renderNormals(); + compositeGameImage(); } @@ -589,7 +610,7 @@ public class RenderingEngine { modelTransformMatrix.scale(EntityUtils.getScale(currentEntity)); currentActor.applyModelMatrix(modelTransformMatrix); //draw - currentActor.draw(); + currentActor.draw(true); } } @@ -629,44 +650,31 @@ public class RenderingEngine { modelTransformMatrix.scale(EntityUtils.getScale(currentEntity)); currentActor.applyModelMatrix(modelTransformMatrix); //draw - currentActor.draw(); + currentActor.draw(true); } } - // - // Pass Three: Composite transparency on top of solids - // - glDepthFunc(GL_ALWAYS); - // glDepthMask(false); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - screenFramebuffer.bind(); - Globals.renderingEngine.setActiveShader(oitCompositeProgram); - - glBindVertexArray(screenTextureVAO); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE3); - glBindTexture(GL_TEXTURE_2D, 0); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer()); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer()); - - glDrawArrays(GL_TRIANGLES, 0, 6); - glBindVertexArray(0); // glBindVertexArray(0); } static void renderDebugContent(){ + + //bind screen fbo + screenFramebuffer.bind(); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDepthMask(true); + glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + Matrix4f modelTransformMatrix = new Matrix4f(); + if(Globals.userSettings.graphicsDebugDrawCollisionSpheres()){ for(Entity currentHitbox : Globals.hitboxManager.getAllHitboxes()){ if((boolean)currentHitbox.getData(EntityDataStrings.DATA_STRING_DRAW)){ @@ -813,6 +821,89 @@ public class RenderingEngine { } } } + + static void renderNormals(){ + + /* + gameImageNormalsTexture; + static Framebuffer gameImageNormalsFramebuffer; + static ShaderProgram renderNormalsShader; + */ + + //bind screen fbo + gameImageNormalsFramebuffer.bind(); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glDepthMask(true); + glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); + + /// + /// R E N D E R I N G S T U F F + /// + //Sets the background color. + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + Matrix4f modelTransformMatrix = new Matrix4f(); + + Globals.renderingEngine.setActiveShader(renderNormalsShader); + + Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); + modelTransformMatrix = new Matrix4f(); + for(Entity currentEntity : Globals.entityManager.getDrawable()){ + Vector3d position = EntityUtils.getPosition(currentEntity); + if( + (boolean)currentEntity.getData(EntityDataStrings.DATA_STRING_DRAW) && + currentEntity.getData(EntityDataStrings.DRAW_SOLID_PASS) != null && + drawPoint(cameraPos,new Vector3f((float)position.x,(float)position.y,(float)position.z)) + ){ + //fetch actor + Actor currentActor = EntityUtils.getActor(currentEntity); + currentActor.incrementAnimationTime(0.001); + //calculate camera-modified vector3f + Vector3f cameraModifiedPosition = new Vector3f((float)position.x,(float)position.y,(float)position.z).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)); + //calculate and apply model transform + modelTransformMatrix.identity(); + modelTransformMatrix.translate(cameraModifiedPosition); + modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); + modelTransformMatrix.scale(EntityUtils.getScale(currentEntity)); + currentActor.applyModelMatrix(modelTransformMatrix); + //draw + currentActor.draw(false); + } + } + } + + static void compositeGameImage(){ + // + // Pass Three: Composite transparency on top of solids + // + glDepthFunc(GL_ALWAYS); + // glDepthMask(false); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + screenFramebuffer.bind(); + Globals.renderingEngine.setActiveShader(oitCompositeProgram); + + glBindVertexArray(screenTextureVAO); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE3); + glBindTexture(GL_TEXTURE_2D, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer()); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer()); + + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } static void renderScreenFramebuffer(){ // @@ -855,7 +946,7 @@ public class RenderingEngine { } else if(outputFramebuffer == 4){ glBindTexture(GL_TEXTURE_2D, transparencyAccumulatorTexture.getTexturePointer()); } else if(outputFramebuffer == 5){ - glBindTexture(GL_TEXTURE_2D, transparencyRevealageTexture.getTexturePointer()); + glBindTexture(GL_TEXTURE_2D, gameImageNormalsTexture.getTexturePointer()); } else if(outputFramebuffer == 6){ Globals.renderingEngine.setActiveShader(drawChannel); glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "channel"),0); diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index af539533..d71d5044 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -180,7 +180,7 @@ public class Actor { } } - public void draw(){ + public void draw(boolean setShader){ Model model = Globals.assetManager.fetchModel(modelPath); boolean hasDrawn = false; if(model != null){ @@ -208,11 +208,11 @@ public class Actor { if(overrideTextureObject != null){ overrideTextureObject.bind(); hasDrawn = true; - model.draw(true, true, false, false, true, true, true); + model.draw(setShader, true, false, false, true, true, true); } } if(!hasDrawn){ - model.draw(true, true, false, true, true, true, true); + model.draw(setShader, true, false, true, true, true, true); } model.getShaderMask().clear(); model.setTextureMask(null); diff --git a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java index 490a7682..34b32210 100644 --- a/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java +++ b/src/main/java/electrosphere/renderer/framebuffer/FramebufferUtils.java @@ -114,6 +114,30 @@ public class FramebufferUtils { return buffer; } + public static Framebuffer generateScreenTextureFramebuffer(int width, int height, Texture colorTexture){ + Framebuffer buffer = new Framebuffer(); + buffer.bind(); + //texture + // int texture = glGenTextures(); + // glBindTexture(GL_TEXTURE_2D,texture); + // glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + // //these make sure the texture actually clamps to the borders of the quad + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + // glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + buffer.setTexturePointer(colorTexture.getTexturePointer()); + //bind texture to fbo + int mipMapLevel = 0; + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture.getTexturePointer(), mipMapLevel); + //check make sure compiled + if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){ + System.out.println("Framebuffer is not complete!"); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + return buffer; + } + public static Framebuffer generateScreensizeTextureFramebuffer(){ Framebuffer buffer = new Framebuffer(); buffer.bind();