如何仅剪切裁剪平面的交集(而不是并集)?

3
在OpenGL / JOGL中,使用多个剪裁平面时,似乎应用所有剪裁平面的并集。我想要的是应用所有剪切平面的交集。这可能吗?请参见下面简化的2D示例。

enter image description here

编辑:顶点着色器剪裁的示例(请参见下面的注释)。 enter image description here


你不能只使用片段着色器来计算像素是否在你想要渲染的区域中吗?如果不是,就调用 discard; - fintelia
@fintelia 是的!这正是我在你刚回答的问题中所说的“测试”。 - martinez314
2个回答

1
多遍处理:
#include <GL/glut.h>

void scene()
{
    glColor3ub( 255, 0, 0 );
    glBegin( GL_QUADS );
    glVertex2i( -1, -1 );
    glVertex2i(  1, -1 );
    glVertex2i(  1,  1 );
    glVertex2i( -1,  1 );
    glEnd();
}

void display()
{
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    double w = glutGet( GLUT_WINDOW_WIDTH );
    double h = glutGet( GLUT_WINDOW_HEIGHT );
    double ar = w / h;
    glOrtho( -2 * ar, 2 * ar, -2, 2, -1, 1);

    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    glEnable( GL_CLIP_PLANE0 );

    // -y plane
    GLdouble plane0[] = { -1, 0, 0, 0 };
    glClipPlane( GL_CLIP_PLANE0, plane0 );

    scene();

    // -x plane
    GLdouble plane1[] = { 0, -1, 0, 0 };
    glClipPlane( GL_CLIP_PLANE0, plane1 );

    scene();

    glutSwapBuffers();
}

int main( int argc, char **argv )
{
    glutInit( &argc, argv );
    glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE );
    glutInitWindowSize( 640, 480 );
    glutCreateWindow( "Clipping" );
    glutDisplayFunc( display );
    glutMainLoop();
    return 0;
}

1
使用glClipPlane,不会被剪辑的顶点是在至少一个平面的正半空间内。一旦发生这种情况,其他任何平面都无关紧要。
但是,你可以通过在顶点着色器中写入适当的值到gl_ClipDistance来获得此效果(或几乎任何其他效果)。
任何插值值小于0.0(“负半空间”)的部分都将被剪切,你可以写入任何你喜欢的值,例如到一个点的平方距离,或到两个平面的距离之和,或者任何你计算出来的东西。

能否使用 gl_ClipVertex 来达到同样的目的?因为在我的OpenGL 2.1项目中无法使用 gl_ClipDistance - martinez314
是的,但正如您链接的问题中所解释的那样,它会稍微复杂一些。您需要为剪辑平面提供4个组成部分的点,这些点在相同的坐标系中,而不仅仅是单个“距离值”,该值不需要在任何特定的坐标系中,因为它只是一个告诉OpenGL“多近”您认为该点被剪辑的值。 - Damon
我在概念上很难从gl_ClipDistance跳到gl_ClipVertex。我能找到的每个gl_ClipVertex示例都只是gl_ModelViewMatrix * gl_Vertex。如果能看到使用gl_ClipVertex修改剪裁平面的示例,就像您描述如何使用gl_ClipDistance一样,那将非常有帮助。我尝试在我的顶点着色器中将gl_ClipVertex设置为各种修改后的顶点,但从未看到任何相对于被剪裁的内容发生变化。如果您能发布一个示例,那将非常有帮助。 - martinez314
gl_ClipVertex这个名称是一个误称,因为它虽然看起来像一个顶点,有4个分量,但实际上它是一个平面方程,而不是一个顶点。也就是说,它是一个法向量加上到原点的距离gl_ClipDistance是平面和顶点的点积,或者说是“顶点距离被裁剪的距离”,这个概念更容易理解。将gl_ClipVertex设置为实际的顶点可能不会给出很多有意义的输出,因为通常情况下_w = 1.0_--所以除非一个顶点非常靠近原点,否则你会一直进行裁剪。 - Damon
通过这种方法,我正在剪切顶点,而不是三角形原语。所以我不应该期望有干净的线条,对吗?我是否正确地假设我需要自己处理重新计算分裂三角形(也许在几何着色器中)?还是我错过了一个简单的解决方案?(顺便说一句,我上面遇到的问题与我的片段着色器以某种方式隐藏了gl_ClipVertex的效果有关 - 很明显我还需要学习一些GLSL知识。) - martinez314
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接