将投影应用于一半的纹理 [英] Apply Projection on half of texture

查看:124
本文介绍了将投影应用于一半的纹理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用三个glcontrol,例如GlControl1,GlControl2,GlControl3. 我有两个纹理stexture1和stexture2. glcontrol2中显示stexture1的位置. stexture2的右半部分显示在glcontrol1上,而左半部分则在glcontrol3上令人失望. 现在,我要在这三个glcontrols上应用投影.使用此链接我可以在glcontrol2上成功应用它,因为它可以完全显示纹理.

I'm using three glcontrols say GlControl1, GlControl2, GlControl3. And I have two textures stexture1 and stexture2. Where stexture1 is displaying in glcontrol2. And right half portion of stexture2 is displaying on glcontrol1 and left half is dispalying on glcontrol3. Now I want to apply projection on these three glcontrols. Using this link I can apply it successfully on glcontrol2 since it is displaying the texture fully.

但是当在glcontrol1和glcontrol3上应用时,它不能很好地工作.

But when applying on glcontrol1 and glcontrol3 it is not working well.

请查看我尝试使用的着色器代码.

Please see the shader code I'm trying with.

   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));

        }

推荐答案

如果您不想使废弃"区域变形,只需保留原始纹理坐标即可:

If you don't want to distort the "discarded" area, the just keep the original texture coordinate:

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);
}


根据问题的变化进行


Edit according to the changes of the question:

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

If you just want to show a part of the texture, then you've to map the texture coordinate from the range [0, 1] to the range [left, right], when the texture is looked up:

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

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

Apply this to your code as follows:

例如:

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 );
    }

    // [...]

}

这篇关于将投影应用于一半的纹理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆