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
This commit is contained in:
kearwood
2012-04-19 23:39:32 +00:00
parent 2ead2995d5
commit 21762174bf
14 changed files with 148 additions and 17 deletions

View File

@@ -31,6 +31,7 @@
#include <iostream>
#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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -19,6 +19,7 @@ public:
virtual ~KRDirectionalLight();
virtual std::string getElementName();
KRVector3 getLightDirection();
#if TARGET_OS_IPHONE

View File

@@ -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];

View File

@@ -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));

View File

@@ -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 *> &KRNode::getChildren() {
return m_childNodes;
}

View File

@@ -34,6 +34,7 @@ public:
virtual std::string getElementName();
void addChild(KRNode *child);
const std::vector<KRNode *> &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);

View File

@@ -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<KRDirectionalLight *>(&node);
if(pLight) {
return pLight;
} else {
const std::vector<KRNode *> children = node.getChildren();
for(std::vector<KRNode *>::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;
}

View File

@@ -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;
};

View File

@@ -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());

View File

@@ -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,

View File

@@ -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
}

View File

@@ -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);
}