我应该如何读取片段着色器中相邻的纹理像素?

问题描述 投票:0回答:1

我刚刚开始学习Opengl,我正在使用Love2D作为框架构建一个“落沙”模拟。我天真的方法是采用从effect()函数传递的texture_coord参数并在将其输入texel()之前对其进行偏移。如果已经为此设计了一个内部解决方案,有人可以指出我正确的方向吗?

extern vec2 dim //the width and height of the display area

vec4 effect( vec4 color, Image tex, vec2 tCoords, vec2 sCoords ){
    
  //find the color of this cell's neighbors
  
  vec4 top = Texel(tex, vec2(tCoords.x,tCoords.y - 1/dim.y));
  //other neighbors excised for brevity
  
  vec4 self = Texel(tex, tCoords); //this pixel

  if (top == Yellow && self == Black){ //sand above and I'm empty
    self = Yellow;
  } 
  return self;
}

它有效。我只是好奇是否有更好的方法。

opengl fragment-shader love2d
1个回答
0
投票

您的代码看起来完全可以接受。但是,您可以根据您的具体要求和限制考虑一些优化和替代方案。

如果您的模拟需要从多个纹理(例如,针对不同的层或状态)进行采样,您可以考虑使用纹理数组或 3D 纹理,而不是单独的 2D 纹理。这可以简化您的采样逻辑并减少纹理查找的数量。顺便说一句,我希望您使用最近邻纹理过滤 (

GL_NEAREST
) 而不是线性过滤 (
GL_LINEAR
)。最近邻过滤将为您提供准确的纹素值,而无需在相邻纹素之间进行插值。 在 OpenGL 网站上阅读更多相关信息

对于大型模拟,使用“单独的缓冲区”来存储模拟状态可能比在同一通道中读取和写入纹理更有效。这可以减少纹理查找次数并简化着色器逻辑。 您的代码示例:

extern vec2 dim; //the width and height of the display area vec4 effect(vec4 color, Image tex, Image buffer, vec2 tCoords, vec2 sCoords) { // find the color of this cell's neighbors // Read from the buffer texture instead of tex vec4 top = Texel(buffer, vec2(tCoords.x, tCoords.y - 1.0 / dim.y)); // other neighbors excised for brevity vec4 self = Texel(buffer, tCoords); // read the current state from the buffer if (top == Yellow && self == Black) { // sand above and I'm empty // Write the updated state to the buffer return Yellow; } return self; // return the current state if no update is needed }

使用单独的缓冲区是否重要取决于模拟的具体要求和约束。
不过我会推荐它。

© www.soinside.com 2019 - 2024. All rights reserved.