Implemented punch-through / alpha tested material support, enabled with the "alpha_test true" in the material file.

--HG--
extra : convert_revision : svn%3A7752d6cf-9f14-4ad2-affc-04f1e67b81a5/trunk%4064
This commit is contained in:
kearwood
2012-08-09 23:40:32 +00:00
parent 61027da1cf
commit e8ad725d45
11 changed files with 67 additions and 23 deletions

View File

@@ -456,8 +456,8 @@
E491018613C99BDC0098455B /* KRTexture.h */,
E491018113C99BDC0098455B /* KRTexture.cpp */,
E47C25A113F4F65A00FF4370 /* KRShaderManager.h */,
E47C25A413F4F66F00FF4370 /* KRShader.h */,
E47C25A613F4F6AB00FF4370 /* KRShaderManager.cpp */,
E47C25A413F4F66F00FF4370 /* KRShader.h */,
E47C25A813F4F6DD00FF4370 /* KRShader.cpp */,
E48B3CBC14393DF5000C50E2 /* KRCamera.h */,
E48B3CBF14393E2F000C50E2 /* KRCamera.cpp */,

View File

@@ -67,7 +67,7 @@ void KRDirectionalLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundi
light_direction_view_space = KRMat4::Dot(matModelToView, light_direction_view_space);
light_direction_view_space.normalize();
KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, renderPass);
KRShader *pShader = pContext->getShaderManager()->getShader("light_directional", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass);
pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass);

View File

@@ -144,7 +144,7 @@ void KRLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolume &f
// Render light flare on transparency pass
KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, renderPass);
KRShader *pShader = pContext->getShaderManager()->getShader("flare", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass);
pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_pFlareTexture->getName());

View File

@@ -66,6 +66,7 @@ KRMaterial::KRMaterial(const char *szName) : KRResource(szName) {
m_reflectionMapOffset = KRVector2(0.0f, 0.0f);
m_reflectionMapScale = KRVector2(1.0f, 1.0f);
m_reflectionFactor = 0.0f;
m_bAlphaTest = false;
}
KRMaterial::~KRMaterial() {
@@ -104,6 +105,9 @@ bool KRMaterial::save(const std::string& path) {
if(m_reflectionMap.size()) {
fprintf(f, "map_Reflection %s.pvr -s %f %f -o %f %f\n", m_reflectionMap.c_str(), m_reflectionMapScale.x, m_reflectionMapScale.y, m_reflectionMapOffset.x, m_reflectionMapOffset.y);
}
if(m_bAlphaTest) {
fprintf(f, "alpha_test true");
}
fclose(f);
return true;
}
@@ -139,6 +143,10 @@ void KRMaterial::setReflectionMap(std::string texture_name, KRVector2 texture_sc
m_reflectionMapOffset = texture_offset;
}
void KRMaterial::setAlphaTest(bool bAlphaTest) {
m_bAlphaTest = bAlphaTest;
}
void KRMaterial::setAmbient(const KRVector3 &c) {
m_ambientColor = c;
}
@@ -199,8 +207,9 @@ void KRMaterial::bind(KRMaterial **prevBoundMaterial, char *szPrevShaderKey, KRC
bool bNormalMap = m_pNormalMap != NULL && pCamera->bEnableNormalMap;
bool bSpecMap = m_pSpecularMap != NULL && pCamera->bEnableSpecMap;
bool bReflectionMap = m_pReflectionMap != NULL && pCamera->bEnableReflectionMap;
bool bAlphaTest = m_bAlphaTest && bDiffuseMap;
KRShader *pShader = pContext->getShaderManager()->getShader("ObjectShader", pCamera, bDiffuseMap, bNormalMap, bSpecMap, cShadowBuffers, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, renderPass);
KRShader *pShader = pContext->getShaderManager()->getShader("ObjectShader", pCamera, bDiffuseMap, bNormalMap, bSpecMap, cShadowBuffers, bLightMap, m_diffuseMapScale != default_scale && bDiffuseMap, m_specularMapScale != default_scale && bSpecMap, m_normalMapScale != default_scale && bNormalMap, m_diffuseMapOffset != default_offset && bDiffuseMap, m_specularMapOffset != default_offset && bSpecMap, m_normalMapOffset != default_offset && bNormalMap, bAlphaTest, renderPass);
bool bSameShader = strcmp(pShader->getKey(), szPrevShaderKey) == 0;
if(!bSameShader) {

View File

@@ -74,6 +74,7 @@ public:
void setTransparency(GLfloat a);
void setShininess(GLfloat s);
void setReflectionFactor(GLfloat r);
void setAlphaTest(bool bAlphaTest);
bool isTransparent();
@@ -122,6 +123,8 @@ private:
GLfloat m_tr; // Transparency
GLfloat m_ns; // Shininess
GLfloat m_reflectionFactor; // Level of reflectivity
bool m_bAlphaTest; // When true, alpha in diffuse texture is interpreted as punch-through when < 0.5
};
#endif

View File

@@ -116,7 +116,11 @@ bool KRMaterialManager::loadFile(const char *szPath) {
m_materials[szSymbol[1]] = pMaterial;
}
if(pMaterial != NULL) {
if(strcmp(szSymbol[0], "Ka") == 0) {
if(strcmp(szSymbol[0], "alpha_test") == 0) {
if(cSymbols == 2) {
pMaterial->setAlphaTest(strcmp(szSymbol[1], "true") == 0);
}
} else if(strcmp(szSymbol[0], "Ka") == 0) {
char *pScan2 = szSymbol[1];
double r = strtof(pScan2, &pScan2);
if(cSymbols == 2) {

View File

@@ -74,7 +74,7 @@ void KRPointLight::render(KRCamera *pCamera, KRContext *pContext, KRBoundingVolu
if(influence_extents.test_intersect(frustrumVolumeNoNearClip)) {
// Cull out any lights not within the view frustrum
KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, false, false, false, false, false, false, false, renderPass);
KRShader *pShader = pContext->getShaderManager()->getShader("light_point", pCamera, false, false, false, 0, false, false, false, false, false, false, false, false, renderPass);
pShader->bind(pCamera, matModelToView, mvpmatrix, cameraPosition, lightDirection, pShadowMatrices, shadowDepthTextures, 0, renderPass);
glUniform3f(
pShader->m_uniforms[KRShader::KRENGINE_UNIFORM_LIGHT_COLOR],

View File

@@ -45,10 +45,10 @@ KRShaderManager::~KRShaderManager() {
}
KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, KRNode::RenderPass renderPass) {
KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, KRNode::RenderPass renderPass) {
char szKey[256];
sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s", pCamera->bEnablePerPixel, bDiffuseMap, bNormalMap, bSpecMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, renderPass, shader_name.c_str());
sprintf(szKey, "%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%d_%i_%s", pCamera->bEnablePerPixel, bAlphaTest, bDiffuseMap, bNormalMap, bSpecMap, pCamera->bDebugPSSM, iShadowQuality, pCamera->bEnableAmbient, pCamera->bEnableDiffuse, pCamera->bEnableSpecular, bLightMap, bDiffuseMapScale, bSpecMapScale, bNormalMapScale, bDiffuseMapOffset, bSpecMapOffset, bNormalMapOffset, renderPass, shader_name.c_str());
/*
@@ -68,6 +68,7 @@ KRShader *KRShaderManager::getShader(std::string shader_name, KRCamera *pCamera,
stream.precision(std::numeric_limits<long double>::digits10);
stream << "#define HAS_DIFFUSE_MAP " << (bDiffuseMap ? "1" : "0");
stream << "\n#define ALPHA_TEST " << (bAlphaTest ? "1" : "0");
stream << "\n#define HAS_NORMAL_MAP " << (bNormalMap ? "1" : "0");
stream << "\n#define HAS_SPEC_MAP " << (bSpecMap ? "1" : "0");
stream << "\n#define HAS_LIGHT_MAP " << (bLightMap ? "1" : "0");

View File

@@ -54,7 +54,7 @@ public:
void loadVertexShader(const std::string &name, const std::string &path);
KRShader *getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, KRNode::RenderPass renderPass);
KRShader *getShader(std::string shader_name, KRCamera *pCamera, bool bDiffuseMap, bool bNormalMap, bool bSpecMap, int iShadowQuality, bool bLightMap, bool bDiffuseMapScale,bool bSpecMapScale, bool bNormalMapScale, bool bDiffuseMapOffset, bool bSpecMapOffset, bool bNormalMapOffset, bool bAlphaTest, KRNode::RenderPass renderPass);
private:
std::map<std::string, KRShader *> m_shaders;

View File

@@ -25,7 +25,6 @@
// or implied, of Kearwood Gilbert.
//
#if ENABLE_PER_PIXEL == 1 || GBUFFER_PASS == 1
uniform mediump float material_shininess;
#if HAS_NORMAL_MAP == 1
@@ -60,6 +59,15 @@
#else
uniform highp mat4 model_normal_to_view_matrix;
#endif
#if HAS_DIFFUSE_MAP == 1 && ALPHA_TEST == 1
uniform sampler2D diffuseTexture;
#if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
varying highp vec2 diffuse_uv;
#else
#define diffuse_uv texCoord
#endif
#endif
#else
uniform lowp vec3 material_ambient, material_diffuse, material_specular;
uniform lowp float material_alpha;
@@ -120,6 +128,15 @@ uniform mediump vec4 viewport;
void main()
{
#if ALPHA_TEST == 1 && HAS_DIFFUSE_MAP == 1
mediump vec4 diffuseMaterial = texture2D(diffuseTexture, diffuse_uv);
if(diffuseMaterial.a < 0.5) discard;
#endif
#if GBUFFER_PASS == 1 && ALPHA_TEST
if(texture2D(diffuseTexture, diffuse_uv).a < 0.5) discard;
#endif
#if GBUFFER_PASS == 2 || GBUFFER_PASS == 3
mediump vec2 gbuffer_uv = vec2(gl_FragCoord.xy / viewport.zw);
#endif
@@ -141,7 +158,12 @@ void main()
gl_FragColor = vec4(view_space_normal * 0.5 + 0.5, material_shininess / 100.0);
#else
#if HAS_DIFFUSE_MAP == 1
mediump vec4 diffuseMaterial = vec4(vec3(texture2D(diffuseTexture, diffuse_uv)), material_alpha);
#if ALPHA_TEST
diffuseMaterial.a = 1.0;
#else
mediump vec4 diffuseMaterial = vec4(vec3(texture2D(diffuseTexture, diffuse_uv)), material_alpha);
#endif
#else
mediump vec4 diffuseMaterial = vec4(vec3(1.0), material_alpha);
#endif

View File

@@ -151,6 +151,22 @@ void main()
#endif
#if GBUFFER_PASS != 1 || ALPHA_TEST == 1
// Scaled and translated diffuse map UV's
#if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv = texCoord;
#if HAS_DIFFUSE_MAP_OFFSET == 1
diffuse_uv + diffuseTexture_Offset;
#endif
#if HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv *= diffuseTexture_Scale;
#endif
#endif
#endif
#if GBUFFER_PASS == 1
#if HAS_NORMAL_MAP == 1
mediump vec3 a_bitangent = cross(vertex_normal, vertex_tangent);
@@ -166,18 +182,7 @@ void main()
lightmap_uv = vertex_lightmap_uv.st;
#endif
// Scaled and translated diffuse map UV's
#if HAS_DIFFUSE_MAP_OFFSET == 1 || HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv = texCoord;
#if HAS_DIFFUSE_MAP_OFFSET == 1
diffuse_uv + diffuseTexture_Offset;
#endif
#if HAS_DIFFUSE_MAP_SCALE == 1
diffuse_uv *= diffuseTexture_Scale;
#endif
#endif
#if ENABLE_PER_PIXEL == 1
// Scaled and translated specular map UV's