- Fixed specular bug affecting rotated, translated and scaled objects

- Cleanup and performance optimizations

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%40136
This commit is contained in:
kearwood
2012-10-20 01:10:57 +00:00
parent 2097664c0a
commit 1f512462b7
9 changed files with 72 additions and 57 deletions

View File

@@ -146,10 +146,6 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
createBuffers();
m_pContext->rotateBuffers(true);
KRMat4 invViewMatrix = viewMatrix;
invViewMatrix.invert();
KRVector3 cameraPosition = KRMat4::Dot(invViewMatrix, KRVector3(0.0,0.0,0.0));
KRVector3 lightDirection(0.0, 0.0, 1.0);
@@ -197,7 +193,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
}
}
renderFrame(scene, viewMatrix, lightDirection, cameraPosition);
renderFrame(scene, viewMatrix, lightDirection);
GLDEBUG(glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO));
renderPost();
@@ -207,7 +203,7 @@ void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix)
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition) {
void KRCamera::renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection) {
setViewportSize(KRVector2(backingWidth, backingHeight));
@@ -842,3 +838,26 @@ void KRCamera::setSkyBox(const std::string &skyBoxName) {
m_pSkyBoxTexture = NULL;
m_skyBoxName = skyBoxName;
}
float KRCamera::getPerspectiveNearZ()
{
return perspective_nearz;
}
float KRCamera::getPerspectiveFarZ()
{
return perspective_farz;
}
void KRCamera::setPerspectiveNear(float v)
{
if(perspective_nearz != v) {
perspective_nearz = v;
invalidateShadowBuffers();
}
}
void KRCamera::setPerpsectiveFarZ(float v)
{
if(perspective_farz != v) {
perspective_farz = v;
invalidateShadowBuffers();
}
}

View File

@@ -57,10 +57,6 @@ public:
GLint backingWidth, backingHeight;
void renderFrame(KRScene &scene, KRMat4 &viewMatrix);
void renderShadowBuffer(KRScene &scene, int iShadow);
void invalidateShadowBuffers();
void allocateShadowBuffers(int cBuffers);
void createBuffers();
KRVector3 getPosition() const;
void setPosition(const KRVector3 &position);
@@ -92,8 +88,9 @@ public:
double dAmbientG;
double dAmbientB;
double perspective_fov;
double perspective_nearz;
double perspective_farz;
int dof_quality;
double dof_depth;
@@ -115,9 +112,22 @@ public:
void setSkyBox(const std::string &skyBoxName);
float getPerspectiveNearZ();
float getPerspectiveFarZ();
void setPerspectiveNear(float v);
void setPerpsectiveFarZ(float v);
private:
KRVector3 m_position;
void renderShadowBuffer(KRScene &scene, int iShadow);
void invalidateShadowBuffers();
void allocateShadowBuffers(int cBuffers);
void createBuffers();
float perspective_nearz;
float perspective_farz;
int m_iFrame;
GLuint compositeFramebuffer, compositeDepthTexture, compositeColorTexture;
GLuint lightAccumulationBuffer, lightAccumulationTexture;
@@ -131,7 +141,7 @@ private:
void destroyBuffers();
void renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection, KRVector3 &cameraPosition);
void renderFrame(KRScene &scene, KRMat4 &viewMatrix, KRVector3 &lightDirection);

View File

@@ -503,17 +503,11 @@ double const PI = 3.141592653589793f;
- (void)setNearZ: (double)dNearZ
{
if(_camera->perspective_nearz != dNearZ) {
_camera->perspective_nearz = dNearZ;
_camera->invalidateShadowBuffers();
}
_camera->setPerspectiveNear(dNearZ);
}
- (void)setFarZ: (double)dFarZ
{
if(_camera->perspective_farz != dFarZ) {
_camera->perspective_farz = dFarZ;
_camera->invalidateShadowBuffers();
}
_camera->setPerpsectiveFarZ(dFarZ);
}
- (void)setDebug_text:(NSString *)value

View File

@@ -120,18 +120,6 @@ void KRInstance::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &viewMatr
m_pContext->getTextureManager()->selectTexture(3, m_pLightMap, 0);
}
KRMat4 inverseViewMatrix = viewMatrix;
inverseViewMatrix.invert();
KRVector3 cameraPosition = KRMat4::Dot(inverseViewMatrix, KRVector3::Zero());
// Transform location of camera to object space for calculation of specular halfVec
KRMat4 inverseModelMatrix = m_modelMatrix;
inverseModelMatrix.invert();
KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, cameraPosition);
KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, lightDirection);
pModel->render(pCamera, pContext, m_modelMatrix, viewMatrix, matMVP, lightDirection, pShadowMatrices, shadowDepthTextures, cShadowBuffers, m_pLightMap, renderPass);
}
}

View File

@@ -61,14 +61,14 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRMat4 &viewMa
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);
KRBoundingVolume frustrumVolumeNoNearClip = KRBoundingVolume(viewMatrix, pCamera->perspective_fov, pCamera->m_viewportSize.x / pCamera->m_viewportSize.y, 0.0, pCamera->getPerspectiveFarZ());
if(influence_extents.test_intersect(frustrumVolumeNoNearClip)) {
// Cull out any lights not within the view frustrum
KRVector3 view_light_position = KRMat4::Dot(viewMatrix, light_position);
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->perspective_nearz) * (influence_radius + pCamera->perspective_nearz);
bool bInsideLight = view_light_position.sqrMagnitude() <= (influence_radius + pCamera->getPerspectiveNearZ()) * (influence_radius + pCamera->getPerspectiveNearZ());
KRShader *pShader = pContext->getShaderManager()->getShader(bVisualize ? "visualize_overlay" : (bInsideLight ? "light_point_inside" : "light_point"), pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, false, false, false, false, false, renderPass);
if(pShader->bind(pCamera, m_modelMatrix, viewMatrix, mvpmatrix, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass)) {

View File

@@ -187,7 +187,7 @@ void KRScene::render(int childOrder[], KROctreeNode *pOctreeNode, std::set<KRAAB
KRMat4 invView = viewMatrix;
invView.invert();
KRVector3 cameraPos = KRMat4::Dot(invView, KRVector3::Zero());
KRAABB cameraExtents = KRAABB(cameraPos - KRVector3(pCamera->perspective_nearz), cameraPos + KRVector3(pCamera->perspective_nearz));
KRAABB cameraExtents = KRAABB(cameraPos - KRVector3(pCamera->getPerspectiveNearZ()), cameraPos + KRVector3(pCamera->getPerspectiveNearZ()));
bVisible = octreeBounds.intersects(cameraExtents);
if(bVisible) {
newVisibleBounds.insert(octreeBounds); // Record the actual tests that succeeded during this frame

View File

@@ -142,9 +142,9 @@ KRShader::KRShader(char *szKey, std::string options, std::string vertShaderSourc
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP1] = glGetUniformLocation(m_iProgram, "shadow_mvp1"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP2] = glGetUniformLocation(m_iProgram, "shadow_mvp2"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SHADOWMVP3] = glGetUniformLocation(m_iProgram, "shadow_mvp3"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION] = glGetUniformLocation(m_iProgram, "light_direction"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_model_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE] = glGetUniformLocation(m_iProgram, "light_direction_view_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS] = glGetUniformLocation(m_iProgram, "cameraPosition"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE] = glGetUniformLocation(m_iProgram, "camera_position_model_space"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_VIEWPORT] = glGetUniformLocation(m_iProgram, "viewport"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_DIFFUSETEXTURE] = glGetUniformLocation(m_iProgram, "diffuseTexture"));
GLDEBUG(m_uniforms[KRENGINE_UNIFORM_SPECULARTEXTURE] = glGetUniformLocation(m_iProgram, "specularTexture"));
@@ -211,6 +211,14 @@ bool KRShader::bind(KRCamera *pCamera, KRMat4 &matModel, KRMat4 &matView, KRMat4
inverseViewMatrix.invert();
KRVector3 cameraPosition = KRMat4::Dot(inverseViewMatrix, KRVector3::Zero());
// Transform location of camera to object space for calculation of specular halfVec
KRMat4 inverseModelMatrix = matModel;
inverseModelMatrix.invert();
KRVector3 cameraPosObject = KRMat4::Dot(inverseModelMatrix, cameraPosition);
KRVector3 lightDirObject = KRMat4::Dot(inverseModelMatrix, lightDirection);
lightDirObject.normalize();
GLDEBUG(glUseProgram(m_iProgram));
@@ -267,15 +275,11 @@ bool KRShader::bind(KRCamera *pCamera, KRMat4 &matModel, KRMat4 &matView, KRMat4
matViewToModel.setUniform(m_uniforms[KRShader::KRENGINE_UNIFORM_V2M]);
}
KRVector3 nLightDir = lightDirection;
nLightDir.normalize();
// Bind the light direction vector
nLightDir.setUniform(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION]);
lightDirObject.setUniform(m_uniforms[KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE]);
// Bind the camera position, in model space
cameraPosition.setUniform(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS]);
cameraPosObject.setUniform(m_uniforms[KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE]);
GLDEBUG(glUniform4f(
m_uniforms[KRENGINE_UNIFORM_VIEWPORT],

View File

@@ -77,7 +77,7 @@ public:
KRENGINE_UNIFORM_LIGHT_POSITION,
KRENGINE_UNIFORM_LIGHT_POSITION_VIEW_SPACE,
KRENGINE_UNIFORM_LIGHT_DIRECTION,
KRENGINE_UNIFORM_LIGHT_DIRECTION_MODEL_SPACE,
KRENGINE_UNIFORM_LIGHT_DIRECTION_VIEW_SPACE,
KRENGINE_UNIFORM_LIGHT_COLOR,
KRENGINE_UNIFORM_LIGHT_DECAY_START,
@@ -96,7 +96,7 @@ public:
KRENGINE_UNIFORM_V2M,
KRENGINE_UNIFORM_MODEL_MATRIX,
KRENGINE_UNIFORM_CAMERAPOS,
KRENGINE_UNIFORM_CAMERAPOS_MODEL_SPACE,
KRENGINE_UNIFORM_VIEWPORT,
KRENGINE_UNIFORM_DIFFUSETEXTURE,
KRENGINE_UNIFORM_SPECULARTEXTURE,

View File

@@ -66,8 +66,8 @@ uniform highp mat4 mvp_matrix; // mvp_matrix is the result of multiplying t
#endif
#else
uniform highp vec3 light_direction; // Must be normalized before entering shader
uniform highp vec3 cameraPosition;
uniform highp vec3 light_direction_model_space; // Must be normalized before entering shader
uniform highp vec3 camera_position_model_space;
#if HAS_LIGHT_MAP == 1
attribute mediump vec2 vertex_lightmap_uv;
@@ -206,10 +206,10 @@ void main()
#if HAS_REFLECTION_CUBE_MAP == 1
#if HAS_NORMAL_MAP == 1
eyeVec = normalize(cameraPosition - vertex_position);
eyeVec = normalize(camera_position_model_space - vertex_position);
#else
// Calculate reflection vector as I - 2.0 * dot(N, I) * N
mediump vec3 eyeVec = normalize(cameraPosition - vertex_position);
mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position);
mediump vec3 incidenceVec = -eyeVec;
reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(vertex_normal, incidenceVec) * vertex_normal);
#endif
@@ -267,27 +267,27 @@ void main()
mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent);
#if HAS_REFLECTION_CUBE_MAP == 0
// The cube map reflections also require an eyeVec as a varying attribute when normal mapping, so only re-calculate here when needed
mediump vec3 eyeVec = normalize(cameraPosition - vertex_position);
mediump vec3 eyeVec = normalize(camera_position_model_space - vertex_position);
#else
tangent_to_world_matrix[0] = vec3(model_inverse_transpose_matrix * vec4(vertex_tangent, 1.0));
tangent_to_world_matrix[1] = vec3(model_inverse_transpose_matrix * vec4(a_bitangent, 1.0));
tangent_to_world_matrix[2] = vec3(model_inverse_transpose_matrix * vec4(vertex_normal, 1.0));
#endif
lightVec = normalize(vec3(dot(light_direction, vertex_tangent), dot(light_direction, a_bitangent), dot(light_direction, vertex_normal)));
lightVec = normalize(vec3(dot(light_direction_model_space, vertex_tangent), dot(light_direction_model_space, a_bitangent), dot(light_direction_model_space, 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 = light_direction;
halfVec = normalize((normalize(cameraPosition - vertex_position) + lightVec)); // Normalizing anyways, no need to divide by 2
lightVec = light_direction_model_space;
halfVec = normalize((normalize(camera_position_model_space - 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) + light_direction)); // Normalizing anyways, no need to divide by 2
lamberFactor = max(0.0,dot(light_direction, vertex_normal));
mediump vec3 halfVec = normalize((normalize(camera_position_model_space - vertex_position) + light_direction_model_space)); // Normalizing anyways, no need to divide by 2
lamberFactor = max(0.0,dot(light_direction_model_space, vertex_normal));
specularFactor = max(0.0,pow(dot(halfVec,vertex_normal), material_shininess));
#endif
#endif