diff --git a/KREngine/KREngine/Classes/KRCamera.cpp b/KREngine/KREngine/Classes/KRCamera.cpp index d938625..30d9b9c 100644 --- a/KREngine/KREngine/Classes/KRCamera.cpp +++ b/KREngine/KREngine/Classes/KRCamera.cpp @@ -31,6 +31,7 @@ #include +#import "KRVector2.h" #import "KRCamera.h" KRCamera::KRCamera() { @@ -47,7 +48,7 @@ KRCamera::KRCamera() { bEnableSpecular = true; bEnableLightMap = true; bDebugSuperShiny = false; - bEnableDeferredLighting = false; + bEnableDeferredLighting = true; dAmbientR = 0.25f; @@ -88,4 +89,12 @@ KRMat4 KRCamera::getProjectionMatrix() { projectionMatrix.perspective(perspective_fov, perspective_aspect, perspective_nearz, perspective_farz); projectionMatrix.rotate(-90 * 0.0174532925199, Z_AXIS); return projectionMatrix; +} + +const KRVector2 &KRCamera::getViewportSize() { + return m_viewportSize; +} + +void KRCamera::setViewportSize(const KRVector2 &size) { + m_viewportSize = size; } \ No newline at end of file diff --git a/KREngine/KREngine/Classes/KRCamera.h b/KREngine/KREngine/Classes/KRCamera.h index 634865c..4bd6f09 100644 --- a/KREngine/KREngine/Classes/KRCamera.h +++ b/KREngine/KREngine/Classes/KRCamera.h @@ -35,6 +35,7 @@ #import "KREngine-common.h" #import "KRMat4.h" +#import "KRVector2.h" class KRCamera { public: @@ -42,6 +43,8 @@ public: ~KRCamera(); KRMat4 getProjectionMatrix(); + const KRVector2 &getViewportSize(); + void setViewportSize(const KRVector2 &size); bool bEnablePerPixel; bool bEnableDiffuseMap; @@ -77,6 +80,8 @@ public: bool bEnableVignette; double vignette_radius; double vignette_falloff; + + KRVector2 m_viewportSize; }; #endif diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.cpp b/KREngine/KREngine/Classes/KRDirectionalLight.cpp index 1ba8e26..6f9f612 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.cpp +++ b/KREngine/KREngine/Classes/KRDirectionalLight.cpp @@ -11,6 +11,7 @@ #import "KRDirectionalLight.h" #import "KRShader.h" #import "KRContext.h" +#import "KRMat4.h" KRDirectionalLight::KRDirectionalLight(std::string name) : KRLight(name) { @@ -26,6 +27,17 @@ std::string KRDirectionalLight::getElementName() { return "directional_light"; } +KRVector3 KRDirectionalLight::getLightDirection() { + KRVector3 world_rotation = getWorldRotation(); + KRVector3 light_rotation = KRVector3(0.0, -1.0, 0.0); + KRMat4 m; + m.rotate(world_rotation.x, X_AXIS); + m.rotate(world_rotation.y, Y_AXIS); + m.rotate(world_rotation.z, Z_AXIS); + KRVector3 light_direction = m.dot(light_rotation); + return light_direction; +} + #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) { @@ -40,9 +52,12 @@ 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(); 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, lightDirection, pShadowMatrices, shadowDepthTextures, 0, gBufferPass); + pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, light_direction, pShadowMatrices, shadowDepthTextures, 0, gBufferPass); // Render a full screen quad diff --git a/KREngine/KREngine/Classes/KRDirectionalLight.h b/KREngine/KREngine/Classes/KRDirectionalLight.h index fc81e9b..660a9ac 100644 --- a/KREngine/KREngine/Classes/KRDirectionalLight.h +++ b/KREngine/KREngine/Classes/KRDirectionalLight.h @@ -19,6 +19,7 @@ public: virtual ~KRDirectionalLight(); virtual std::string getElementName(); + KRVector3 getLightDirection(); #if TARGET_OS_IPHONE diff --git a/KREngine/KREngine/Classes/KREngine.h b/KREngine/KREngine/Classes/KREngine.h index 60e89f2..6082c35 100644 --- a/KREngine/KREngine/Classes/KREngine.h +++ b/KREngine/KREngine/Classes/KREngine.h @@ -72,6 +72,7 @@ typedef enum KREngineParameterType {KRENGINE_PARAMETER_INT, KRENGINE_PARAMETER_F KRENGINE_UNIFORM_SHADOWMVP3, KRENGINE_UNIFORM_LIGHTDIRECTION, KRENGINE_UNIFORM_CAMERAPOS, + KRENGINE_UNIFORM_VIEWPORT, KRENGINE_NUM_UNIFORMS }; GLint m_shadowUniforms[KRENGINE_NUM_UNIFORMS]; diff --git a/KREngine/KREngine/Classes/KREngine.mm b/KREngine/KREngine/Classes/KREngine.mm index fb9d845..9c52636 100644 --- a/KREngine/KREngine/Classes/KREngine.mm +++ b/KREngine/KREngine/Classes/KREngine.mm @@ -350,12 +350,12 @@ double const PI = 3.141592653589793f; KRVector3 lightDirection; KRBoundingVolume shadowVolume = KRBoundingVolume(vertices); pScene->render(&m_camera, m_pContext, shadowVolume, true, shadowmvpmatrix[iShadow], cameraPosition, lightDirection, shadowmvpmatrix, NULL, m_cShadowBuffers, 0); - glViewport(0, 0, 768, 1024); + glViewport(0, 0, backingWidth, backingHeight); } - (void)renderScene: (KRScene *)pScene WithViewMatrix: (KRMat4)viewMatrix LightDirection: (KRVector3)lightDirection CameraPosition: (KRVector3)cameraPosition { - + m_camera.setViewportSize(KRVector2(backingWidth, backingHeight)); diff --git a/KREngine/KREngine/Classes/KRNode.cpp b/KREngine/KREngine/Classes/KRNode.cpp index f8c8e80..d8c85b1 100644 --- a/KREngine/KREngine/Classes/KRNode.cpp +++ b/KREngine/KREngine/Classes/KRNode.cpp @@ -112,6 +112,16 @@ const KRVector3 &KRNode::getLocalRotation() { return m_localRotation; } +const KRVector3 &KRNode::getWorldTranslation() { + return m_localTranslation; +} +const KRVector3 &KRNode::getWorldScale() { + return m_localScale; +} +const KRVector3 &KRNode::getWorldRotation() { + return m_localRotation; +} + std::string KRNode::getElementName() { return "node"; } @@ -180,3 +190,7 @@ void KRNode::calcExtents(KRContext *pContext) { } } } + +const std::vector &KRNode::getChildren() { + return m_childNodes; +} diff --git a/KREngine/KREngine/Classes/KRNode.h b/KREngine/KREngine/Classes/KRNode.h index 9d5b496..6cbdc78 100644 --- a/KREngine/KREngine/Classes/KRNode.h +++ b/KREngine/KREngine/Classes/KRNode.h @@ -34,6 +34,7 @@ public: virtual std::string getElementName(); void addChild(KRNode *child); + const std::vector &getChildren(); void setLocalTranslation(const KRVector3 &v); void setLocalScale(const KRVector3 &v); @@ -43,6 +44,10 @@ public: const KRVector3 &getLocalScale(); const KRVector3 &getLocalRotation(); + const KRVector3 &getWorldTranslation(); + const KRVector3 &getWorldScale(); + const KRVector3 &getWorldRotation(); + void clearExtents(); virtual void calcExtents(KRContext *Context); KRBoundingVolume getExtents(KRContext *pContext); diff --git a/KREngine/KREngine/Classes/KRScene.cpp b/KREngine/KREngine/Classes/KRScene.cpp index 6301073..69a5d41 100644 --- a/KREngine/KREngine/Classes/KRScene.cpp +++ b/KREngine/KREngine/Classes/KRScene.cpp @@ -35,10 +35,12 @@ #import "KRMat4.h" #import "tinyxml2.h" +#import "KRDirectionalLight.h" + #import "KRScene.h" KRScene::KRScene(std::string name) : KRResource(name) { - + m_pFirstDirectionalLight = NULL; m_pRootNode = new KRNode("scene_root"); } KRScene::~KRScene() { @@ -77,7 +79,13 @@ void KRScene::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } - m_pRootNode->render(pCamera, pContext, frustrumVolume, bRenderShadowMap, viewMatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, gBufferPass); + KRVector3 forward_render_light_direction = lightDirection; + KRDirectionalLight *directional_light = getFirstDirectionalLight(); + if(directional_light) { + forward_render_light_direction = directional_light->getLightDirection(); + } + + m_pRootNode->render(pCamera, pContext, frustrumVolume, bRenderShadowMap, viewMatrix, cameraPosition, forward_render_light_direction, pShadowMatrices, shadowDepthTextures, cShadowBuffers, gBufferPass); } #endif @@ -104,6 +112,22 @@ bool KRScene::save(const std::string& path) { } +KRDirectionalLight *KRScene::findFirstDirectionalLight(KRNode &node) { + KRDirectionalLight *pLight = dynamic_cast(&node); + if(pLight) { + return pLight; + } else { + const std::vector children = node.getChildren(); + for(std::vector::const_iterator itr=children.begin(); itr < children.end(); ++itr) { + pLight = findFirstDirectionalLight(*(*itr)); + if(pLight) { + return pLight; + } + } + } + return NULL; +} + KRScene *KRScene::LoadXML(const std::string& path) { tinyxml2::XMLDocument doc; @@ -114,6 +138,13 @@ KRScene *KRScene::LoadXML(const std::string& path) if(n) { new_scene->getRootNode()->addChild(n); } - return new_scene; } + +KRDirectionalLight *KRScene::getFirstDirectionalLight() +{ + if(m_pFirstDirectionalLight == NULL) { + m_pFirstDirectionalLight = findFirstDirectionalLight(*m_pRootNode); + } + return m_pFirstDirectionalLight; +} diff --git a/KREngine/KREngine/Classes/KRScene.h b/KREngine/KREngine/Classes/KRScene.h index 906e93f..74c6c60 100644 --- a/KREngine/KREngine/Classes/KRScene.h +++ b/KREngine/KREngine/Classes/KRScene.h @@ -44,6 +44,7 @@ #import "KRNode.h" class KRBoundingVolume; class KRInstance; +class KRDirectionalLight; using std::vector; @@ -58,6 +59,7 @@ public: static KRScene *LoadXML(const std::string& path); KRNode *getRootNode(); + KRDirectionalLight *getFirstDirectionalLight(); #if TARGET_OS_IPHONE @@ -67,8 +69,11 @@ public: KRBoundingVolume getExtents(KRContext *pContext); private: + KRDirectionalLight *findFirstDirectionalLight(KRNode &node); + KRNode *m_pRootNode; KRBoundingVolume *m_pExtents; + KRDirectionalLight *m_pFirstDirectionalLight; }; diff --git a/KREngine/KREngine/Classes/KRShader.cpp b/KREngine/KREngine/Classes/KRShader.cpp index be2fb35..6fea6b7 100644 --- a/KREngine/KREngine/Classes/KRShader.cpp +++ b/KREngine/KREngine/Classes/KRShader.cpp @@ -114,6 +114,7 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc m_uniforms[KRENGINE_UNIFORM_SHADOWMVP3] = glGetUniformLocation(m_iProgram, "shadow_mvp3"); m_uniforms[KRENGINE_UNIFORM_LIGHTDIRECTION] = glGetUniformLocation(m_iProgram, "lightDirection"); m_uniforms[KRENGINE_UNIFORM_CAMERAPOS] = glGetUniformLocation(m_iProgram, "cameraPosition"); + m_uniforms[KRENGINE_UNIFORM_VIEWPORT] = glGetUniformLocation(m_iProgram, "viewport"); m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE] = glGetUniformLocation(m_iProgram, "diffuseTexture"); m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE] = glGetUniformLocation(m_iProgram, "specularTexture"); @@ -193,6 +194,14 @@ void KRShader::bind(KRCamera *pCamera, KRMat4 &matModelToView, KRMat4 &mvpMatrix (GLfloat)cameraPosition.z ); + glUniform4f( + m_uniforms[KRENGINE_UNIFORM_VIEWPORT], + (GLfloat)0.0, + (GLfloat)0.0, + (GLfloat)pCamera->getViewportSize().x, + (GLfloat)pCamera->getViewportSize().y + ); + // Bind the shadowmap space matrices for(int iShadow=0; iShadow < cShadowBuffers; iShadow++) { glUniformMatrix4fv(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1 + iShadow], 1, GL_FALSE, pShadowMatrices[iShadow].getPointer()); diff --git a/KREngine/KREngine/Classes/KRShader.h b/KREngine/KREngine/Classes/KRShader.h index 9aae1ee..99af4b7 100644 --- a/KREngine/KREngine/Classes/KRShader.h +++ b/KREngine/KREngine/Classes/KRShader.h @@ -72,6 +72,7 @@ public: KRENGINE_UNIFORM_M2V, KRENGINE_UNIFORM_LIGHTDIRECTION, KRENGINE_UNIFORM_CAMERAPOS, + KRENGINE_UNIFORM_VIEWPORT, KRENGINE_UNIFORM_DIFFUSETEXTURE, KRENGINE_UNIFORM_SPECULARTEXTURE, KRENGINE_UNIFORM_NORMALTEXTURE, diff --git a/KREngine/KREngine/Shaders/ObjectShader.fsh b/KREngine/KREngine/Shaders/ObjectShader.fsh index 84b9e0e..8d40c7c 100644 --- a/KREngine/KREngine/Shaders/ObjectShader.fsh +++ b/KREngine/KREngine/Shaders/ObjectShader.fsh @@ -114,10 +114,14 @@ #endif +#if GBUFFER_PASS == 1 || GBUFFER_PASS == 3 +uniform mediump vec4 viewport; +#endif + void main() { #if GBUFFER_PASS == 2 || GBUFFER_PASS == 3 - mediump vec2 gbuffer_uv = vec2(gl_FragCoord.x / 768.0, gl_FragCoord.y / 1024.0); + mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); #endif #if GBUFFER_PASS == 2 @@ -161,7 +165,11 @@ void main() #endif mediump float specularFactor = 0.0; if(material_shininess > 0.0) { - specularFactor = max(0.0,pow(dot(halfVec,normal), material_shininess)); + #if GBUFFER_PASS == 3 + specularFactor = gbuffer_specular_factor; + #else + specularFactor = max(0.0,pow(dot(halfVec,normal), material_shininess)); + #endif } #if SHADOW_QUALITY == 1 @@ -249,5 +257,8 @@ 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 + + //gl_FragColor = vec4(vec3(specularFactor), 1.0); + #endif } diff --git a/KREngine/KREngine/Shaders/light_directional.fsh b/KREngine/KREngine/Shaders/light_directional.fsh index 49878a8..caf3025 100644 --- a/KREngine/KREngine/Shaders/light_directional.fsh +++ b/KREngine/KREngine/Shaders/light_directional.fsh @@ -29,23 +29,47 @@ uniform sampler2D gbuffer_frame; uniform sampler2D gbuffer_depth; -uniform highp vec3 lightDirection; // Must be normalized before entering shader +uniform highp vec3 lightDirection; // Must be normalized and converted to view space before entering shader uniform highp mat4 model_to_view_matrix; +uniform mediump vec4 viewport; void main() { - + + + - mediump vec2 gbuffer_uv = vec2(gl_FragCoord.x / 768.0, gl_FragCoord.y / 1024.0); + mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw); + + highp 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) - 1.0; + */ + view_space_vertex_position.z = -texture2D(gbuffer_depth, gbuffer_uv).r; + lowp vec4 gbuffer_sample = texture2D(gbuffer_frame, gbuffer_uv); - mediump vec3 gbuffer_normal = normalize(2.0 * gbuffer_sample.rgb - 1.0); - mediump float gbuffer_specular_exponent = gbuffer_sample.a; + mediump vec3 gbuffer_normal = 2.0 * gbuffer_sample.rgb - 1.0; + mediump float gbuffer_specular_exponent = gbuffer_sample.a * 100.0; + + mediump vec3 view_space_light = lightDirection; // vec3(model_to_view_matrix * vec4(lightDirection, 1.0)); - mediump vec3 view_space_light = vec3(model_to_view_matrix * vec4(lightDirection, 1.0)); mediump float lamberFactor = max(0.0,dot(view_space_light, gbuffer_normal)); - - gl_FragColor = vec4(vec3(lamberFactor), 0.0); + + + + highp vec3 halfVec = normalize((normalize(vec3(0.0, 0.0, 0.0) - view_space_vertex_position) + view_space_light)); // Normalizing anyways, no need to divide by 2 + + //highp vec3 halfVec = normalize(view_space_light - normalize(view_space_vertex_position)); + //highp vec3 halfVec = normalize(vec3(0.0, 0.0, -1.0) - normalize(view_space_vertex_position)); + + mediump float specularFactor = max(0.0,pow(clamp(dot(halfVec,normalize(gbuffer_normal)), 0.0, 1.0), gbuffer_specular_exponent)); + //mediump float specularFactor = 0.0; + + //specularFactor = halfVec.z; + + gl_FragColor = vec4(vec3(lamberFactor), specularFactor); }