【问题标题】:Apply Projection on half of texture在纹理的一半上应用投影
【发布时间】:2019-11-23 19:03:03
【问题描述】:

我正在使用三个 glcontrols 说 GlControl1、GlControl2、GlControl3。 我有两个纹理 stexture1 和 stexture2。 stexture1 在 glcontrol2 中显示的位置。 stexture2 的右半部分显示在 glcontrol1 上,左半部分显示在 glcontrol3 上。 现在我想在这三个 glcontrols 上应用投影。使用这个link,我可以在glcontrol2 上成功应用它,因为它可以完全显示纹理。

但是在 glcontrol1 和 glcontrol3 上应用时,它不能正常工作。

请查看我正在尝试的着色器代码。

   GL.ShaderSource(fragShader, @"precision highp float;
    uniform sampler2D sTexture_1;
    uniform sampler2D sTexture_2;
    uniform float sSelectedRangeLeft;   
    uniform float sSelectedRangeRight;
    uniform float sSelectedRangeLeftEnd;   
    uniform float sSelectedRangeRightEnd;     
    uniform int sCurrentGLControl;
    varying vec2 vTexCoordIn;
    void main ()
    {
    vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);

   float rightsliderStartval=sSelectedRangeRight;//0.5(value between 0.5 and 1.0)
   float rightsliderEndval=sSelectedRangeRightEnd;//1.0(value between 0.5 and 1.0)
   float rightsliderDelta=rightsliderEndval-rightsliderStartval;

   float leftsliderStartval=sSelectedRangeLeftEnd;//0.0(value between 0 and 0.5)
   float leftsliderEndval=sSelectedRangeLeft;//0.5(value between 0 and 0.5)
   float leftsliderDelta=leftsliderEndval-leftsliderStartval;

 if(sCurrentGLControl==1)
 { 
 if ( vTexCoord.x <=1.0 &&  vTexCoord.x > 1.0 -rightsliderDelta)
 {
 vec4 colorLeft=texture2D (sTexture_2, vec2(vTexCoord.x -(1.0-rightsliderEndval), vTexCoord.y));
//i want to show this result in a projected view like glcontrol2
 gl_FragColor  = colorLeft;
 }
 }
 else if(sCurrentGLControl==3) 
 { 
  if ( vTexCoord.x <=leftsliderDelta )
 {
  vec4 colorRight=texture2D (sTexture_2, vec2((vTexCoord.x)+leftsliderStartval, vTexCoord.y+sSelectedRightEndVerticalShift));
   //i want to show this result in a projected view like glcontrol2
    gl_FragColor  = colorRight;  
   }
  }

else if(sCurrentGLControl==2) 
 {  //Projection works fine 
vec2  pos     = vTexCoord.xy * 2.0 - 1.0;
float b       = 0.3;
float v_scale = (1.0 + b) / (1.0 + b * sqrt(1.0 - pos.x*pos.x));
float u = asin( pos.x ) / 3.1415 + 0.5;
float v = (pos.y * v_scale) * 0.5 + 0.5;
if ( v < 0.0 || v > 1.0 )
  discard;
vec3 texColor = texture2D( sTexture_1, vec2(u, v) ).rgb;
gl_FragColor  = vec4( texColor.rgb, 1.0 );   
  }
    }");

  ==================================================================
if (glControl.Name == "glControl1")
        {
            GL.Viewport(new Rectangle(-glControl.Width, 0, glControl.Width*2.0, glControl.Height));

        }
        else if (glControl.Name == "glControl2")
        {
            GL.Viewport(new Rectangle(0, 0, glControl.Width , glControl.Height));

        }
        else
        {
            GL.Viewport(new Rectangle(0, 0, glControl.Width*2.0, glControl.Height));

        }

【问题讨论】:

    标签: c# opengl glsl fragment-shader opentk


    【解决方案1】:

    如果你不想扭曲“丢弃”区域,只需保留原始纹理坐标即可:

    precision highp float;
    
    uniform sampler2D sTexture;
    varying vec2 vTexCoordIn;
    
    void main ()
    {
        vec2 uv = vTexCoordIn.xy
    
        if (vTexCoordIn.x >= 0.7 && vTexCoordIn.x <= 0.9)
        {
            vec2  pos     = vTexCoordIn.xy * 2.0 - 1.0;
            float b       = 0.3;
            float v_scale = (1.0 + b) / (1.0 + b * sqrt(1.0 - pos.x*pos.x));
    
            float u = asin( pos.x ) / 3.1415 + 0.5;
            float v = (pos.y * v_scale) * 0.5 + 0.5;
            if (v >= 0.0 && v <= 1.0)
              uv = vec2(u, v);
        }
    
        vec3 texColor = texture2D(sTexture, uv).rgb;
        gl_FragColor  = vec4(texColor.rgb, 1.0);
    }
    

    根据问题的变化进行编辑:

    如果您只想显示纹理的一部分,那么您必须在查找纹理时将纹理坐标从范围 [0, 1] 映射到范围 [left, right]:

    u = u * rightsliderDelta + rightsliderStartval;  
    vec3 texColor = texture2D( sTexture_2, vec2(u, v) ).rgb;
    

    将其应用到您的代码中,如下所示:

    例如:

    void main ()
    {
        vec2 vTexCoord=vec2(vTexCoordIn.x,vTexCoordIn.y);
    
        float rightsliderStartval=sSelectedRangeRight;//0.5(value between 0.5 and 1.0)
        float rightsliderEndval=sSelectedRangeRightEnd;//1.0(value between 0.5 and 1.0)
        float rightsliderDelta=rightsliderEndval-rightsliderStartval;
    
        // [...]
    
        if(sCurrentGLControl==1) {
    
            vec2  pos     =  vTexCoord.xy * 2.0 - 1.0;
            float b       = 0.3;
            float v_scale = (1.0 + b) / (1.0 + b * sqrt(1.0 - pos.x*pos.x));
            float u = asin( pos.x ) / 3.1415 + 0.5;
            float v = (pos.y * v_scale) * 0.5 + 0.5;
            if ( v < 0.0 || v > 1.0 )
                discard;
    
            u = u * rightsliderDelta + rightsliderStartval;   
            vec3 colorLeft = texture2D( sTexture_2, vec2(u, v) ).rgb;
            gl_FragColor   = vec4( colorLeft .rgb, 1.0 );
        }
    
        // [...]
    
    }
    

    【讨论】:

    • 我想在附加图像的可见区域显示完整的投影。
    • 意味着,我想在丢弃区域以外的区域应用投影。现在屏幕截图看起来像图像显示在圆柱体的右半部分。圆柱体的左半部分是黑色的。我想显示该图像部分完全是圆柱形的。
    • 简而言之,我需要在 rightsliderStartval 和 rightsliderEndval 之间进行投影
    • 现在我在 glcontrol1 的某些点上变得模糊。在我的代码中,除了投影之外的所有其他部分都工作正常(因为这个 rightsliderStartval 和 rightsliderEndval 将随滑块而变化)。那么我可以用现有代码更正吗?例如在 glcontrol1 的情况下,投影应该应用于“ if ( vTexCoord.x 1.0 -rightsliderDelta){ vec4 colorLeft=texture2D (sTexture_2, vec2(vTexCoord.x -(1.0-rightsliderEndval) , vTexCoord.y));}"
    • @user2431727 我想我知道发生了什么。尝试答案中的新代码。 (我现在已经编辑过了。
    猜你喜欢
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 2014-12-19
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2021-10-06
    • 2016-01-04
    相关资源
    最近更新 更多