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

View File

@@ -129,8 +129,8 @@ void GPU_material_free(struct Material *ma);
void GPU_materials_free(void); void GPU_materials_free(void);
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]);
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_uniforms(GPUMaterial *material, float obmat[4][4], float obcol[4], float autobumpscale);
void GPU_material_unbind(GPUMaterial *material); void GPU_material_unbind(GPUMaterial *material);
int GPU_material_bound(GPUMaterial *material); int GPU_material_bound(GPUMaterial *material);

View File

@@ -1457,10 +1457,10 @@ int GPU_enable_material(int nr, void *attribs)
gpumat = GPU_material_from_blender(GMS.gscene, mat); gpumat = GPU_material_from_blender(GMS.gscene, mat);
GPU_material_vertex_attributes(gpumat, gattribs); 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; 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; GMS.gboundmat= mat;
/* for glsl use alpha blend mode, unless it's set to solid and /* for glsl use alpha blend mode, unless it's set to solid and

View File

@@ -257,11 +257,12 @@ void GPU_material_free(Material *ma)
BLI_freelistN(&ma->gpumaterial); 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) { if (material->pass) {
LinkData *nlink; LinkData *nlink;
GPULamp *lamp; GPULamp *lamp;
GPUShader *shader = GPU_pass_shader(material->pass);
/* handle layer lamps */ /* handle layer lamps */
for (nlink=material->lamps.first; nlink; nlink=nlink->next) { 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->dynenergy = 0.0f;
lamp->dyncol[0]= lamp->dyncol[1]= lamp->dyncol[2] = 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) { if (material->dynproperty & DYN_LAMP_VEC) {
copy_v3_v3(lamp->dynvec, 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); 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);
}
} }
} }

View File

@@ -46,11 +46,20 @@ void BL_BlenderShader::ReloadMaterial()
mGPUMat = (mMat) ? GPU_material_from_blender(mBlenderScene, mMat) : NULL; 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 (VerifyShader()) {
if (enable) if (enable) {
GPU_material_bind(mGPUMat, mLightLayer, mBlenderScene->lay, time, 1); 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 else
GPU_material_unbind(mGPUMat); 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 ) 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; GPUMaterial *gpumat;
gpumat = mGPUMat; gpumat = mGPUMat;
@@ -130,13 +139,9 @@ void BL_BlenderShader::Update(const RAS_MeshSlot & ms, RAS_IRasterizer* rasty )
MT_Matrix4x4 model; MT_Matrix4x4 model;
model.setValue(ms.m_OpenGLMatrix); 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 // note: getValue gives back column major as needed by OpenGL
model.getValue((float*)obmat); model.getValue((float*)obmat);
view.getValue((float*)viewmat);
viewinv.getValue((float*)viewinvmat);
if (ms.m_bObjectColor) if (ms.m_bObjectColor)
ms.m_RGBAcolor.getValue((float *)obcol); 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; 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; 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); mAlphaBlend = GPU_material_alpha_blend(gpumat, obcol);
} }

View File

@@ -78,7 +78,7 @@ public:
// same as VerifyShared // same as VerifyShared
return (NULL != mGPUMat); 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(); int GetAttribNum();
void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat); void SetAttribs(class RAS_IRasterizer* ras, const BL_Material *mat);

View File

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