From 21762174bfce899d59944cea56bc9b03efbcc7c1 Mon Sep 17 00:00:00 2001 From: kearwood Date: Thu, 19 Apr 2012 23:39:32 +0000 Subject: [PATCH] Specular calculations for deferred lighting in progress Have integrated the position of the directional light in the scene graph (imported from fbx) with the forward renderer and deferred lighting renderer's directional light angle --HG-- extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4048 --- KREngine/KREngine/Classes/KRCamera.cpp | 11 ++++- KREngine/KREngine/Classes/KRCamera.h | 5 +++ .../KREngine/Classes/KRDirectionalLight.cpp | 17 +++++++- .../KREngine/Classes/KRDirectionalLight.h | 1 + KREngine/KREngine/Classes/KREngine.h | 1 + KREngine/KREngine/Classes/KREngine.mm | 4 +- KREngine/KREngine/Classes/KRNode.cpp | 14 +++++++ KREngine/KREngine/Classes/KRNode.h | 5 +++ KREngine/KREngine/Classes/KRScene.cpp | 37 +++++++++++++++-- KREngine/KREngine/Classes/KRScene.h | 5 +++ KREngine/KREngine/Classes/KRShader.cpp | 9 +++++ KREngine/KREngine/Classes/KRShader.h | 1 + KREngine/KREngine/Shaders/ObjectShader.fsh | 15 ++++++- .../KREngine/Shaders/light_directional.fsh | 40 +++++++++++++++---- 14 files changed, 148 insertions(+), 17 deletions(-) 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); }