opengl - 显示 2 个半透明对象的公共(public)部分?

标签 opengl testing transparency intersection depth

我正在创建一个数学应用程序,它使用 OpenGL 来显示多个几何 3D 形状。在某些情况下,这些形状相交,当这种情况发生时,我想显示每个形状的相交部分。由于两种形状都是半透明的,所以我需要的大致是这样的:

Perfect intersection

但是,使用 2 个半透明球体时,我得到的结果是:

With depth testing

我知道,要获得正确的透明效果,应该在绘制透明形状之前关闭深度测试。然而,当透明形状超出另一个非透明形状时,这会导致另一个副作用:

Without depth testing

那么,有没有办法在不破坏深度测试的情况下正确显示 2 个体积形状的相交部分?

最佳答案

So, is there a way to show (…) volumetric shapes

OpenGL(本身)并不知道“体积”。它知道平面三角形、直线和点,这些纯属偶然也可能导致渲染副作用,例如通过深度缓冲区测试进行深度排序。

从技术上讲,可以链接一系列绘图和模板缓冲区操作来执行 CSG(构造立体几何);见ftp://ftp.sgi.com/opengl/contrib/blythe/advanced99/notes/node22.html了解详情。

但是,通过在片段着色器中执行一个简单的光线追踪器,可以更轻松地实现您想要做的事情。现在光线追踪本身就是一个广泛的主题,你可以写满书(实际上很多书都是关于这个主题的)。最好引用一个例子。在这种情况下,我引用以下 ShaderToy https://www.shadertoy.com/view/ldS3DW – 该着色器的略微简化版本绘制了您感兴趣的交叉几何形状:

float sphere(vec3 ray, vec3 dir, vec3 center, float radius)
{
    vec3 rc = ray-center;
    float c = dot(rc, rc) - (radius*radius);
    float b = dot(dir, rc);
    float d = b*b - c;
    float t = -b - sqrt(abs(d));
    float st = step(0.0, min(t,d));
    return mix(-1.0, t, st);
}


void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
    vec2 uv = (-1.0 + 2.0*fragCoord.xy / iResolution.xy) * 
        vec2(iResolution.x/iResolution.y, 1.0);

    vec3 ro = vec3(0.0, 0.0, -3.0);
    vec3 rd = normalize(vec3(uv, 1.0));

    vec3 p0 = vec3(0.5, 0.0, 0.0);
    float t0 = sphere(ro, rd, p0, 1.0);

    vec3 p1 = vec3(-0.05, 0.0, 0.0);
    float t1 = sphere(ro, rd, p1, 1.0);

    fragColor = vec4( step(0.0,t0)*step(0.0,t1)*rd, 1.0 );
}

关于opengl - 显示 2 个半透明对象的公共(public)部分?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47682437/

相关文章:

java - OpenGL Ortho中相同顶点之间的这些像素间隙的来源是什么?如何消除它们?

c++ - FBO 在 OSX 中无法正常工作

html - 这些链接的顶部不起作用,我怎样才能获得按钮内的链接?

colors - GIMP - Alpha 到颜色

c# WPF 对 Winform 控件的透明性

c++ - 使用 CGL 编译 MacOS 应用程序

opengl - 如何在 PyOpenGL 中将纹理复制到 pbo 中?

design-patterns - 单例测试和子类化

testing - 在 BDD 测试中时不时地混合使用

unit-testing - 如何验证是否使用 Spock 中的一组指定元素调用了方法?