gpt4 book ai didi

opengl - 使用着色器在 2D 环境中实现视野

转载 作者:行者123 更新时间:2023-12-04 05:04:54 24 4
gpt4 key购买 nike

我正在实现动态视野。我决定使用着色器以使照明效果更好看以及它如何影响墙壁。这是我正在处理的场景:
http://i.imgur.com/QxZVyo7.jpg

  • 我有一张 map ,地板和墙壁都是平的。这里的所有东西都是 2d 的,没有 3d 几何体,只有构成墙壁的 2d 多边形。
  • 使用我转换阴影的多边形的顶点来定义可视区域。 (紫色线条是我下一步使用的面膜的一部分)
  • 在场景顶部绘制阴影时使用着色器,我避免墙壁也被遮挡。
  • 这样,随着视野的变化,阴影会沿着墙壁动态转换

  • 我使用以下着色器来实现这一点。但我觉得这有点矫枉过正,而且效率很低:
    uniform sampler2D texture;
    uniform sampler2D filterTexture;
    uniform vec2 textureSize;
    uniform float cellSize;
    uniform sampler2D shadowTexture;



    void main()
    {
    vec2 position;
    vec4 filterPixel;
    vec4 shadowPixel;
    vec4 pixel = texture2D(texture, gl_TexCoord[0].xy );


    for( float i=0 ; i<=cellSize*2 ; i++)
    {
    position = gl_TexCoord[0].xy;
    position.y = position.y - (i/textureSize.y);
    filterPixel = texture2D( filterTexture, position );

    position.y = position.y - (1/textureSize.y);
    shadowPixel = texture2D( texture, position );

    if (shadowPixel == 0){
    if( filterPixel.r == 1.0 )
    {
    if( filterPixel.b == 1.0 ){
    pixel.a = 0;
    break;
    }
    else if( i<=cellSize )
    {
    pixel.a = 0;
    break;
    }
    }
    }
    }

    gl_FragColor = pixel;
    }

    迭代每个帧只是为了寻找蒙版中的红色像素似乎是一个巨大的过载,但我看不出如何通过使用着色器以任何其他方式完成这个任务。

    最佳答案

    这里的解决方案非常简单:使用阴影贴图。

    您的情况可能是 2D 而不是 3D,但基本概念是相同的。您想根据世界上的某个点和“光源”(在您的情况下,玩家角色)之间是否存在障碍表面来“阴影”区域。

    在 3D 中,阴影贴图通过从光源的角度渲染世界来工作。这会产生一个 2D 纹理,其中的值表示从光(在特定方向上)到最近的障碍物的深度。当您真实地渲染场景时,您可以通过将当前片段投影到 2D 深度纹理(阴影贴图)中来检查当前片段的位置。如果您为当前片段计算的深度值比阴影贴图中投影位置中最近的障碍物更近,则该片段在灯光下可见。如果不是,那就不是。

    您的 2D 版本必须做同样的事情,只是少了一个维度。您从“光源”的角度渲染您的 2D 世界。在这种情况下,您的 2D 世界实际上只是阻塞的四边形(您必须使用线多边形填充来渲染它们)。任何阻碍视线的四边形都应渲染到阴影贴图中。纹理访问完全没有必要;您需要的唯一信息是深度。您的着色器甚至不必编写颜色。您可以通过将 2D 空间投影到 1D 纹理中来渲染这些对象。

    这看起来像这样:

           X..X
    XXXXXXXX..XXXXXXXXXXXXXXXXXXXX
    X.............\.../..........X
    X..............\./...........X
    X...............C............X
    X............../.\...........X
    X............./...\..........X
    X............/.....\.........X
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    C是角色的位置;这些点只是规则的、无障碍的地板。 X s 是墙壁。来自 C 的线路代表您需要从中渲染 2D 线的四个方向。

    在 3D 中,要对点光源进行阴影贴图,您必须将场景渲染 6 次,从 6 个不同的方向进入立方体阴影贴图的面。在 2D 中,您必须在 4 个不同的方向上将场景渲染 4 次,从而生成 4 个不同的 1D 阴影贴图。您可以为此使用一维数组纹理。

    有了阴影贴图后,您只需在着色器中使用它们来检测片段何时可​​见。为此,您需要一组从窗口空间到 4 个不同投影的变换,这些投影代表您渲染的 4 个 View 方向。根据片段相对于目标的位置,只有其中一个将用于任何特定片段。

    为了实现这一点,我首先要让一个简单的定向“阴影”案例起作用。也就是说,不要使用位置;只是一个“光”的方向。这将测试您开发 2D 到 1D 投影矩阵以及适当的相机空间矩阵以将您的世界空间四边形转换为相机空间的能力。一旦你掌握了这一点,你就可以用不同的预测来做 4 次。

    关于opengl - 使用着色器在 2D 环境中实现视野,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15658031/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com