Fix for [#34754] "Revision 55527 provokes glitchy GLSL shadow map rendering" reported by Alain Ducharme. Per material uniforms and per object uniforms are now better separated.

This commit is contained in:
Mitchell Stokes 2013-04-04 03:55:43 +00:00
parent 7bbaf4853a
commit 966e86cd2d
6 changed files with 60 additions and 57 deletions

@ -129,8 +129,8 @@ void GPU_material_free(struct Material *ma);
void GPU_materials_free(void);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale);
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4]);
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material);

@ -1457,10 +1457,10 @@ int GPU_enable_material(int nr, void *attribs)
gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs);
GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT));
GPU_material_bind(gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT), GMS.gviewmat, GMS.gviewinv);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gviewinv, GMS.gob->col, auto_bump_scale);
GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gob->col, auto_bump_scale);
GMS.gboundmat= mat;
/* for glsl use alpha blend mode, unless it's set to solid and

@ -257,11 +257,12 @@ void GPU_material_free(Material *ma)
BLI_freelistN(&ma->gpumaterial);
}
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap)
void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double time, int mipmap, float viewmat[4][4], float viewinv[4][4])
{
if (material->pass) {
LinkData *nlink;
GPULamp *lamp;
GPUShader *shader = GPU_pass_shader(material->pass);
/* handle layer lamps */
for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
@ -275,47 +276,6 @@ void GPU_material_bind(GPUMaterial *material, int oblay, int viewlay, double tim
lamp->dynenergy = 0.0f;
lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 0.0f;
}
}
GPU_pass_bind(material->pass, time, mipmap);
GPU_pass_update_uniforms(material->pass);
material->bound = 1;
}
}
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float viewinv[4][4], float obcol[4], float autobumpscale)
{
if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
LinkData *nlink;
GPULamp *lamp;
float invmat[4][4], col[4];
/* handle builtins */
if (material->builtins & GPU_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
}
if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
}
if (material->builtins & GPU_OBJECT_MATRIX) {
GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
}
if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
invert_m4_m4(invmat, obmat);
GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
}
if (material->builtins & GPU_OBCOLOR) {
copy_v4_v4(col, obcol);
CLAMP(col[3], 0.0f, 1.0f);
GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
}
if (material->builtins & GPU_AUTO_BUMPSCALE) {
GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
}
/* update lamps */
for (nlink=material->lamps.first; nlink; nlink=nlink->next) {
lamp= nlink->data;
if (material->dynproperty & DYN_LAMP_VEC) {
copy_v3_v3(lamp->dynvec, lamp->vec);
@ -339,6 +299,44 @@ void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float
mult_m4_m4m4(lamp->dynpersmat, lamp->persmat, viewinv);
}
}
/* handle per material built-ins */
if (material->builtins & GPU_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->viewmatloc, 16, 1, (float*)viewmat);
}
if (material->builtins & GPU_INVERSE_VIEW_MATRIX) {
GPU_shader_uniform_vector(shader, material->invviewmatloc, 16, 1, (float*)viewinv);
}
GPU_pass_bind(material->pass, time, mipmap);
GPU_pass_update_uniforms(material->pass);
material->bound = 1;
}
}
void GPU_material_bind_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale)
{
if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
float invmat[4][4], col[4];
/* handle per object builtins */
if (material->builtins & GPU_OBJECT_MATRIX) {
GPU_shader_uniform_vector(shader, material->obmatloc, 16, 1, (float*)obmat);
}
if (material->builtins & GPU_INVERSE_OBJECT_MATRIX) {
invert_m4_m4(invmat, obmat);
GPU_shader_uniform_vector(shader, material->invobmatloc, 16, 1, (float*)invmat);
}
if (material->builtins & GPU_OBCOLOR) {
copy_v4_v4(col, obcol);
CLAMP(col[3], 0.0f, 1.0f);
GPU_shader_uniform_vector(shader, material->obcolloc, 4, 1, col);
}
if (material->builtins & GPU_AUTO_BUMPSCALE) {
GPU_shader_uniform_vector(shader, material->obautobumpscaleloc, 1, 1, &autobumpscale);
}
}
}

@ -46,11 +46,20 @@ void BL_BlenderShader::ReloadMaterial()
mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL;
}
void BL_BlenderShader::SetProg(bool enable, double time)
void BL_BlenderShader::SetProg(bool enable, double time, RAS_IRasterizer* rasty)
{
if (VerifyShader()) {
if (enable)
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1);
if (enable) {
assert(rasty != NULL); // XXX Kinda hacky, but SetProg() should always have the rasterizer if enable is true
float viewmat[4][4], viewinvmat[4][4];
const MT_Matrix4x4& view = rasty->GetViewMatrix();
const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
view.getValue((float*)viewmat);
viewinv.getValue((float*)viewinvmat);
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1, viewmat, viewinvmat);
}
else
GPU_material_unbind(mGPUMat);
}
@ -120,7 +129,7 @@ void BL_BlenderShader::SetAttribs(RAS_IRasterizer* ras, const BL_Material *mat)
void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
{
float obmat[4][4], viewmat[4][4], viewinvmat[4][4], obcol[4];
float obmat[4][4], obcol[4];
GPUMaterial *gpumat;
gpumat = mGPUMat;
@ -130,13 +139,9 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
MT_Matrix4x4 model;
model.setValue(ms.m_OpenGLMatrix);
const MT_Matrix4x4& view = rasty->GetViewMatrix();
const MT_Matrix4x4& viewinv = rasty->GetViewInvMatrix();
// note: getValue gives back column major as needed by OpenGL
model.getValue((float*)obmat);
view.getValue((float*)viewmat);
viewinv.getValue((float*)viewinvmat);
if (ms.m_bObjectColor)
ms.m_RGBAcolor.getValue((float *)obcol);
@ -144,7 +149,7 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
obcol[0] = obcol[1] = obcol[2] = obcol[3] = 1.0f;
float auto_bump_scale = ms.m_pDerivedMesh!=0 ? ms.m_pDerivedMesh->auto_bump_scale : 1.0f;
GPU_material_bind_uniforms(gpumat, obmat, viewmat, viewinvmat, obcol, auto_bump_scale);
GPU_material_bind_uniforms(gpumat, obmat, obcol, auto_bump_scale);
mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
}

@ -78,7 +78,7 @@ public:
// same as VerifyShared
return (NULL != mGPUMat);
}
void SetProg(bool enable, double time=0.0);
void SetProg(bool enable, double time=0.0, RAS_IRasterizer* rasty=NULL);
int GetAttribNum();
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);

@ -314,7 +314,7 @@ void KX_BlenderMaterial::setBlenderShaderData( bool enable, RAS_IRasterizer *ras
else
BL_Texture::DisableAllTextures();
mBlenderShader->SetProg(true, ras->GetTime());
mBlenderShader->SetProg(true, ras->GetTime(), ras);
mLastBlenderShader= mBlenderShader;
}
}