我正在创建一个地形,使用geomip映射技术。目前已经基本实现了。在相机附近的地形细分程度很高,远离相机时逐渐减少。地形的几何图形基本上遵循相机并根据顶点位置采样高度图纹理。由于地形几何图形的细分程度非常高,当采样时有时会看到纹理中的每个像素。这会产生明显的像素颗粒。我想通过平滑高度图采样来解决这个问题。但是,我似乎遇到了一些与双线性采样代码相关的奇怪问题。我通过将每个顶点位移根据高度图纹理进行渲染。要获得给定UV坐标处顶点的高度,可以使用以下公式:
vec2 worldToMapSpace( vec2 worldPosition ) {
return ( worldPosition / worldScale + 0.5 );
}
float getHeight( vec3 worldPosition )
{
#ifdef USE_HEIGHTFIELD
vec2 heightUv = worldToMapSpace(worldPosition.xz);
vec2 tHeightSize = vec2( HEIGHTFIELD_SIZE_WIDTH, HEIGHTFIELD_SIZE_HEIGHT ); //both 512
vec2 texel = vec2( 1.0 / tHeightSize );
//float coarseHeight = texture2DBilinear( heightfield, heightUv, texel, tHeightSize ).r;
float coarseHeight = texture2D( heightfield, vUv ).r;
return altitude * coarseHeight + heightOffset;
#else
return 0.0;
#endif
}
这将产生以下结果(请注意您可以看到每个像素):
这是一个线框图:
我希望使地形采样更加平滑。因此,我想使用一些双线性采样代替标准的texture2D函数。因此,这是我的双线性采样函数:
vec4 texture2DBilinear( sampler2D textureSampler, vec2 uv, vec2 texelSize, vec2 textureSize )
{
vec4 tl = texture2D(textureSampler, uv);
vec4 tr = texture2D(textureSampler, uv + vec2( texelSize.x, 0.0 ));
vec4 bl = texture2D(textureSampler, uv + vec2( 0.0, texelSize.y ));
vec4 br = texture2D(textureSampler, uv + vec2( texelSize.x, texelSize.y ));
vec2 f = fract( uv.xy * textureSize ); // get the decimal part
vec4 tA = mix( tl, tr, f.x );
vec4 tB = mix( bl, br, f.x );
return mix( tA, tB, f.y );
}
texelSize是根据高度图大小计算的,公式为1 / 高度图大小:
vec2 texel = vec2( 1.0 / tHeightSize );
textureSize是高度图的宽度和高度。然而,当我使用这个函数时,我得到了这个结果:
float coarseHeight = texture2DBilinear( heightfield, heightUv, texel, tHeightSize ).r;
现在看起来更糟糕了 :( 有什么想法我可能做错了吗?或者如何获得更平滑的地形采样?
编辑
这是一个垂直的截图,从上往下看地形。您可以看到层的效果很好。请注意,外层的三角剖分较少,看起来更加平滑,而具有更高细分的层则显示每个像素。我正在尝试找到一种方法来平滑纹理采样。