【问题标题】:Display three textures equally on openGL control - OpenTK C#在openGL控件上平均显示三个纹理 - OpenTK C#
【发布时间】:2019-03-15 03:04:26
【问题描述】:

我有三个纹理应该显示在 opengl 控件上,这三个纹理应该同样包含在其中。意味着 texture1 应该在 glcontrol 的 0 到 0.33 之间。并且texture2 应该在0.33 到0.66 和texture3 中保持原位。我已经完成了如下操作。但是中间图像的右侧部分区域模糊。请帮忙改正

   private void CreateShaders()
    {
        /***********Vert Shader********************/
        vertShader = GL.CreateShader(ShaderType.VertexShader);
        GL.ShaderSource(vertShader, @"attribute vec3 a_position;
                                    varying vec2 vTexCoordIn; 
         void main() {
            vTexCoordIn=( a_position.xy+1)/2 ;                                 
            gl_Position = vec4(a_position,1);
          }");
           GL.CompileShader(vertShader);

        /***********Frag Shader ****************/
        fragShader = GL.CreateShader(ShaderType.FragmentShader);
        GL.ShaderSource(fragShader, @"
    uniform sampler2D sTexture1;
    uniform sampler2D sTexture2;
    uniform sampler2D sTexture3;     
    varying vec2 vTexCoordIn;
    void main ()
    {                                               
    vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);
    if ( vTexCoord.x<0.3 )
    gl_FragColor = texture2D (sTexture1, vec2(vTexCoord.x*2.0, vTexCoord.y));
    else if ( vTexCoord.x>=0.3 && vTexCoord.x<=0.6 )
    gl_FragColor = texture2D (sTexture2, vec2(vTexCoord.x*2.0, vTexCoord.y));
    else
    gl_FragColor = texture2D (sTexture3, vec2(vTexCoord.x*2.0, vTexCoord.y));
 }");
        GL.CompileShader(fragShader);
    }

【问题讨论】:

    标签: c# opengl glsl fragment-shader opentk


    【解决方案1】:

    意味着texture1 应该在glcontrol 的0 到0.33 之间。而且texture2应该在0.33到0.66之间,texture3在原地。

    如果纹理坐标在 [0, 0.33] 范围内,则必须绘制 sTexture1,并且必须将纹理坐标从 [0, 0.33] 映射到 [0, 1]:

    if ( vTexCoord.x < 1.0/3.0 )
        gl_FragColor = texture2D(sTexture1, vec2(vTexCoord.x * 3.0, vTexCoord.y));
    

    如果纹理坐标在 [0.33, 0.66] 范围内,则必须绘制 sTexture2,并且必须将纹理坐标从 [0.33, 0.66] 映射到 [0, 1]:

    else if ( vTexCoord.x >= 1.0/3.0 && vTexCoord.x < 2.0/3.0 )
        gl_FragColor = texture2D(sTexture2, vec2(vTexCoord.x * 3.0 - 1.0, vTexCoord.y));
    

    如果纹理坐标在 [0.66, 1] 范围内,则必须绘制 sTexture3,并且必须将纹理坐标从 [0.66, 1] 映射到 [0, 1]:

    else if ( vTexCoord.x >= 2.0/3.0 )
        gl_FragColor = texture2D(sTexture2, vec2(vTexCoord.x * 3.0 - 2.0, vTexCoord.y));
    

    【讨论】:

    • 它得到了!。你能解释一下为什么需要乘以 3 吗?在最后一个循环中,为什​​么要减去 2.0?
    • @nds 映射从 [0.66, 1] 到 [0, 1] :0.66*3 - 2 = 01*3 - 2 = 1。注意,每个纹理的纹理坐标在 [0, 1] 范围内
    • 谢谢。看起来纹理的纵横比丢失了。例如:如果使用以下代码: if (vTexCoord.x
    • 设置为 gl_Position = vec4(a_position,1);
    • aspect 表示图像的纵横比?还是关键字?
    【解决方案2】:
    gl_FragColor = texture2D (sTexture3, vec2(vTexCoord.x*2.0, vTexCoord.y));
                                                         ^^^^
    

    如果 x >= 0.5,将 x 坐标乘以 2.0 会导致值超过 1.0。如果您的采样器设置为 CLAMP_TO_EDGE(似乎是这种情况),这会导致在纹理边缘重复采样相同的纹素(这将显示为您提到的拖尾/模糊)。

    【讨论】:

    • 我有这些行:GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.ClampToEdge); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.ClampToEdge);当我评论这条线时,一个放大的输出正在得到
    猜你喜欢
    • 2019-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-10
    • 2012-11-22
    相关资源
    最近更新 更多