シェーダーについてはわかりませんが、その概念の基本的な考え方は知っています。
深度ピーリングを実装する必要があるため、最初にシェーダーの世界に深く入り込む必要があるかどうか、または glDepthFunc をスマートに使用するだけでシェーダーなしで実装できるかどうかを知りたい..
シェーダーについてはわかりませんが、その概念の基本的な考え方は知っています。
深度ピーリングを実装する必要があるため、最初にシェーダーの世界に深く入り込む必要があるかどうか、または glDepthFunc をスマートに使用するだけでシェーダーなしで実装できるかどうかを知りたい..
はい、面倒ですが、GL_ARB_depth_texture と GL_ARB_shadow があればできます。
GL_ARB_occlusion_query は、ピーリングを停止するタイミングを決定できるため、非常に便利です。これがない場合でも実行できますが、ループを一定回数反復する必要があります。高すぎると時間とメモリが無駄になり、低すぎると視覚的なアーティファクトが発生する可能性があります。
このコードは、少し前にデプス ピーリング アルゴリズムをデバッグするために使用したテスト コードからハッキングされたものです。システム固有のものをすべて取り除き、疑似コードに置き換え、再構築を行ったので、コンパイルされるとは思わないでください。うまくいけば、あなたはアイデアを得ることができるはずです。
このアプローチを使用して順序に依存しない透明度を得るには、おそらく深度テクスチャのリストを作成してから、逆の順序でトラバースします。
[コード] bool DrawNthSurface(size_t パス) { GLboolean cached_stencil_test_enabled; GLboolean cached_alpha_test_enabled; GLboolean cached_depth_test_enabled; GLboolean cached_face_cull_enabled;
glGetBooleanv(GL_STENCIL_TEST, &cached_stencil_test_enabled);
glGetBooleanv(GL_ALPHA_TEST, &cached_alpha_test_enabled);
glGetBooleanv(GL_DEPTH_TEST, &cached_depth_test_enabled);
glGetBooleanv(GL_CULL_FACE, &cached_face_cull_enabled);
if(HasShadow()) // Checks GL_ARB_shadow
{
return false;
}
else
{
GLuint depthTexture(0);
bool status(true);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
// Draw geometry into the depth buffer. No textures, shaders etc.
//
// This could easily be folded into next part by restructuring into
// do...while()
status&= DrawSimpleGeometry();
if(status)
{
// for transparency etc. you would build a list of these inside the
// loop. For finding the nth surface we can recycle one.
glGenTextures(1, &depthTexture);
if(depthTexture)
{
glBindTexture(GL_TEXTURE_2D, depthTexture);
glTexImage2D(GL_TEXTURE_2D, 0,
GL_DEPTH_COMPONENT,
ctx->GetViewportWidth(),
ctx->GetViewportHeight(), 0,
GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
// Set up texture unit.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glEnable(GL_TEXTURE_2D);
// Set up texture coord generation. Should get bias from depth buffer
// precision.
SetupTexGen(-0.004);
// Set up shadow test.
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_COMPARE_MODE_ARB,
GL_COMPARE_R_TO_TEXTURE_ARB);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_COMPARE_FUNC_ARB,
GL_GREATER);
glTexParameteri(GL_TEXTURE_2D,
GL_DEPTH_TEXTURE_MODE_ARB,
GL_ALPHA);
glAlphaFunc(GL_GREATER, 0.5f);
glEnable(GL_ALPHA_TEST);
for(size_t n=0;(n<passes) && status;n++)
{
// Update depth texture.
glBindTexture(GL_TEXTURE_2D, depthTexture);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
ctx->GetViewportWidth(),
ctx->GetViewportHeight());
glClear(GL_DEPTH_BUFFER_BIT);
status&= DrawSimpleGeometry();
}
// deactivate shadow test.
{
// Texgen
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glDisable(GL_TEXTURE_GEN_R);
glDisable(GL_TEXTURE_GEN_Q);
// Texture unit
glDisable(GL_TEXTURE_2D);
// Shadow comparison
glDisable(GL_ALPHA_TEST);
}
glDeleteTextures(1, &depthTexture);
}
else
{
status = false;
}
}
// Restore some of the rendering state.
if(cached_face_cull_enabled)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else
{
glDisable(GL_CULL_FACE);
}
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
if(cached_face_cull_enabled)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else
{
glDisable(GL_CULL_FACE);
}
if(!cached_stencil_test_enabled)
{
glDisable(GL_STENCIL_TEST);
}
else
{
glEnable(GL_STENCIL_TEST);
}
if(!cached_alpha_test_enabled)
{
glDisable(GL_ALPHA_TEST);
}
else
{
glEnable(GL_ALPHA_TEST);
}
if(!cached_depth_test_enabled)
{
glDisable(GL_DEPTH_TEST);
}
else
{
glEnable(GL_DEPTH_TEST);
}
// FINALLY: Draw everything.
if(status)
{
glDepthFunc(GL_EQUAL);
status&= DrawAllGeometry();
}
glDepthFunc(GL_LEQUAL);
return status;
}
}
[/コード]
私見で最も難しいのは、texgenを正しくセットアップすることです。コードはとてもシンプルです。Zファイティングアーティファクトを避けるために、バイアスパラメータを含めました。
[コード] マトリックス CreateTextureMatrix(二重バイアス) { マトリックス射影、cmay;
double tmp[16];
glGetDoublev(GL_PROJECTION_MATRIX, tmp);
projection = Matrix(tmp);
Matrix bias_matrix(0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5 + bias, 1.0);
return (projection * bias_matrix);
}
void SetupTexGen(double bias)
{
Matrix texmat;
Matrix mv, imv;
{
double tmp[16];
glGetDoublev(GL_MODELVIEW_MATRIX, tmp);
mv = Matrix(tmp);
imv = mv.GetInverse();
}
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_S, GL_EYE_PLANE, imv.Row(0));
glEnable(GL_TEXTURE_GEN_S);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_T, GL_EYE_PLANE, imv.Row(1));
glEnable(GL_TEXTURE_GEN_T);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_R, GL_EYE_PLANE, imv.Row(2));
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
glTexGendv(GL_Q, GL_EYE_PLANE, imv.Row(3));
glEnable(GL_TEXTURE_GEN_Q);
texmat = CreateTextureMatrix(bias);
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
glMultMatrixd(texmat);
glMatrixMode(GL_MODELVIEW);
}
[/コード]
HTH。