显示图像选定部分的着色器代码 - OpenTk

Shader code to show selected part of image - OpenTk

我想在我的 glcontrol 中显示图像后半部分的选定区域(这是从 0.5 到 1.0 的范围)。为此,我使用了两个变量 rightsliderStartval(0.5 和 1.0 之间的任何值) 和 rightsliderEndval(1.0 到 0.5 之间的任何值)。我想要这个 rightsliderStartval 和 rightsliderEndval 之间的选定区域。当像下面这样尝试时,所选区域正在变大但它被拉伸了。

  decimal RateOfResolution = (decimal)videoSource.VideoResolution.FrameSize.Width / (decimal)videoSource.VideoResolution.FrameSize.Height;          
  int openGLwidth = (this._Screenwidth / 3) - 40;  
  int openGLheight = Convert.ToInt32(screenWidthbyThree / RateOfResolution); 
  glControl.Width = openGLwidth;
  glControl.Height = openGLheight;
  GL.Viewport(new Rectangle(0, 0, glControl.Width, glControl.Height));


 public 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, @"precision highp float;

    uniform sampler2D sTexture;
    varying vec2 vTexCoordIn;
    void main ()
    {
        vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);
        float rightsliderStartval=0.6;//0.5 to 1.0
        float rightsliderEndval=0.8;//1.0 to 0.5
        float rightsliderDelta=rightsliderEndval-rightsliderStartval;

     if (vTexCoordIn.x < 0.5)
     discard;
    float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);

   vec4 color = texture2D(sTexture, vec2(u, vTexCoordIn.y));
   gl_FragColor = color;


    }");
GL.CompileShader(fragShader);
   }

在屏幕截图中,白线代表图像的中心。我想显示黄色和橙色线之间的区域。

如果你想跳过纹理的某些部分,那么你可以使用discard关键字。此命令导致片段的输出值被丢弃,并且根本不绘制片段。

如果您有一个矩形区域并且只想在矩形区域的第二半部分绘制,那么您必须丢弃第一半部分的片段:

if (vTexCoordIn.x < 0.5)
    discard;

如果你想在第二半的矩形区域绘制rightsliderStartvalrightsliderEndval的范围,那么你必须映射范围[0.5, 1.0]传入纹理坐标vTexCoordIn.x 到 [rightsliderStartval, rightsliderEndval]:

float w = (vTexCoordIn.x-0.5) * 2.0;                      // [0.5, 1.0] -> [0.0, 1.0]
float u = mix(rightsliderStartval, rightsliderEndval, w); // [0.0, 1.0] -> [0.7, 0.9]

这导致片段着色器:

precision highp float;

uniform sampler2D sTexture;
varying vec2 vTexCoordIn;

void main ()
{
    float rightsliderStartval = 0.7;
    float rightsliderEndval   = 0.9;

    if (vTexCoordIn.x < 0.5)
        discard;

    float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);

    vec4 color = texture2D(sTexture, vec2(u, vTexCoordIn.y));
    gl_FragColor = color;
}

如果您不希望图像被拉伸,那么您有两种可能性。

丢弃从 0.0 到 0.7 和 0.9 到 1.0 的区域:

precision highp float;

uniform sampler2D sTexture;
varying vec2 vTexCoordIn;

void main ()
{
    float rightsliderStartval = 0.7;
    float rightsliderEndval   = 0.9;

    if (vTexCoordIn.x < 0.7 || vTexCoordIn.x > 0.9)
        discard;

    vec4 color = texture2D(sTexture, vTexCoordIn.xy));
    gl_FragColor = color;
}

或者在 y 方向也缩放图像:

precision highp float;

uniform sampler2D sTexture;
varying vec2 vTexCoordIn;

void main ()
{
    float rightsliderStartval = 0.7;
    float rightsliderEndval   = 0.9;

    if (vTexCoordIn.x < 0.5)
        discard;

    float u = mix(rightsliderStartval, rightsliderEndval, (vTexCoordIn.x-0.5) * 2.0);

    float v_scale = (rightsliderEndval - rightsliderStartval) / 0.5;
    float v = vTexCoordIn.y * v_scale + (1.0 - v_scale) / 2.0;;

    vec4 color = texture2D(sTexture, vec2(u, v));
    gl_FragColor = color;
}