Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opengl es 在UV坐标中查找屏幕像素的大小以供片段着色器使用_Opengl Es_Webgl_Shader_Fragment Shader - Fatal编程技术网

Opengl es 在UV坐标中查找屏幕像素的大小以供片段着色器使用

Opengl es 在UV坐标中查找屏幕像素的大小以供片段着色器使用,opengl-es,webgl,shader,fragment-shader,Opengl Es,Webgl,Shader,Fragment Shader,我有一个非常详细的纹理(带有假颜色信息,我在片段着色器中使用假颜色查找进行渲染)。我的问题是,有时用户将缩放到远离此纹理的地方,精细的细节将丢失:无法看到纹理中的细线。我想修改我的代码,使这些行弹出 我的想法是,我可以在相邻的文本上运行快速过滤器,并选择要渲染的最大/最小/最有趣的值。我不确定该如何做的是找出是否(以及多少)要这样做。当用户被放大成三角形时,我需要标准的查找。缩小后,屏幕上的单个像素将映射到多个纹理像素 我如何得到这个估计?我用正字法和透视法相机都能做到这一点 我的想法是,我可以

我有一个非常详细的纹理(带有假颜色信息,我在片段着色器中使用假颜色查找进行渲染)。我的问题是,有时用户将缩放到远离此纹理的地方,精细的细节将丢失:无法看到纹理中的细线。我想修改我的代码,使这些行弹出

我的想法是,我可以在相邻的文本上运行快速过滤器,并选择要渲染的最大/最小/最有趣的值。我不确定该如何做的是找出是否(以及多少)要这样做。当用户被放大成三角形时,我需要标准的查找。缩小后,屏幕上的单个像素将映射到多个纹理像素

我如何得到这个估计?我用正字法和透视法相机都能做到这一点

我的想法是,我可以以某种方式使用顶点着色器来估计UV空间中的一个屏幕像素有多大,并将其作为一个变量传递给片段着色器,但我仍然没有对变换和空间有足够的把握来获得这个想法

我当前的顶点着色器非常简单:

  varying vec2 vUv;
  varying vec3 vPosition;
  varying vec3 vNormal;
  varying vec3 vViewDirection;

   void main() {
       vUv = uv;
       vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
       vPosition = (modelMatrix *
           vec4(position,1.0)).xyz;
       gl_Position = projectionMatrix * mvPosition;
      vec3 transformedNormal = normalMatrix *  vec3( normal );
      vNormal = normalize( transformedNormal );
      vViewDirection = normalize(mvPosition.xyz);
   }
如何得到像vDeltaUV这样的东西,它以UV为单位给出屏幕像素之间的距离

约束:我在WebGL中工作,在three.js中

以下是一幅图像的示例,其中用户放大了接近“我的纹理”的透视图:

这里是相同的例子,但缩小了;上面的特征是靠近中心的一条几乎看不见的对角线(参见坐标以获得比例感)。我希望这一行通过使用对应文本数组的红色est颜色渲染所有像素来弹出

附录(关于LJ的意见)。。。 不,我不认为mipmapping能满足我的要求,原因有二

首先,我没有实际映射纹理;也就是说,我在做这样的事情:

   gl_FragColor = texture2D(mappingtexture,  texture2d(vec2(inputtexture.g,inputtexture.r))
   float x = ... the u coordinate in pixels in the input texture
   float y = ... the v coordinate in pixels in the input texture
   vec4 inc = get_encoded_adc_value(x,y);

   // Extremum mapping:
   if(pixel_ratio>2.0) {
    inc = most_extreme_value(inc, get_encoded_adc_value(x+1.0, y));
   }
   if(pixel_ratio>3.0) {
    inc = most_extreme_value(inc, get_encoded_adc_value(x-1.0, y));    
  }
用户动态创建mappingtexture,允许我实时更改假颜色贴图。我认为这实际上是我的应用程序的一个非常优雅的解决方案

其次,我不想画相邻像素的平均值(即平滑),我想要相邻像素的最极值(即更类似于边缘查找的东西)。在这种情况下,“极端”在技术上是由我对输入纹理中的g/r颜色值进行编码定义的

解决方案: 多亏了下面的答案,我现在有了一个有效的解决方案

在我的javascript代码中,我必须添加:

  extensions: {derivatives: true}
我对ShaderMaterial的声明。然后在我的片段着色器中:

   float dUdx = dFdx(vUv.x); // Difference in U between this pixel and the one to the right.
  float dUdy = dFdy(vUv.x); // Difference in U between this pixel and the one to the above.
  float dU = sqrt(dUdx*dUdx + dUdy*dUdy);
  float pixel_ratio = (dU*(uInputTextureResolution));
这让我可以做这样的事情:

   gl_FragColor = texture2D(mappingtexture,  texture2d(vec2(inputtexture.g,inputtexture.r))
   float x = ... the u coordinate in pixels in the input texture
   float y = ... the v coordinate in pixels in the input texture
   vec4 inc = get_encoded_adc_value(x,y);

   // Extremum mapping:
   if(pixel_ratio>2.0) {
    inc = most_extreme_value(inc, get_encoded_adc_value(x+1.0, y));
   }
   if(pixel_ratio>3.0) {
    inc = most_extreme_value(inc, get_encoded_adc_value(x-1.0, y));    
  }
效果是微妙的,但肯定有!台词跳得更清楚了


谢谢你的帮助

在顶点着色器中无法执行此操作,因为它是预光栅化阶段,因此输出分辨率不可知,但在片段着色器中,可以使用
GL_OES_标准_导数
扩展(几乎无处不在)来估计采样足迹


如果不实时更新纹理,则更简单、更有效的解决方案是在CPU上为纹理生成自定义mip级别

看起来很有趣。我会看看是否有关于这些函数的教程。纹理确实是动态生成的,因此在实时应用程序中这很耗时。即使我有它们,我仍然需要一种可靠的方法来选择要使用的纹理。GPU已经为您完成了这项工作,这就是mip映射的全部内容,选择最接近1:1 texel/屏幕像素比的mip级别。如果纹理是每帧生成的,并且缩放级别非常小(如2-4缩小),则使用您的方法(如,不使用建议的生成自定义mip贴图的方法)会更快,在其他任何情况下,mipmap都会更快,如果CPU成为瓶颈,你也可以将负载转移到GPU上。@LJ我不这么认为;上述增编