Opengl 法线贴图生成-着色器和FBO

Opengl 法线贴图生成-着色器和FBO,opengl,glsl,fbo,normals,Opengl,Glsl,Fbo,Normals,我想从高度贴图生成法线贴图。我知道这是一个相当“过分紧张的问题”,但我还没有找到任何关于这个的好话题。法线贴图应该比原始纹理大6-8倍左右。我已经在CPU上实现了它,但是对于一个大的纹理来说这是相当慢的,我想用着色器来代替它。我的想法是将高度贴图渲染为全屏四边形,并使用着色器将其转换为片段着色器中的法线贴图,然后保存FBO纹理。这可以在init期间完成。在地图上。但是我怎样才能以任何分辨率呈现它呢 假设高度贴图是*20000*20000*,那么法线贴图应该是160000*160000。这超过了2

我想从高度贴图生成法线贴图。我知道这是一个相当“过分紧张的问题”,但我还没有找到任何关于这个的好话题。法线贴图应该比原始纹理大6-8倍左右。我已经在CPU上实现了它,但是对于一个大的纹理来说这是相当慢的,我想用着色器来代替它。我的想法是将高度贴图渲染为全屏四边形,并使用着色器将其转换为片段着色器中的法线贴图,然后保存FBO纹理。这可以在init期间完成。在地图上。但是我怎样才能以任何分辨率呈现它呢

假设高度贴图是*20000*20000*,那么法线贴图应该是160000*160000。这超过了25Mrd texel。当然,我只会将其中的一部分流式传输到GPU。法线贴图的分辨率是否取决于视口或GPU支持的最大分辨率,或者我可以制作非常高分辨率的纹理

有没有办法使用着色器在GPU上创建非常大分辨率的纹理?现在,我正在使用双三次过滤计算地形着色器中每一帧的法线,这非常平滑,但是因为它是静态网格,所以不需要,而且会严重影响性能

我的算法是得到插值高度,然后在指定高度周围再采样4个。然后是一个简单的corss产品:

h(x,y) //is samples 16 heigths, then interpolates them using bicubic filtering
n(x,y)
{
    h1 = h(x+offset0,y+offset0);
    ...
    v1 = (x+offset0,h1,y+offset0)
    ...
    c1 = cross(v1-v0,v2-v0)
    ...
    n = normalize(c1+c2+c3+c4)
}
这需要5*16=每个正常值80个样本。2500000000*80=2000000000 texelFetch用于我的法线贴图。这对我来说似乎是一个很大的数字,我只在CPU上制作了4000*4000高度贴图的法线贴图,但速度相当慢。计算所有这些需要多少时间?在GPU上,我想这需要大约5分钟。在CPU上…我不会尝试

我是否在线性过滤的高度图查找中得到相同的结果,然后在法线图上运行双三次过滤器


我不能为这一代使用第三方软件,我必须使用OpenGL自己实现它。如果要依靠GPU制作高分辨率的贴图,也许我可以渲染一次法线贴图的一部分,然后渲染其他部分。

是的,这是可能的。虽然我从未做过类似于您描述的以高度贴图原始分辨率的8倍对法线贴图进行重采样的事情,但根据经验,我可以告诉您,您真正需要的是将Sobel过滤器作为图像处理步骤应用于高度贴图。这实际上在许多应用程序中都非常有效,因为您可以将高度贴图存储为节省空间的单色纹理,并在运行时使用应用程序所需的任何图像格式和精度生成法线贴图。更重要的是,拥有原始的高度图对于一些算法是有用的。有一件事我真的不明白,那就是索贝尔。我已经读过很多次了,我需要Sobel过滤来生成法线贴图,但是我可以用相邻样本的简单叉积来生成法线贴图,就像我在片段着色器中做的那样。还是更快?你是说现在你在计算照明的同时生成法线贴图?生成和重用专用法线图肯定会更快——但对于您所希望的分辨率,我认为您可能需要考虑稀疏纹理,可以推迟计算正常映射部分的过程,直到它们首先在DX 11.2类或AMD HD 7xxx硬件上使用。它还不是一个标准特性,但他们在OpenGL4.4中为它引入了ARB扩展,它是DX11.2的一部分。这是该扩展的一个很好的用例。谢谢,我将尝试该扩展。是的,我仍然在渲染过程中生成法线,每一帧都非常平滑,但代价高昂。这就是为什么我想生成一个高分辨率的静态法线贴图。因为我的网格是静态的,所以只能计算一次。