Opengl es 在UV坐标中查找屏幕像素的大小以供片段着色器使用
我有一个非常详细的纹理(带有假颜色信息,我在片段着色器中使用假颜色查找进行渲染)。我的问题是,有时用户将缩放到远离此纹理的地方,精细的细节将丢失:无法看到纹理中的细线。我想修改我的代码,使这些行弹出 我的想法是,我可以在相邻的文本上运行快速过滤器,并选择要渲染的最大/最小/最有趣的值。我不确定该如何做的是找出是否(以及多少)要这样做。当用户被放大成三角形时,我需要标准的查找。缩小后,屏幕上的单个像素将映射到多个纹理像素 我如何得到这个估计?我用正字法和透视法相机都能做到这一点 我的想法是,我可以以某种方式使用顶点着色器来估计UV空间中的一个屏幕像素有多大,并将其作为一个变量传递给片段着色器,但我仍然没有对变换和空间有足够的把握来获得这个想法 我当前的顶点着色器非常简单:Opengl es 在UV坐标中查找屏幕像素的大小以供片段着色器使用,opengl-es,webgl,shader,fragment-shader,Opengl Es,Webgl,Shader,Fragment Shader,我有一个非常详细的纹理(带有假颜色信息,我在片段着色器中使用假颜色查找进行渲染)。我的问题是,有时用户将缩放到远离此纹理的地方,精细的细节将丢失:无法看到纹理中的细线。我想修改我的代码,使这些行弹出 我的想法是,我可以在相邻的文本上运行快速过滤器,并选择要渲染的最大/最小/最有趣的值。我不确定该如何做的是找出是否(以及多少)要这样做。当用户被放大成三角形时,我需要标准的查找。缩小后,屏幕上的单个像素将映射到多个纹理像素 我如何得到这个估计?我用正字法和透视法相机都能做到这一点 我的想法是,我可以
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我不这么认为;上述增编