小编nom*_*ncy的帖子

如何在opengl中实现z-fail算法?

我代码作为NeHe导师Lesson27告诉我,但它是一个z-pass算法.当我在阴影中时,阴影消失.有人告诉我,我可以使用z-fail算法来解决这个问题.所以我花了两天时间来研究z-fail算法.最后,我无法弄明白.我的程序永远不会像我想的那样运行.

作为wiki列出的z-fail算法:

深度失败在2000年左右,有几个人发现Heidmann的方法可以通过反转深度来适用于所有摄像机位置.而不是计算对象表面前面的阴影表面,它后面的表面可以很容易地计算,具有相同的最终结果.这解决了眼睛处于阴影中的问题,因为眼睛和物体之间的阴影体积不计算,但是引入了阴影体积的后端必须加盖的条件,或者阴影将最终丢失在体积指向的位置向后无穷大.

  1. 禁用对深度和颜色缓冲区的写入.

  2. 使用正面剔除.

  3. 将模板操作设置为在深度失败时递增(仅计算对象后面的阴影).

  4. 渲染阴影卷.

  5. 使用背面剔除.

  6. 将模板操作设置为在深度失败时递减.

  7. 渲染阴影卷.

我认为的主要问题是深度测试.在步骤3和6,模板操作基于深度失败.虽然它可以显示阴影,但它可能在它之前的对象上阴影(即:深度缓冲值小于它的对象).所有阴影效果看起来很乱.

但是在z-pass算法中,模板操作基于深度通过,这意味着它不仅可以显示阴影,而且仅在其后面的对象上阴影,符合眼睛系统.

所以如何解决这个问题使我的深度失败算法显示出正确对象的阴影.

这是我的z-fail算法代码(某处可能在哪里,请帮我看看,阴影效果很糟糕)

VECTOR vec;        
void shadowvolume(SECTOR &sec,float *lp)
{
    unsigned int    p1, p2;
    VECTOR          v1, v2;
    int i, j, k, jj;
    for (i=0; i<sec.numplanes;i++)
    {
        if (sec.planes[i].visible)
        {
            for (j=0;j<3;j++)
            {
                k = sec.planes[i].neigh[j];
                if ((!k) || (!sec.planes[k-1].visible))//????k??????????????????????
                {
                    // here we have an edge, we must draw a polygon
                    p1 = sec.planes[i].p[j]-1;//?????
                    jj = (j+1)%3;           
                    p2 = sec.planes[i].p[jj]-1;//?????

                    //calculate the length of the vector
                    v1.x = (sec.points[p1].vec.x …
Run Code Online (Sandbox Code Playgroud)

opengl shadow stencil-buffer

6
推荐指数
1
解决办法
1495
查看次数

标签 统计

opengl ×1

shadow ×1

stencil-buffer ×1