Opengl es OpenGL中的贴纸/贴花:绘制纹理而不拉伸从夹具到边缘?

Opengl es OpenGL中的贴纸/贴花:绘制纹理而不拉伸从夹具到边缘?,opengl-es,shader,Opengl Es,Shader,基本上是在飞机上做贴纸。纹理图像显示在平面上(可以四处移动),但我不想将图像拉伸到边缘或重复它。我怎么能把图像像贴纸一样贴在墙上?我正在使用着色器,不知道这是否是我解决问题的地方。假设棋盘是我的图像,会发生以下情况: 您可以将范围检查合并到着色器中。将“clamp_”设置为“_edge”会影响仅从采样返回的像素,因此当您处于不希望输出任何像素的区域时,进入着色器的纹理坐标仍将超出从0到1的范围。在目前常用于GL ES的硬件上,传递alpha为0的颜色比丢弃要快,因此如果混合模式允许,请这样做 例

基本上是在飞机上做贴纸。纹理图像显示在平面上(可以四处移动),但我不想将图像拉伸到边缘或重复它。我怎么能把图像像贴纸一样贴在墙上?我正在使用着色器,不知道这是否是我解决问题的地方。假设棋盘是我的图像,会发生以下情况:


您可以将范围检查合并到着色器中。将“clamp_”设置为“_edge”会影响仅从采样返回的像素,因此当您处于不希望输出任何像素的区域时,进入着色器的纹理坐标仍将超出从0到1的范围。在目前常用于GL ES的硬件上,传递alpha为0的颜色比丢弃要快,因此如果混合模式允许,请这样做

例如,假设您当前只有最普通的纹理片段着色器:

void main()
{
    gl_FragColor = texture2D(tex2D, texCoordVarying);
}
你可以选择:

void main()
{
    if(clamp(texCoordVarying, vec2(0.0, 0.0), vec2(1.0, 1.0)) == texCoordVarying)
        gl_FragColor = texture2D(tex2D, texCoordVarying);
    else
        gl_FragColor = vec4(0.0); // or discard, if you need to
}
但是,显式范围检查将增加处理成本。显然,只有当它成为一个问题时才需要担心,但这种情况下的解决方案只是在纹理中添加一个边框。因此,如果您的纹理是256x256,那么您将使用中心254x254像素,并在外部放置一个完全透明的边框


编辑:想得更清楚一些,如果可以接受alpha而不是discard,那么可以使用step函数来消除条件。对每个轴上的每个限制重复四次-一次,在需要大于测试而不是小于测试的地方反转结果,然后将输出alpha乘以所有四个结果。如果任何一个为零,则输出alpha将为零。

您可以将范围检查合并到着色器中。将“clamp_”设置为“_edge”会影响仅从采样返回的像素,因此当您处于不希望输出任何像素的区域时,进入着色器的纹理坐标仍将超出从0到1的范围。在目前常用于GL ES的硬件上,传递alpha为0的颜色比丢弃要快,因此如果混合模式允许,请这样做

例如,假设您当前只有最普通的纹理片段着色器:

void main()
{
    gl_FragColor = texture2D(tex2D, texCoordVarying);
}
你可以选择:

void main()
{
    if(clamp(texCoordVarying, vec2(0.0, 0.0), vec2(1.0, 1.0)) == texCoordVarying)
        gl_FragColor = texture2D(tex2D, texCoordVarying);
    else
        gl_FragColor = vec4(0.0); // or discard, if you need to
}
但是,显式范围检查将增加处理成本。显然,只有当它成为一个问题时才需要担心,但这种情况下的解决方案只是在纹理中添加一个边框。因此,如果您的纹理是256x256,那么您将使用中心254x254像素,并在外部放置一个完全透明的边框


编辑:想得更清楚一些,如果可以接受alpha而不是discard,那么可以使用step函数来消除条件。对每个轴上的每个限制重复四次-一次,在需要大于测试而不是小于测试的地方反转结果,然后将输出alpha乘以所有四个结果。如果其中任何一个为零,则输出alpha将为零。

请改用“钳制到”边框,不要忘记设置边框颜色。

改用“钳制到”边框,不要忘记设置边框颜色。

遗憾的是,GL ES中忽略了边框。请参见-“指定边框的宽度。必须为0。”遗憾的是,GL ES中忽略了边框。请参见-“指定边框的宽度。必须为0。”