From 0594bc09537a6c92c0f537b12f1d7ea361f43402 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 26 Apr 2012 09:06:45 +0000 Subject: [PATCH] Point lights now fully functional with deferred lighting --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4054 --- KREngine/KREngine.xcodeproj/project.pbxproj | 8 + KREngine/KREngine/Classes/KRCamera.cpp | 5 +- .../KREngine/Classes/KRDirectionalLight.cpp | 47 +++- .../KREngine/Classes/KRDirectionalLight.h | 4 +- KREngine/KREngine/Classes/KREngine.h | 12 +- KREngine/KREngine/Classes/KREngine.mm | 17 ++ KREngine/KREngine/Classes/KRLight.h | 2 + KREngine/KREngine/Classes/KRMat4.cpp | 16 +- KREngine/KREngine/Classes/KRNode.cpp | 4 + KREngine/KREngine/Classes/KRNode.h | 1 + KREngine/KREngine/Classes/KRPointLight.cpp | 248 +++++++++++++++++- KREngine/KREngine/Classes/KRPointLight.h | 15 ++ KREngine/KREngine/Classes/KRScene.cpp | 2 +- KREngine/KREngine/Classes/KRShader.cpp | 24 +- KREngine/KREngine/Classes/KRShader.h | 17 +- KREngine/KREngine/Classes/KRVector3.cpp | 6 + KREngine/KREngine/Classes/KRVector3.h | 1 + KREngine/KREngine/Shaders/ObjectShader.fsh | 5 +- KREngine/KREngine/Shaders/ObjectShader.vsh | 18 +- .../KREngine/Shaders/light_directional.fsh | 17 +- KREngine/KREngine/Shaders/light_point.fsh | 74 ++++++ KREngine/KREngine/Shaders/light_point.vsh | 35 +++ objview/Classes/KRObjViewGLView.mm | 4 +- objview/Classes/KRObjViewViewController.mm | 2 +- objview/KRObjView.xcodeproj/project.pbxproj | 10 + 25 files changed, 541 insertions(+), 53 deletions(-) create mode 100644 KREngine/KREngine/Shaders/light_point.fsh create mode 100644 KREngine/KREngine/Shaders/light_point.vsh diff --git a/KREngine/KREngine.xcodeproj/project.pbxproj b/KREngine/KREngine.xcodeproj/project.pbxproj index 6de74e9..f064bfb 100644 --- a/KREngine/KREngine.xcodeproj/project.pbxproj +++ b/KREngine/KREngine.xcodeproj/project.pbxproj @@ -83,6 +83,8 @@ E497B95D151BF05F00D3DC67 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E497B95C151BF05F00D3DC67 /* CoreServices.framework */; }; E497B95F151BF09600D3DC67 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E497B95E151BF09600D3DC67 /* SystemConfiguration.framework */; }; E49E79FF1512615F009CF99C /* KRMesh.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E49E79FE1512615F009CF99C /* KRMesh.cpp */; }; + E4A9DEBE154120C4009DF363 /* light_point.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E4A9DEBD154120C4009DF363 /* light_point.fsh */; }; + E4A9DEC1154120E8009DF363 /* light_point.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4A9DEC0154120E8009DF363 /* light_point.vsh */; }; E4B2A4391523B027004CB0EC /* KRMaterial.h in Headers */ = {isa = PBXBuildFile; fileRef = E491017D13C99BDC0098455B /* KRMaterial.h */; settings = {ATTRIBUTES = (Public, ); }; }; E4B2A43B1523B02E004CB0EC /* KRMaterial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E491017C13C99BDC0098455B /* KRMaterial.cpp */; }; E4BBBB8A1512A40300F43B5B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E4BBBB881512A40300F43B5B /* InfoPlist.strings */; }; @@ -204,6 +206,8 @@ E497B95E151BF09600D3DC67 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/SystemConfiguration.framework; sourceTree = DEVELOPER_DIR; }; E49E79FC15126146009CF99C /* KRMesh.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; name = KRMesh.h; path = Classes/KRMesh.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; E49E79FE1512615F009CF99C /* KRMesh.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = KRMesh.cpp; path = Classes/KRMesh.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; + E4A9DEBD154120C4009DF363 /* light_point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.fsh; path = Shaders/light_point.fsh; sourceTree = ""; }; + E4A9DEC0154120E8009DF363 /* light_point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.vsh; path = Shaders/light_point.vsh; sourceTree = ""; }; E4BBBB7E1512A40300F43B5B /* krengine_osx.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = krengine_osx.framework; sourceTree = BUILT_PRODUCTS_DIR; }; E4BBBB871512A40300F43B5B /* krengine_osx-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "krengine_osx-Info.plist"; sourceTree = ""; }; E4BBBB891512A40300F43B5B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -260,6 +264,8 @@ E45772F613C9A13C0037BEEA /* PostShader.vsh */, E4D133B91538F7480070068C /* light_directional.fsh */, E4D133BB1538F7560070068C /* light_directional.vsh */, + E4A9DEBD154120C4009DF363 /* light_point.fsh */, + E4A9DEC0154120E8009DF363 /* light_point.vsh */, ); name = Shaders; sourceTree = ""; @@ -650,6 +656,8 @@ E48C697215374F7E00232E28 /* KRContext.cpp in Sources */, E4D133BA1538F7480070068C /* light_directional.fsh in Sources */, E4D133BC1538F7560070068C /* light_directional.vsh in Sources */, + E4A9DEBE154120C4009DF363 /* light_point.fsh in Sources */, + E4A9DEC1154120E8009DF363 /* light_point.vsh in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index 66d4c59..cf01efe 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -36,6 +36,7 @@ KRCamera::KRCamera() { double const PI = 3.141592653589793f; + double const D2R = PI * 2 / 360; bShowShadowBuffer = false; bEnablePerPixel = true; @@ -59,8 +60,8 @@ KRCamera::KRCamera() { dSunG = 1.0f; dSunB = 1.0f; - perspective_fov = PI / 8.0; - perspective_nearz = 0.25f; + perspective_fov = 45.0 * D2R; + perspective_nearz = 5.0f; perspective_farz = 100.0f; dof_quality = 0; diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index 37994a7..1119ab8 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -27,8 +27,8 @@ std::string KRDirectionalLight::getElementName() { return "directional_light"; } -KRVector3 KRDirectionalLight::getLightDirection() { - KRVector3 world_rotation = getWorldRotation(); +KRVector3 KRDirectionalLight::getWorldLightDirection() { + KRVector3 world_rotation = getLocalRotation(); KRVector3 light_rotation = KRVector3(0.0, 0.0, 1.0); KRMat4 m; m.rotate(world_rotation.x, X_AXIS); @@ -38,6 +38,10 @@ KRVector3 KRDirectionalLight::getLightDirection() { return light_direction; } +KRVector3 KRDirectionalLight::getLocalLightDirection() { + return KRVector3(0.0, 0.0, 1.0); +} + #if TARGET_OS_IPHONE void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, bool bRenderShadowMap, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, int gBufferPass) { @@ -52,19 +56,39 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundi matModelToView.transpose(); matModelToView.invert(); - KRVector3 light_direction = getLightDirection(); - light_direction = matModelToView.dot(light_direction); - light_direction.normalize(); + KRVector3 light_direction_view_space = getWorldLightDirection(); + light_direction_view_space = matModelToView.dot(light_direction_view_space); + light_direction_view_space.normalize(); KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, gBufferPass); - pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, light_direction, pShadowMatrices, shadowDepthTextures, 0, gBufferPass); + pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, gBufferPass); + + glUniform3f( - pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR], - m_color.x * m_intensity / 100.0f, - m_color.y * m_intensity / 100.0f, - m_color.z * m_intensity / 100.0f + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE], + light_direction_view_space.x, + light_direction_view_space.y, + light_direction_view_space.z ); + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR], + m_color.x, + m_color.y, + m_color.z + ); + + glUniform1f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY], + m_intensity / 100.0f + ); + + // Disable z-buffer write + glDepthMask(GL_FALSE); + + // Disable z-buffer test + glDisable(GL_DEPTH_TEST); + // Render a full screen quad static const GLfloat squareVertices[] = { -1.0f, -1.0f, @@ -73,9 +97,6 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundi 1.0f, 1.0f, }; - // Disable z-buffer test - glDisable(GL_DEPTH_TEST); - glBindBuffer(GL_ARRAY_BUFFER, 0); glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices); glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.h b/KREngine/KREngine/Classes/KRDirectionalLight.h index 660a9ac..73dbf64 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.h +++ b/KREngine/KREngine/Classes/KRDirectionalLight.h @@ -15,11 +15,13 @@ class KRDirectionalLight : public KRLight { public: + KRDirectionalLight(std::string name); virtual ~KRDirectionalLight(); virtual std::string getElementName(); - KRVector3 getLightDirection(); + KRVector3 getLocalLightDirection(); + KRVector3 getWorldLightDirection(); #if TARGET_OS_IPHONE diff --git a/KREngine/KREngine/Classes/KREngine.h b/KREngine/KREngine/Classes/KREngine.h index 1af1d74..82f22ff 100644 --- a/KREngine/KREngine/Classes/KREngine.h +++ b/KREngine/KREngine/Classes/KREngine.h @@ -65,13 +65,23 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F KRENGINE_UNIFORM_MATERIAL_AMBIENT, KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRENGINE_UNIFORM_MATERIAL_SPECULAR, + KRENGINE_UNIFORM_LIGHT_POSITION, + KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE, + KRENGINE_UNIFORM_LIGHT_DIRECTION, + KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, KRENGINE_UNIFORM_LIGHT_COLOR, + KRENGINE_UNIFORM_LIGHT_DECAY_START, + KRENGINE_UNIFORM_LIGHT_CUTOFF, + KRENGINE_UNIFORM_LIGHT_INTENSITY, KRENGINE_UNIFORM_MVP, + KRENGINE_UNIFORM_INVP, + KRENGINE_UNIFORM_MN2V, KRENGINE_UNIFORM_M2V, + KRENGINE_UNIFORM_V2M, KRENGINE_UNIFORM_SHADOWMVP1, KRENGINE_UNIFORM_SHADOWMVP2, KRENGINE_UNIFORM_SHADOWMVP3, - KRENGINE_UNIFORM_LIGHTDIRECTION, + KRENGINE_UNIFORM_CAMERAPOS, KRENGINE_UNIFORM_VIEWPORT, KRENGINE_NUM_UNIFORMS diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index 12ce04c..6d6de93 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -151,6 +151,8 @@ double const PI = 3.141592653589793f; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); // This is necessary for non-power-of-two textures glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); // This is necessary for non-power-of-two textures glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + //glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, backingWidth, backingHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); + //glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, backingWidth, backingHeight); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, compositeDepthTexture, 0); @@ -376,6 +378,9 @@ double const PI = 3.141592653589793f; glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + // Enable z-buffer write + glDepthMask(GL_TRUE); + // Enable z-buffer test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); @@ -398,6 +403,9 @@ double const PI = 3.141592653589793f; glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE); + // Disable z-buffer write + glDepthMask(GL_FALSE); + // Set source to buffers from pass 1 glActiveTexture(GL_TEXTURE6); glBindTexture(GL_TEXTURE_2D, compositeColorTexture); @@ -432,6 +440,9 @@ double const PI = 3.141592653589793f; glDepthFunc(GL_LEQUAL); glDepthRangef(0.0, 1.0); + // Enable z-buffer write + glDepthMask(GL_TRUE); + // Render the geometry pScene->render(&m_camera, m_pContext, frustrumVolume, false, viewMatrix, cameraPosition, lightDirection, shadowmvpmatrix, shadowDepthTexture, m_cShadowBuffers, 3); @@ -457,6 +468,9 @@ double const PI = 3.141592653589793f; glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + // Enable z-buffer write + glDepthMask(GL_TRUE); + // Enable z-buffer test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); @@ -477,6 +491,9 @@ double const PI = 3.141592653589793f; glCullFace(GL_BACK); glEnable(GL_CULL_FACE); + // Enable z-buffer write + glDepthMask(GL_TRUE); + // Enable z-buffer test glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); diff --git a/KREngine/KREngine/Classes/KRLight.h b/KREngine/KREngine/Classes/KRLight.h index 3f08ea2..edf014c 100644 --- a/KREngine/KREngine/Classes/KRLight.h +++ b/KREngine/KREngine/Classes/KRLight.h @@ -14,6 +14,8 @@ class KRLight : public KRNode { public: + static const float KRLIGHT_MIN_INFLUENCE = 0.10f; + virtual ~KRLight(); virtual std::string getElementName() = 0; virtual tinyxml2::XMLElement *saveXML( tinyxml2::XMLNode *parent); diff --git a/KREngine/KREngine/Classes/KRMat4.cpp b/KREngine/KREngine/Classes/KRMat4.cpp index d2e451a..d790ed2 100644 --- a/KREngine/KREngine/Classes/KRMat4.cpp +++ b/KREngine/KREngine/Classes/KRMat4.cpp @@ -108,16 +108,26 @@ KRMat4 KRMat4::operator*(const KRMat4 &m) { /* Generate a perspective view matrix using a field of view angle fov, * window aspect ratio, near and far clipping planes */ void KRMat4::perspective(GLfloat fov, GLfloat aspect, GLfloat nearz, GLfloat farz) { - GLfloat range; - - range = tan(fov / 2.0f) * nearz; + memset(m_mat, 0, sizeof(GLfloat) * 16); + + GLfloat range= tan(fov / 2.0f) * nearz; m_mat[0] = (2 * nearz) / ((range * aspect) - (-range * aspect)); m_mat[5] = (2 * nearz) / (2 * range); m_mat[10] = -(farz + nearz) / (farz - nearz); m_mat[11] = -1; m_mat[14] = -(2 * farz * nearz) / (farz - nearz); + /* + GLfloat range= atan(fov / 20.0f) * nearz; + GLfloat r = range * aspect; + GLfloat t = range * 1.0; + m_mat[0] = nearz / r; + m_mat[5] = nearz / t; + m_mat[10] = -(farz + nearz) / (farz - nearz); + m_mat[11] = -(2.0 * farz * nearz) / (farz - nearz); + m_mat[14] = -1.0; + */ } /* Perform translation operations on a matrix */ diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index d8c85b1..d2ab5a8 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -194,3 +194,7 @@ void KRNode::calcExtents(KRContext *pContext) { const std::vector &KRNode::getChildren() { return m_childNodes; } + +const std::string &KRNode::getName() { + return m_name; +} \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index 6cbdc78..fe4c5c2 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -32,6 +32,7 @@ public: virtual void loadXML(tinyxml2::XMLElement *e); virtual std::string getElementName(); + const std::string &getName(); void addChild(KRNode *child); const std::vector &getChildren(); diff --git a/KREngine/KREngine/Classes/KRPointLight.cpp b/KREngine/KREngine/Classes/KRPointLight.cpp index 8d5a5cd..b0c4516 100644 --- a/KREngine/KREngine/Classes/KRPointLight.cpp +++ b/KREngine/KREngine/Classes/KRPointLight.cpp @@ -9,17 +9,261 @@ #include #import "KRPointLight.h" +#import "KRMat4.h" +#import "KRVector3.h" +#import "KRCamera.h" +#import "KRContext.h" +#import "KRBoundingVolume.h" KRPointLight::KRPointLight(std::string name) : KRLight(name) { - + m_sphereVertices = NULL; + m_cVertices = 0; } KRPointLight::~KRPointLight() { - + if(m_sphereVertices) { + delete m_sphereVertices; + m_cVertices = 0; + } } std::string KRPointLight::getElementName() { return "point_light"; } + +#if TARGET_OS_IPHONE + +void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &frustrumVolume, bool bRenderShadowMap, KRMat4 &viewMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, int gBufferPass) { + + if(gBufferPass == 2) { + // Lights are rendered on the second pass of the deferred renderer + + KRMat4 projectionMatrix = pCamera->getProjectionMatrix(); + KRVector3 light_position = getLocalTranslation(); + + float influence_radius = sqrt((m_intensity / 100.0) / KRLIGHT_MIN_INFLUENCE - 1.0) + m_decayStart; + + m_modelMatrix = KRMat4(); + m_modelMatrix.scale(influence_radius); + m_modelMatrix.translate(light_position.x, light_position.y, light_position.z); + + + KRMat4 mvpmatrix = m_modelMatrix * viewMatrix * projectionMatrix; + KRMat4 matModelToView = viewMatrix * m_modelMatrix; + matModelToView.transpose(); + matModelToView.invert(); + + KRMat4 matModelToView2 = KRMat4() * m_modelMatrix * viewMatrix; + + KRMat4 matViewToModel = m_modelMatrix * viewMatrix; + matViewToModel.invert(); + + KRVector3 view_space_light_position = matModelToView2.dot(KRVector3(0.0)); // Origin point of model space is the light source position. No perspective, so no w divide required + + KRBoundingVolume influence_extents = KRBoundingVolume(KRVector3(-1.0), KRVector3(1.0), m_modelMatrix); + + KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewMatrix, pCamera->perspective_fov, pCamera->m_viewportSize.x / pCamera->m_viewportSize.y, 0.0, pCamera->perspective_farz); + + if(influence_extents.test_intersect(frustrumVolumeNoNearClip)) { + // Cull out any lights not within the view frustrum + + KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, false, false, false, false, false, false, false, gBufferPass); + pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, gBufferPass); + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR], + m_color.x, + m_color.y, + m_color.z + ); + + glUniform1f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_INTENSITY], + m_intensity / 100.0f + ); + + glUniform1f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_DECAY_START], + getDecayStart() + ); + + glUniform1f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_CUTOFF], + KRLIGHT_MIN_INFLUENCE + ); + + + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION], + light_position.x, + light_position.y, + light_position.z + ); + + glUniform3f( + pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE], + view_space_light_position.x, + view_space_light_position.y, + view_space_light_position.z + ); + + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_V2M], 1, GL_FALSE, matViewToModel.getPointer()); + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_M2V], 1, GL_FALSE, matModelToView2.getPointer()); + + + KRMat4 matInvProjection; + matInvProjection = pCamera->getProjectionMatrix(); + matInvProjection.invert(); + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_INVP], 1, GL_FALSE, matInvProjection.getPointer()); + + + // Disable z-buffer write + glDepthMask(GL_FALSE); + + //if(view_space_light_position.GetMagnitude() > influence_radius) { + // Render sphere of light's influence + generateMesh(); + + // Enable z-buffer test + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LEQUAL); + glDepthRangef(0.0, 1.0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, m_sphereVertices); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); + glDrawArrays(GL_TRIANGLES, 0, m_cVertices); + /* + } else { + // Sphere would be clipped against view frustrum. Fall back to a full screen quad + + // Disable z-buffer test + glDisable(GL_DEPTH_TEST); + + // Render a full screen quad + static const GLfloat squareVertices[] = { + -1.0f, -1.0f, 0.0f, + 1.0f, -1.0f, 0.0f, + -1.0f, 1.0f, 0.0f, + 1.0f, 1.0f, 0.0f, + }; + + KRMat4 matIdentity; + glUniformMatrix4fv(pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_MVP], 1, GL_FALSE, matIdentity.getPointer()); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glVertexAttribPointer(KRShader::KRENGINE_ATTRIB_VERTEX, 3, GL_FLOAT, 0, 0, squareVertices); + glEnableVertexAttribArray(KRShader::KRENGINE_ATTRIB_VERTEX); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + */ + } + } + + KRNode::render(pCamera, pContext, frustrumVolume, bRenderShadowMap, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, gBufferPass); +} + +void KRPointLight::generateMesh() { + // Create a triangular facet approximation to a sphere + // Based on algorithm from Paul Bourke: http://paulbourke.net/miscellaneous/sphere_cylinder/ + + int iterations = 3; + int facet_count = pow(4, iterations) * 8; + + if(m_cVertices != facet_count * 3) { + if(m_sphereVertices) { + free(m_sphereVertices); + m_sphereVertices = NULL; + } + + m_cVertices = facet_count * 3; + + + class Facet3 { + public: + Facet3() { + + } + ~Facet3() { + + } + KRVector3 p1; + KRVector3 p2; + KRVector3 p3; + }; + + std::vector f = std::vector(facet_count); + + int i,it; + double a; + KRVector3 p[6] = { + KRVector3(0,0,1), + KRVector3(0,0,-1), + KRVector3(-1,-1,0), + KRVector3(1,-1,0), + KRVector3(1,1,0), + KRVector3(-1,1,0) + }; + + KRVector3 pa,pb,pc; + int nt = 0,ntold; + + /* Create the level 0 object */ + a = 1 / sqrt(2.0); + for (i=0;i<6;i++) { + p[i].x *= a; + p[i].y *= a; + } + f[0].p1 = p[0]; f[0].p2 = p[3]; f[0].p3 = p[4]; + f[1].p1 = p[0]; f[1].p2 = p[4]; f[1].p3 = p[5]; + f[2].p1 = p[0]; f[2].p2 = p[5]; f[2].p3 = p[2]; + f[3].p1 = p[0]; f[3].p2 = p[2]; f[3].p3 = p[3]; + f[4].p1 = p[1]; f[4].p2 = p[4]; f[4].p3 = p[3]; + f[5].p1 = p[1]; f[5].p2 = p[5]; f[5].p3 = p[4]; + f[6].p1 = p[1]; f[6].p2 = p[2]; f[6].p3 = p[5]; + f[7].p1 = p[1]; f[7].p2 = p[3]; f[7].p3 = p[2]; + nt = 8; + + /* Bisect each edge and move to the surface of a unit sphere */ + for (it=0;itgetLightDirection(); + forward_render_light_direction = directional_light->getWorldLightDirection(); KRVector3 sun_color = directional_light->getColor() * (directional_light->getIntensity() / 100.0f); pCamera->dSunR = sun_color.x; pCamera->dSunG = sun_color.y; diff --git a/KREngine/KREngine/Classes/KRShader.cpp b/KREngine/KREngine/Classes/KRShader.cpp index 98a4fb6..b969550 100644 --- a/KREngine/KREngine/Classes/KRShader.cpp +++ b/KREngine/KREngine/Classes/KRShader.cpp @@ -67,7 +67,7 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc glGetShaderiv(fragShader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 0) { GLchar *log = (GLchar *)malloc(logLength); - glGetShaderInfoLog(vertexShader, logLength, &logLength, log); + glGetShaderInfoLog(fragShader, logLength, &logLength, log); fprintf(stderr, "KREngine - Failed to compile fragment shader: %s\nShader compile log:\n%s", szKey, log); free(log); } @@ -104,17 +104,31 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc m_uniforms[KRENGINE_UNIFORM_MATERIAL_AMBIENT] = glGetUniformLocation(m_iProgram, "material_ambient"); m_uniforms[KRENGINE_UNIFORM_MATERIAL_DIFFUSE] = glGetUniformLocation(m_iProgram, "material_diffuse"); m_uniforms[KRENGINE_UNIFORM_MATERIAL_SPECULAR] = glGetUniformLocation(m_iProgram, "material_specular"); + + m_uniforms[KRENGINE_UNIFORM_LIGHT_POSITION] = glGetUniformLocation(m_iProgram, "light_position"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "view_space_light_position"); m_uniforms[KRENGINE_UNIFORM_LIGHT_COLOR] = glGetUniformLocation(m_iProgram, "light_color"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_INTENSITY] = glGetUniformLocation(m_iProgram, "light_intensity"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_DECAY_START] = glGetUniformLocation(m_iProgram, "light_decay_start"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_CUTOFF] = glGetUniformLocation(m_iProgram, "light_cutoff"); + + + m_uniforms[KRENGINE_UNIFORM_MATERIAL_ALPHA] = glGetUniformLocation(m_iProgram, "material_alpha"); m_uniforms[KRENGINE_UNIFORM_MATERIAL_SHININESS] = glGetUniformLocation(m_iProgram, "material_shininess"); m_uniforms[KRENGINE_UNIFORM_MVP] = glGetUniformLocation(m_iProgram, "mvp_matrix"); + m_uniforms[KRENGINE_UNIFORM_INVP] = glGetUniformLocation(m_iProgram, "inv_projection_matrix"); + + m_uniforms[KRENGINE_UNIFORM_MN2V] = glGetUniformLocation(m_iProgram, "model_normal_to_view_matrix"); m_uniforms[KRENGINE_UNIFORM_M2V] = glGetUniformLocation(m_iProgram, "model_to_view_matrix"); + m_uniforms[KRENGINE_UNIFORM_V2M] = glGetUniformLocation(m_iProgram, "view_to_model_matrix"); m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_iProgram, "shadow_mvp1"); m_uniforms[KRENGINE_UNIFORM_SHADOWMVP2] = glGetUniformLocation(m_iProgram, "shadow_mvp2"); m_uniforms[KRENGINE_UNIFORM_SHADOWMVP3] = glGetUniformLocation(m_iProgram, "shadow_mvp3"); - m_uniforms[KRENGINE_UNIFORM_LIGHTDIRECTION] = glGetUniformLocation(m_iProgram, "lightDirection"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION] = glGetUniformLocation(m_iProgram, "light_direction"); + m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_view_space"); m_uniforms[KRENGINE_UNIFORM_CAMERAPOS] = glGetUniformLocation(m_iProgram, "cameraPosition"); m_uniforms[KRENGINE_UNIFORM_VIEWPORT] = glGetUniformLocation(m_iProgram, "viewport"); @@ -173,18 +187,18 @@ KRShader::~KRShader() { void KRShader::bind(KRCamera *pCamera, KRMat4 &matModelToView, KRMat4 &mvpMatrix, KRVector3 &cameraPosition, KRVector3 &lightDirection, KRMat4 *pShadowMatrices, GLuint *shadowDepthTextures, int cShadowBuffers, int gBufferPass) { glUseProgram(m_iProgram); - // Bind our modelmatrix variable to be a uniform called mvpmatrix in our shaderprogram glUniformMatrix4fv(m_uniforms[KRENGINE_UNIFORM_MVP], 1, GL_FALSE, mvpMatrix.getPointer()); - glUniformMatrix4fv(m_uniforms[KRENGINE_UNIFORM_M2V], 1, GL_FALSE, matModelToView.getPointer()); + glUniformMatrix4fv(m_uniforms[KRENGINE_UNIFORM_MN2V], 1, GL_FALSE, matModelToView.getPointer()); + KRVector3 nLightDir = lightDirection; nLightDir.normalize(); // Bind the light direction vector glUniform3f( - m_uniforms[KRENGINE_UNIFORM_LIGHTDIRECTION], + m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION], (GLfloat)nLightDir.x, (GLfloat)nLightDir.y, (GLfloat)nLightDir.z diff --git a/KREngine/KREngine/Classes/KRShader.h b/KREngine/KREngine/Classes/KRShader.h index 527cf1d..822daab 100644 --- a/KREngine/KREngine/Classes/KRShader.h +++ b/KREngine/KREngine/Classes/KRShader.h @@ -70,12 +70,25 @@ public: KRENGINE_UNIFORM_MATERIAL_AMBIENT, KRENGINE_UNIFORM_MATERIAL_DIFFUSE, KRENGINE_UNIFORM_MATERIAL_SPECULAR, - KRENGINE_UNIFORM_LIGHT_COLOR, KRENGINE_UNIFORM_MATERIAL_ALPHA, KRENGINE_UNIFORM_MATERIAL_SHININESS, + + KRENGINE_UNIFORM_LIGHT_POSITION, + KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE, + KRENGINE_UNIFORM_LIGHT_DIRECTION, + KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE, + KRENGINE_UNIFORM_LIGHT_COLOR, + KRENGINE_UNIFORM_LIGHT_DECAY_START, + KRENGINE_UNIFORM_LIGHT_CUTOFF, + KRENGINE_UNIFORM_LIGHT_INTENSITY, + + KRENGINE_UNIFORM_MVP, + KRENGINE_UNIFORM_INVP, + KRENGINE_UNIFORM_MN2V, KRENGINE_UNIFORM_M2V, - KRENGINE_UNIFORM_LIGHTDIRECTION, + KRENGINE_UNIFORM_V2M, + KRENGINE_UNIFORM_CAMERAPOS, KRENGINE_UNIFORM_VIEWPORT, KRENGINE_UNIFORM_DIFFUSETEXTURE, diff --git a/KREngine/KREngine/Classes/KRVector3.cpp b/KREngine/KREngine/Classes/KRVector3.cpp index a2b20ed..d58ead7 100644 --- a/KREngine/KREngine/Classes/KRVector3.cpp +++ b/KREngine/KREngine/Classes/KRVector3.cpp @@ -39,6 +39,12 @@ KRVector3::KRVector3() z = 0.0f; } +KRVector3::KRVector3(float v) { + x = v; + y = v; + z = v; +} + KRVector3::KRVector3(float X, float Y, float Z) { x = X; diff --git a/KREngine/KREngine/Classes/KRVector3.h b/KREngine/KREngine/Classes/KRVector3.h index 189538c..4e91a3c 100644 --- a/KREngine/KREngine/Classes/KRVector3.h +++ b/KREngine/KREngine/Classes/KRVector3.h @@ -44,6 +44,7 @@ public: //default constructor KRVector3(float X, float Y, float Z); + KRVector3(float v); KRVector3(); ~KRVector3(); diff --git a/KREngine/KREngine/Shaders/ObjectShader.fsh b/KREngine/KREngine/Shaders/ObjectShader.fsh index 2f38a09..a662911 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.fsh +++ b/KREngine/KREngine/Shaders/ObjectShader.fsh @@ -58,7 +58,7 @@ #if HAS_NORMAL_MAP == 1 varying highp mat3 tangent_to_view_matrix; #else - uniform highp mat4 model_to_view_matrix; + uniform highp mat4 model_normal_to_view_matrix; #endif #else uniform lowp vec3 material_ambient, material_diffuse, material_specular; @@ -136,7 +136,7 @@ void main() mediump vec3 normal = normalize(2.0 * texture2D(normalTexture,normal_uv).rgb - 1.0); mediump vec3 view_space_normal = tangent_to_view_matrix * normal; #else - mediump vec3 view_space_normal = vec3(model_to_view_matrix * vec4(normal, 1.0)); + mediump vec3 view_space_normal = vec3(model_normal_to_view_matrix * vec4(normal, 1.0)); #endif gl_FragColor = vec4(view_space_normal * 0.5 + 0.5, material_shininess / 100.0); #else @@ -255,6 +255,5 @@ void main() mediump vec3 lightMapColor = vec3(texture2D(shadowTexture1, lightmap_uv)); gl_FragColor = vec4(gl_FragColor.r * lightMapColor.r, gl_FragColor.g * lightMapColor.g, gl_FragColor.b * lightMapColor.b, 1.0); #endif - #endif } diff --git a/KREngine/KREngine/Shaders/ObjectShader.vsh b/KREngine/KREngine/Shaders/ObjectShader.vsh index 031d3c5..93bb3d4 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.vsh +++ b/KREngine/KREngine/Shaders/ObjectShader.vsh @@ -61,12 +61,12 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t #if GBUFFER_PASS == 1 #if HAS_NORMAL_MAP == 1 - uniform highp mat4 model_to_view_matrix; + uniform highp mat4 model_normal_to_view_matrix; varying highp mat3 tangent_to_view_matrix; #endif #else - uniform highp vec3 lightDirection; // Must be normalized before entering shader + uniform highp vec3 light_direction; // Must be normalized before entering shader uniform highp vec3 cameraPosition; #if HAS_LIGHT_MAP == 1 @@ -154,9 +154,9 @@ void main() #if GBUFFER_PASS == 1 #if HAS_NORMAL_MAP == 1 mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent); - tangent_to_view_matrix[0] = vec3(model_to_view_matrix * vec4(vertex_tangent, 1.0)); - tangent_to_view_matrix[1] = vec3(model_to_view_matrix * vec4(a_bitangent, 1.0)); - tangent_to_view_matrix[2] = vec3(model_to_view_matrix * vec4(vertex_normal, 1.0)); + tangent_to_view_matrix[0] = vec3(model_normal_to_view_matrix * vec4(vertex_tangent, 1.0)); + tangent_to_view_matrix[1] = vec3(model_normal_to_view_matrix * vec4(a_bitangent, 1.0)); + tangent_to_view_matrix[2] = vec3(model_normal_to_view_matrix * vec4(vertex_normal, 1.0)); #else normal = vertex_normal; #endif @@ -211,20 +211,20 @@ void main() mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent); mediump vec3 eyeVec = normalize(cameraPosition - vertex_position); - lightVec = normalize(vec3(dot(lightDirection, vertex_tangent), dot(lightDirection, a_bitangent), dot(lightDirection, vertex_normal))); + lightVec = normalize(vec3(dot(light_direction, vertex_tangent), dot(light_direction, a_bitangent), dot(light_direction, vertex_normal))); halfVec = normalize(vec3(dot(eyeVec, vertex_tangent), dot(eyeVec, a_bitangent), dot(eyeVec, vertex_normal))); halfVec = normalize(halfVec + lightVec); // Normalizing anyways, no need to divide by 2 #else // ------ Calculate per-pixel lighting without normal mapping ------ normal = vertex_normal; - lightVec = lightDirection; + lightVec = light_direction; halfVec = normalize((normalize(cameraPosition - vertex_position) + lightVec)); // Normalizing anyways, no need to divide by 2 #endif #else // ------ Calculate per-vertex lighting ------ - mediump vec3 halfVec = normalize((normalize(cameraPosition - vertex_position) + lightDirection)); // Normalizing anyways, no need to divide by 2 - lamberFactor = max(0.0,dot(lightDirection, vertex_normal)); + mediump vec3 halfVec = normalize((normalize(cameraPosition - vertex_position) + light_direction)); // Normalizing anyways, no need to divide by 2 + lamberFactor = max(0.0,dot(light_direction, vertex_normal)); specularFactor = max(0.0,pow(dot(halfVec,vertex_normal), material_shininess)); #endif #endif diff --git a/KREngine/KREngine/Shaders/light_directional.fsh b/KREngine/KREngine/Shaders/light_directional.fsh index f392fa8..783da45 100644 --- a/KREngine/KREngine/Shaders/light_directional.fsh +++ b/KREngine/KREngine/Shaders/light_directional.fsh @@ -29,8 +29,9 @@ uniform sampler2D gbuffer_frame; uniform sampler2D gbuffer_depth; -uniform mediump vec3 lightDirection; // Must be normalized and converted to view space before entering shader +uniform mediump vec3 light_direction_view_space; // Must be normalized and converted to view space before entering shader uniform lowp vec3 light_color; +uniform highp float light_intensity; uniform mediump vec4 viewport; void main() @@ -41,20 +42,20 @@ void main() mediump vec3 gbuffer_normal = 2.0 * gbuffer_sample.rgb - 1.0; mediump float gbuffer_specular_exponent = gbuffer_sample.a * 100.0; - mediump float lamberFactor = max(0.0,dot(lightDirection, gbuffer_normal)); + mediump float lamberFactor = max(0.0,dot(light_direction_view_space, gbuffer_normal)); - mediump vec3 view_space_vertex_position; - view_space_vertex_position.xy = ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.0; - view_space_vertex_position.z = (2.0 * -texture2D(gbuffer_depth, gbuffer_uv).r - gl_DepthRange.near - gl_DepthRange.far) / - (gl_DepthRange.far - gl_DepthRange.near); + mediump vec3 view_space_vertex_position = vec3( + ((2.0 * gl_FragCoord.xy) - (2.0 * viewport.xy)) / (viewport.zw) - 1.0, + (2.0 * -texture2D(gbuffer_depth, gbuffer_uv).r - gl_DepthRange.near - gl_DepthRange.far) / (gl_DepthRange.far - gl_DepthRange.near) + ); mediump float specularFactor = 0.0; if(gbuffer_specular_exponent > 0.0) { - mediump vec3 halfVec = normalize((normalize(vec3(0.0, 0.0, 0.0) - view_space_vertex_position) + lightDirection)); // Normalizing anyways, no need to divide by 2 + mediump vec3 halfVec = normalize((normalize(- view_space_vertex_position) + light_direction_view_space)); // Normalizing anyways, no need to divide by 2 specularFactor = clamp(pow(dot(halfVec,normalize(gbuffer_normal)), gbuffer_specular_exponent), 0.0, 1.0); } - gl_FragColor = vec4(light_color * lamberFactor, specularFactor); + gl_FragColor = vec4(light_color * lamberFactor, specularFactor) * light_intensity; } diff --git a/KREngine/KREngine/Shaders/light_point.fsh b/KREngine/KREngine/Shaders/light_point.fsh new file mode 100644 index 0000000..832b54a --- /dev/null +++ b/KREngine/KREngine/Shaders/light_point.fsh @@ -0,0 +1,74 @@ +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + + +uniform sampler2D gbuffer_frame; +uniform sampler2D gbuffer_depth; + +uniform lowp vec3 light_color; +uniform highp float light_intensity; +uniform highp float light_decay_start; +uniform highp float light_cutoff; +uniform mediump vec4 viewport; + +uniform highp mat4 inv_projection_matrix; + +uniform highp vec3 view_space_light_position; + +void main() +{ + + mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); + lowp vec4 gbuffer_sample = texture2D(gbuffer_frame, gbuffer_uv); + + mediump vec3 gbuffer_normal = 2.0 * gbuffer_sample.rgb - 1.0; + mediump float gbuffer_specular_exponent = gbuffer_sample.a * 100.0; + + mediump vec4 clip_space_vertex_position = vec4( + gl_FragCoord.xy / viewport.zw * 2.0 - 1.0, + texture2D(gbuffer_depth, gbuffer_uv).r * 2.0 - 1.0, + 1.0 + ); + + + mediump vec4 view_space_vertex_position = inv_projection_matrix * clip_space_vertex_position; + view_space_vertex_position.xyz /= view_space_vertex_position.w; + + mediump float light_distance = max(0.0, distance(view_space_light_position.xyz, view_space_vertex_position.xyz) - light_decay_start); + mediump float light_attenuation = (light_intensity / ((light_distance + 1.0) * (light_distance + 1.0)) - light_cutoff) / (1.0 - light_cutoff); + mediump vec3 light_vec = normalize(view_space_light_position.xyz - view_space_vertex_position.xyz); + mediump float lamberFactor = clamp(dot(light_vec, gbuffer_normal), 0.0, 1.0); + + mediump float specularFactor = 0.0; + if(gbuffer_specular_exponent > 0.0) { + mediump vec3 halfVec = normalize((normalize(- view_space_vertex_position.xyz) + light_vec)); + specularFactor = clamp(pow(dot(halfVec,normalize(gbuffer_normal)), gbuffer_specular_exponent), 0.0, 1.0); + } + + + gl_FragColor = vec4(light_color * lamberFactor, specularFactor) * light_attenuation; +} diff --git a/KREngine/KREngine/Shaders/light_point.vsh b/KREngine/KREngine/Shaders/light_point.vsh new file mode 100644 index 0000000..84ef213 --- /dev/null +++ b/KREngine/KREngine/Shaders/light_point.vsh @@ -0,0 +1,35 @@ +// Copyright 2012 Kearwood Gilbert. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other materials +// provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY KEARWOOD GILBERT ''AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KEARWOOD GILBERT OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// The views and conclusions contained in the software and documentation are those of the +// authors and should not be interpreted as representing official policies, either expressed +// or implied, of Kearwood Gilbert. +// + +attribute vec4 vertex_position; +uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying the model, view, and projection matrices + +void main() +{ + gl_Position = mvp_matrix * vertex_position; + gl_Position.z = max(gl_Position.z / gl_Position.w, 0.0) * gl_Position.w; +} \ No newline at end of file diff --git a/objview/Classes/KRObjViewGLView.mm b/objview/Classes/KRObjViewGLView.mm index 4e2b5fc..d2db7d7 100644 --- a/objview/Classes/KRObjViewGLView.mm +++ b/objview/Classes/KRObjViewGLView.mm @@ -108,8 +108,8 @@ [renderEngine loadResource: path]; } - [renderEngine setNearZ: 25.0]; - [renderEngine setFarZ: 5000.0]; + [renderEngine setNearZ: 100.0]; + [renderEngine setFarZ: 3000.0]; return TRUE; } diff --git a/objview/Classes/KRObjViewViewController.mm b/objview/Classes/KRObjViewViewController.mm index 65bc69c..04d6639 100644 --- a/objview/Classes/KRObjViewViewController.mm +++ b/objview/Classes/KRObjViewViewController.mm @@ -263,7 +263,7 @@ double frameTime = CACurrentMediaTime() - frame_start_time; - NSLog(@"frameTime = %.1f ms (%.2f fps / %.2f fps) - %.2f%%", frameTime * 1000.0f, 1.0f / frameTime, 1.0f / deltaTime, frameTime / deltaTime * 100.0f); + //NSLog(@"frameTime = %.1f ms (%.2f fps / %.2f fps) - %.2f%%", frameTime * 1000.0f, 1.0f / frameTime, 1.0f / deltaTime, frameTime / deltaTime * 100.0f); } @end diff --git a/objview/KRObjView.xcodeproj/project.pbxproj b/objview/KRObjView.xcodeproj/project.pbxproj index 6aaaf73..b12a3ac 100644 --- a/objview/KRObjView.xcodeproj/project.pbxproj +++ b/objview/KRObjView.xcodeproj/project.pbxproj @@ -30,6 +30,9 @@ E46FED3113C9A49F009F5814 /* ObjectShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2513C9A488009F5814 /* ObjectShader.vsh */; }; E46FED3213C9A49F009F5814 /* PostShader.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E46FED2613C9A488009F5814 /* PostShader.vsh */; }; E49EB29C13806C5D00A4E727 /* MainWindow-iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */; }; + E4A9DEC615412906009DF363 /* light_point.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; }; + E4A9DEC715412923009DF363 /* light_point.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC2154128F0009DF363 /* light_point.fsh */; }; + E4A9DEC815412923009DF363 /* light_point.vsh in Resources */ = {isa = PBXBuildFile; fileRef = E4A9DEC515412906009DF363 /* light_point.vsh */; }; E4FF48C21538FBF0002053FC /* light_directional.fsh in Sources */ = {isa = PBXBuildFile; fileRef = E4FF48C01538FBF0002053FC /* light_directional.fsh */; }; E4FF48C31538FBF0002053FC /* light_directional.vsh in Sources */ = {isa = PBXBuildFile; fileRef = E4FF48C11538FBF0002053FC /* light_directional.vsh */; }; E4FF48C51538FBF8002053FC /* light_directional.fsh in Resources */ = {isa = PBXBuildFile; fileRef = E4FF48C01538FBF0002053FC /* light_directional.fsh */; }; @@ -67,6 +70,8 @@ E46FED2513C9A488009F5814 /* ObjectShader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; lineEnding = 0; name = ObjectShader.vsh; path = ../KREngine/KREngine/Shaders/ObjectShader.vsh; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.glsl; }; E46FED2613C9A488009F5814 /* PostShader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = PostShader.vsh; path = ../KREngine/KREngine/Shaders/PostShader.vsh; sourceTree = ""; }; E49EB29B13806C5D00A4E727 /* MainWindow-iPad.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = "MainWindow-iPad.xib"; path = "iPad/MainWindow-iPad.xib"; sourceTree = ""; }; + E4A9DEC2154128F0009DF363 /* light_point.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.fsh; path = ../KREngine/KREngine/Shaders/light_point.fsh; sourceTree = ""; }; + E4A9DEC515412906009DF363 /* light_point.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_point.vsh; path = ../KREngine/KREngine/Shaders/light_point.vsh; sourceTree = ""; }; E4FF48C01538FBF0002053FC /* light_directional.fsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.fsh; path = ../KREngine/KREngine/Shaders/light_directional.fsh; sourceTree = ""; }; E4FF48C11538FBF0002053FC /* light_directional.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = light_directional.vsh; path = ../KREngine/KREngine/Shaders/light_directional.vsh; sourceTree = ""; }; /* End PBXFileReference section */ @@ -182,6 +187,8 @@ E46FED2013C9A472009F5814 /* Shaders */ = { isa = PBXGroup; children = ( + E4A9DEC2154128F0009DF363 /* light_point.fsh */, + E4A9DEC515412906009DF363 /* light_point.vsh */, E4FF48C01538FBF0002053FC /* light_directional.fsh */, E4FF48C11538FBF0002053FC /* light_directional.vsh */, E46FED2113C9A488009F5814 /* ShadowShader.vsh */, @@ -263,6 +270,8 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + E4A9DEC715412923009DF363 /* light_point.fsh in Resources */, + E4A9DEC815412923009DF363 /* light_point.vsh in Resources */, E46FED2D13C9A49F009F5814 /* ShadowShader.vsh in Resources */, E46FED2E13C9A49F009F5814 /* ShadowShader.fsh in Resources */, E46FED2F13C9A49F009F5814 /* PostShader.fsh in Resources */, @@ -291,6 +300,7 @@ 1063FC77136D6A1B00EE555B /* KRObjViewGLView.mm in Sources */, E4FF48C21538FBF0002053FC /* light_directional.fsh in Sources */, E4FF48C31538FBF0002053FC /* light_directional.vsh in Sources */, + E4A9DEC615412906009DF363 /* light_point.vsh in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };