New streaming algorithm in progress

Corrected reflections
Corrected KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE alpha mode
Corrected alpha transparent back face culling

--HG--
branch : nfb
This commit is contained in:
2014-04-12 23:42:26 -07:00
parent e8f9652e42
commit 0405eb681b
12 changed files with 77 additions and 127 deletions

View File

@@ -335,7 +335,11 @@ void KRCamera::renderFrame(float deltaTime, GLint renderBufferWidth, GLint rende
//
// // Disable backface culling
// GLDEBUG(glDisable(GL_CULL_FACE));
//
//
// Enable backface culling
GLDEBUG(glCullFace(GL_BACK));
GLDEBUG(glEnable(GL_CULL_FACE));
// Disable z-buffer write
GLDEBUG(glDepthMask(GL_FALSE));
//

View File

@@ -55,7 +55,7 @@ void KRLODSet::updateLODVisibility(const KRViewport &viewport)
} else if(m_activeLODGroup == NULL) {
m_activeLODGroup = new_active_lod_group;
} else if(new_active_lod_group != m_activeLODGroup) {
if(new_active_lod_group->getStreamLevel(true, viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) {
if(true || new_active_lod_group->getStreamLevel(true, viewport) >= kraken_stream_level::STREAM_LEVEL_IN_LQ) { // FINDME, HACK! Disabled due to performance issues.
// fprintf(stderr, "LOD %s -> %s\n", m_activeLODGroup->getName().c_str(), new_active_lod_group->getName().c_str());
m_activeLODGroup = new_active_lod_group;
} else {

View File

@@ -370,11 +370,11 @@ bool KRMaterial::bind(KRCamera *pCamera, std::vector<KRPointLight *> &point_ligh
m_pContext->getTextureManager()->selectTexture(2, m_pNormalMap, lod_coverage, KRTexture::TEXTURE_USAGE_NORMAL_MAP);
}
if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) {
if(bReflectionCubeMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) {
m_pContext->getTextureManager()->selectTexture(4, m_pReflectionCube, lod_coverage, KRTexture::TEXTURE_USAGE_REFECTION_CUBE);
}
if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) {
if(bReflectionMap && (renderPass == KRNode::RENDER_PASS_FORWARD_OPAQUE || renderPass == KRNode::RENDER_PASS_FORWARD_TRANSPARENT || renderPass == KRNode::RENDER_PASS_DEFERRED_OPAQUE)) {
// GL_TEXTURE7 is used for reading the depth buffer in gBuffer pass 2 and re-used for the reflection map in gBuffer Pass 3 and in forward rendering
m_pContext->getTextureManager()->selectTexture(7, m_pReflectionMap, lod_coverage, KRTexture::TEXTURE_USAGE_REFLECTION_MAP);
}

View File

@@ -153,7 +153,7 @@ bool KRMaterialManager::load(const char *szName, KRDataBlock *data) {
} else if(strcmp(szSymbol[1], "blendoneside") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE);
} else if(strcmp(szSymbol[1], "blendtwoside") == 0) {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDONESIDE);
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE);
} else {
pMaterial->setAlphaMode(KRMaterial::KRMATERIAL_ALPHA_MODE_OPAQUE);
}

View File

@@ -1150,10 +1150,10 @@ void LoadMaterial(KRContext &context, FbxSurfaceMaterial *pMaterial) {
lKFbxDouble1 =((FbxSurfacePhong *) pMaterial)->ReflectionFactor;
// Reflection color
lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection;
//lKFbxDouble3 =((FbxSurfacePhong *) pMaterial)->Reflection;
// We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken
new_material->setReflection(KRVector3(lKFbxDouble3.Get()[0] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[1] * lKFbxDouble1.Get(), lKFbxDouble3.Get()[2] * lKFbxDouble1.Get()));
new_material->setReflection(KRVector3(/*lKFbxDouble3.Get()[0] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[1] * */lKFbxDouble1.Get(), /*lKFbxDouble3.Get()[2] * */lKFbxDouble1.Get()));
} else if(pMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) {
// We found a Lambert material.
@@ -1371,6 +1371,8 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe
}
}
pMesh->GenerateTangentsDataForAllUVSets(true);
int polygon_count = pMesh->GetPolygonCount();
int uv_count = pMesh->GetElementUVCount();
int normal_count = pMesh->GetElementNormalCount();
@@ -1487,36 +1489,38 @@ void LoadMesh(KRContext &context, FbxScene* pFbxScene, FbxGeometryConverter *pGe
mi.normals.push_back(KRVector3(new_normal[0], new_normal[1], new_normal[2]));
}
/*
TODO - Tangent vectors imported from maya appear incorrectly... Only calculating them in Kraken for now
// ----====---- Read Tangents ----====----
for(int l = 0; l < tangent_count; ++l)
{
FbxVector4 new_tangent;
FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l);
if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
switch (leTangent->GetReferenceMode()) {
case FbxGeometryElement::eDirect:
new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = leTangent->GetIndexArray().GetAt(lControlPointIndex);
new_tangent = leTangent->GetDirectArray().GetAt(id);
if(need_tangents) {
for(int l = 0; l < tangent_count; ++l)
{
FbxVector4 new_tangent;
FbxGeometryElementTangent* leTangent = pMesh->GetElementTangent(l);
if(leTangent->GetMappingMode() == FbxGeometryElement::eByPolygonVertex) {
switch (leTangent->GetReferenceMode()) {
case FbxGeometryElement::eDirect:
new_tangent = leTangent->GetDirectArray().GetAt(lControlPointIndex);
break;
case FbxGeometryElement::eIndexToDirect:
{
int id = leTangent->GetIndexArray().GetAt(lControlPointIndex);
new_tangent = leTangent->GetDirectArray().GetAt(id);
}
break;
default:
break; // other reference modes not shown here!
}
break;
default:
break; // other reference modes not shown here!
}
if(l == 0) {
mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
}
}
if(l == 0) {
mi.tangents.push_back(KRVector3(new_tangent[0], new_tangent[1], new_tangent[2]));
}
}
*/
source_vertex_id++;
dest_vertex_id++;

View File

@@ -145,7 +145,7 @@ float KRTexture::getStreamPriority()
priority += 100000.0f;
}
if(m_last_frame_usage & (TEXTURE_USAGE_REFECTION_CUBE)) {
priority += 1000.0f;
priority += 100000.0f;
}
priority += m_last_frame_max_lod_coverage * 10.0f;
return priority;

View File

@@ -223,7 +223,15 @@ void KRTextureManager::startFrame(float deltaTime)
// TODO - Implement proper double-buffering to reduce copy operations
m_streamerFenceMutex.lock();
m_activeTextures_streamer_copy = m_activeTextures;
m_activeTextures_streamer_copy.clear();
for(auto itr=m_activeTextures.begin(); itr != m_activeTextures.end(); itr++) {
KRTexture *texture = *itr;
float priority = texture->getStreamPriority();
m_activeTextures_streamer_copy.push_back(std::pair<float, KRTexture *>(priority, texture));
}
m_streamerFenceMutex.unlock();
m_memoryTransferredThisFrame = 0;
@@ -269,20 +277,22 @@ void KRTextureManager::balanceTextureMemory()
// ---------------
/*
// TODO - Would this be faster with int's for weights?
std::vector<std::pair<float, KRTexture *>> sortedTextures;
std::vector<std::pair<float, KRTexture *> > sortedTextures;
for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *texture = *itr;
float priority = texture->getStreamPriority();
sortedTextures.push_back(std::pair<float, KRTexture *>(priority, texture));
}
*/
std::sort(sortedTextures.begin(), sortedTextures.end(), std::greater<std::pair<float, KRTexture *>>());
std::sort(m_activeTextures_streamer.begin(), m_activeTextures_streamer.end(), std::greater<std::pair<float, KRTexture *>>());
long memoryRemaining = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX;
long memoryRemainingThisFrame = KRMIN(getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed(), getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX);
long memoryRemainingThisFrame = getContext().KRENGINE_MAX_TEXTURE_MEM - getMemUsed();
for(auto itr=sortedTextures.begin(); itr != sortedTextures.end(); itr++) {
for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *texture = (*itr).second;
int min_mip_level = KRMAX(getContext().KRENGINE_MIN_TEXTURE_DIM, texture->getMinMipMap());
long minLodMem = texture->getMemRequiredForSize(min_mip_level);
@@ -299,7 +309,7 @@ void KRTextureManager::balanceTextureMemory()
auto mip_itr = mipPercents.begin();
long memoryRemainingThisMip = 0;
for(auto itr=sortedTextures.begin(); itr != sortedTextures.end(); itr++) {
for(auto itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
if(memoryRemainingThisMip <= 0) {
if(mip_itr == mipPercents.end()) {
break;
@@ -327,91 +337,11 @@ void KRTextureManager::balanceTextureMemory()
}
// ---------------
/*
// Determine the additional amount of memory required in order to resize all active textures to the maximum size
long wantedTextureMem = 0;
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end(); itr++) {
KRTexture *activeTexture = *itr;
wantedTextureMem = activeTexture->getMemRequiredForSize(getContext().KRENGINE_MAX_TEXTURE_DIM) - activeTexture->getMemSize();
}
// Determine how much memory we need to free up
long memoryDeficit = wantedTextureMem - (getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - getMemUsed());
// Determine how many mip map levels we need to strip off of inactive textures to free the memory we need
long maxDimInactive = getContext().KRENGINE_MAX_TEXTURE_DIM;
long potentialMemorySaving = 0;
while(potentialMemorySaving < memoryDeficit && maxDimInactive > getContext().KRENGINE_MIN_TEXTURE_DIM) {
maxDimInactive = maxDimInactive >> 1;
potentialMemorySaving = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr;
long potentialMemoryDelta = poolTexture->getMemRequiredForSize(maxDimInactive) - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) {
potentialMemorySaving += -potentialMemoryDelta;
}
}
}
// Strip off mipmap levels of inactive textures to free up memory
long inactive_texture_mem_used_target = 0;
for(std::set<KRTexture *>::iterator itr=m_poolTextures_streamer.begin(); itr != m_poolTextures_streamer.end(); itr++) {
KRTexture *poolTexture = *itr;
long mem_required = poolTexture->getMemRequiredForSize(maxDimInactive);
long potentialMemoryDelta = mem_required - poolTexture->getMemSize();
if(potentialMemoryDelta < 0) {
if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) {
long mem_free;
m_pContext->getMemoryStats(mem_free);
if(mem_required * 2 < mem_free - 10000000) {
poolTexture->resize(maxDimInactive);
}
}
inactive_texture_mem_used_target += mem_required;
} else {
inactive_texture_mem_used_target += poolTexture->getMemSize();
}
}
// Determine the maximum mipmap level for the active textures we can achieve with the memory that is available
long memory_available = 0;
long maxDimActive = getContext().KRENGINE_MAX_TEXTURE_DIM;
while(memory_available <= 0 && maxDimActive >= getContext().KRENGINE_MIN_TEXTURE_DIM) {
memory_available = getContext().KRENGINE_TARGET_TEXTURE_MEM_MAX - inactive_texture_mem_used_target;
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr;
memory_available -= activeTexture->getMemRequiredForSize(maxDimActive);
}
if(memory_available <= 0) {
maxDimActive = maxDimActive >> 1; // Try the next smaller mipmap size
}
}
// Resize active textures to balance the memory usage and mipmap levels
for(std::set<KRTexture *>::iterator itr=m_activeTextures_streamer.begin(); itr != m_activeTextures_streamer.end() && memory_available > 0; itr++) {
KRTexture *activeTexture = *itr;
long mem_required = activeTexture->getMemRequiredForSize(maxDimActive);
if(mem_required * 2 + getMemUsed() < KRContext::KRENGINE_MAX_TEXTURE_MEM) {
long mem_free;
m_pContext->getMemoryStats(mem_free);
if(mem_required * 2 < mem_free - 10000000) {
activeTexture->resize(maxDimActive);
}
}
}
*/
}
void KRTextureManager::rotateBuffers()
{
const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 120;
const long KRENGINE_TEXTURE_EXPIRY_FRAMES = 10;
// ----====---- Expire textures that haven't been used in a long time ----====----
std::set<KRTexture *> expiredTextures;

View File

@@ -95,8 +95,8 @@ private:
std::set<KRTexture *> m_activeTextures;
std::set<KRTexture *> m_activeTextures_streamer;
std::set<KRTexture *> m_activeTextures_streamer_copy;
std::vector<std::pair<float, KRTexture *> > m_activeTextures_streamer;
std::vector<std::pair<float, KRTexture *> > m_activeTextures_streamer_copy;
std::atomic<long> m_textureMemUsed;

View File

@@ -347,7 +347,7 @@ KRTexture *KRTextureTGA::compress(bool premultiply_alpha)
assert(lod_width == 1);
GLDEBUG(glBindTexture(GL_TEXTURE_2D, 0));
getContext().getTextureManager()->selectTexture(0, NULL);
getContext().getTextureManager()->selectTexture(0, NULL, 0.0f, KRTexture::TEXTURE_USAGE_NONE);
GLDEBUG(glDeleteTextures(1, &compressed_handle));
KRTextureKTX *new_texture = new KRTextureKTX(getContext(), getName(), internal_format, base_internal_format, width, height, blocks);

View File

@@ -176,6 +176,17 @@ float KRViewport::coverage(const KRAABB &b) const
if(!visible(b)) {
return 0.0f; // Culled out by view frustrum
} else {
KRVector3 nearest_point = b.nearestPoint(getCameraPosition());
float distance = (nearest_point - getCameraPosition()).magnitude();
KRVector3 v = KRMat4::DotWDiv(m_matProjection, getCameraPosition() + getCameraDirection() * distance);
float screen_depth = distance / 1000.0f;
return KRCLAMP(1.0f - screen_depth, 0.01f, 1.0f);
/*
KRVector2 screen_min;
KRVector2 screen_max;
// Loop through all corners and transform them to screen space
@@ -199,6 +210,7 @@ float KRViewport::coverage(const KRAABB &b) const
float c = (screen_max.x - screen_min.x) * (screen_max.y - screen_min.y);
return KRCLAMP(c, 0.01f, 1.0f);
*/
}
}

View File

@@ -372,9 +372,9 @@ void main()
mediump vec3 reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(world_space_normal, incidenceVec) * world_space_normal);
#endif
#if HAS_REFLECTION_MAP == 1
gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * textureCube(reflectionCubeTexture, reflectionVec);
gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0);
#else
gl_FragColor += vec4(material_reflection, 0.0) * textureCube(reflectionCubeTexture, reflectionVec);
gl_FragColor += vec4(material_reflection, 0.0) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0);
#endif
#endif

View File

@@ -372,9 +372,9 @@ void main()
mediump vec3 reflectionVec = mat3(model_matrix) * (incidenceVec - 2.0 * dot(world_space_normal, incidenceVec) * world_space_normal);
#endif
#if HAS_REFLECTION_MAP == 1
gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * textureCube(reflectionCubeTexture, reflectionVec);
gl_FragColor += vec4(material_reflection, 0.0) * texture2D(reflectionTexture, reflection_uv) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0);
#else
gl_FragColor += vec4(material_reflection, 0.0) * textureCube(reflectionCubeTexture, reflectionVec);
gl_FragColor += vec4(material_reflection, 0.0) * vec4(textureCube(reflectionCubeTexture, reflectionVec).rgb, 1.0);
#endif
#endif