gpt4 book ai didi

javascript - 在three.js中Mipmap一个行星?

转载 作者:行者123 更新时间:2023-12-04 21:51:33 26 4
gpt4 key购买 nike

所以我最近了解了 mipmapping 的定义,但我不确定如何在 Three.js 中正确使用该技术。

我看了一下这个例子:
http://threejs.org/examples/webgl_materials_texture_manualmipmap.html

我也看到了这个:
http://threejs.org/examples/#webgl_materials_texture_anisotropy

两者似乎都使用mipmapping。第一个例子有这部分代码:

function mipmap( size, color ) {

var imageCanvas = document.createElement( "canvas" ),
context = imageCanvas.getContext( "2d" );

imageCanvas.width = imageCanvas.height = size;

context.fillStyle = "#444";
context.fillRect( 0, 0, size, size );

context.fillStyle = color;
context.fillRect( 0, 0, size / 2, size / 2 );
context.fillRect( size / 2, size / 2, size / 2, size / 2 );
return imageCanvas;

}

var canvas = mipmap( 128, '#f00' );
var textureCanvas1 = new THREE.CanvasTexture( canvas );
textureCanvas1.mipmaps[ 0 ] = canvas;
textureCanvas1.mipmaps[ 1 ] = mipmap( 64, '#0f0' );
textureCanvas1.mipmaps[ 2 ] = mipmap( 32, '#00f' );
textureCanvas1.mipmaps[ 3 ] = mipmap( 16, '#400' );
textureCanvas1.mipmaps[ 4 ] = mipmap( 8, '#040' );
textureCanvas1.mipmaps[ 5 ] = mipmap( 4, '#004' );
textureCanvas1.mipmaps[ 6 ] = mipmap( 2, '#044' );
textureCanvas1.mipmaps[ 7 ] = mipmap( 1, '#404' );
textureCanvas1.repeat.set( 1000, 1000 );
textureCanvas1.wrapS = THREE.RepeatWrapping;
textureCanvas1.wrapT = THREE.RepeatWrapping;

var textureCanvas2 = textureCanvas1.clone();
textureCanvas2.magFilter = THREE.NearestFilter;
textureCanvas2.minFilter = THREE.NearestMipMapNearestFilter;

materialCanvas1 = new THREE.MeshBasicMaterial( { map: textureCanvas1 } );
materialCanvas2 = new THREE.MeshBasicMaterial( { color: 0xffccaa, map: textureCanvas2 } );

var geometry = new THREE.PlaneBufferGeometry( 100, 100 );

var meshCanvas1 = new THREE.Mesh( geometry, materialCanvas1 );
meshCanvas1.rotation.x = -Math.PI / 2;
meshCanvas1.scale.set(1000, 1000, 1000);

var meshCanvas2 = new THREE.Mesh( geometry, materialCanvas2 );
meshCanvas2.rotation.x = -Math.PI / 2;
meshCanvas2.scale.set( 1000, 1000, 1000 );

所以不清楚的是:
textureCanvas1.mipmaps[ 1 ] = mipmap( 64, '#0f0' );

以及 2d 上下文的使用。

无论哪种方式,鉴于示例的性质,我仍然不知道如何对行星进行 mipmap。所以是的,我不确定如何正确映射球体。首先,我需要我的行星/球体由单独的部分组成,以便我可以将分解纹理的不同部分放在球体的每个部分上。然后我创建了 2 个尺寸变化的幂,但是然后呢?

所以我的问题是,当用于立方体、球体等时,three.js 中的 mipmapping 看起来如何?一个简化的演示将非常受欢迎,因为现有的示例(很少见)似乎都过于臃肿或没有记录。

编辑:stackoverflow 中的另一个用户发布了这个:
var texture = THREE.ImageUtils.loadTexture( 'images/512.png', undefined, function() {
texture.repeat.set( 1, 1 );
texture.mipmaps[ 0 ] = texture.image;
texture.generateMipmaps = true;
texture.needsUpdate = true;
};

看来mipmaps 的关键是texture.mipmaps[]。不过,这里的人只指定了一张图片。我们不应该提供各种图像并让计算机根据您的距离来决定哪个合适吗?不确定此mipmapping如何工作。

最佳答案

映射

Mipmapping 是一种纹理渲染技术,您可以在每个纹理的基础上应用。它的基本要点是,当启用 mipmapping 时,GPU 将使用较小版本的纹理来渲染表面,具体取决于表面与相机的距离。

为了使用 mipmapping,您需要为您的纹理设置一组 mipmap; mipmap 是纹理的较小版本。您可以自己提供这些 mipmap,在过去您可能不得不这样做,但是使用最新的图形 API(OpenGL >= 3.0)可以自动生成它们。 如果您所做的只是将基本纹理贴图应用到球体表面,则不太可能需要生成自己的 mipmap

Mipmapping 与您正在纹理化的对象的 3D 形状没有任何关系。无论您是将纹理应用于立方体、球体还是任何其他模型,您作为程序员启用 mipmapping 所需采取的步骤都是相同的。您不需要启用 mipmapping 来渲染纹理,尽管它可能会使您的纹理看起来更漂亮。

这对 Three.js 有何影响

默认情况下,three.js 中的 您不需要做任何事情来为您的纹理生成 mipmap 。引用Texture的three.js文档,有一个 generateMipmaps 属性可控制自动生成mipmap,默认值为true。此功能在渲染器 here 中实现。这意味着获得 mipmapped 纹理所需的最低限度是:

var texture1 = THREE.ImageUtils.loadTexture("surface.png");
// our mipmaps will generate automatically now!

还有一个 mipmaps 属性,可以手动填充 mipmap 图像,如您提供的示例所示。奇怪的是,一个未记录的功能是如果这个数组不为空,它会禁用自动 mipmap 生成。您可以查看该 here 的来源。

示例分割

在瓷砖地板上有绘画的 first example 中, mipmap() 函数在 HTML Canvas 上绘制 2D 纹理。它负责绘制您在地平面上看到的平铺纹理。然后将这些纹理作为 mipmap 加载到 mipmaps 数组中,这样它们就可以通过 Three.js 以 3D 形式呈现。
var canvas = mipmap( 128, '#f00' );
var textureCanvas1 = new THREE.CanvasTexture( canvas );
// manually set up some mipmaps
textureCanvas1.mipmaps[ 0 ] = canvas;
textureCanvas1.mipmaps[ 1 ] = mipmap( 64, '#0f0' );
textureCanvas1.mipmaps[ 2 ] = mipmap( 32, '#00f' );
textureCanvas1.mipmaps[ 3 ] = mipmap( 16, '#400' );
textureCanvas1.mipmaps[ 4 ] = mipmap( 8, '#040' );
textureCanvas1.mipmaps[ 5 ] = mipmap( 4, '#004' );
textureCanvas1.mipmaps[ 6 ] = mipmap( 2, '#044' );
textureCanvas1.mipmaps[ 7 ] = mipmap( 1, '#404' );

你有没有注意到每个连续的 mipmap 是如何小两倍?起始纹理(我们必须放入 mipmaps[0] )是 128x128,第二个是 64x64,第三个是 32x32,依此类推。颜色( #0f0#00f#400等)是导致瓷砖上怪异的彩虹效果的原因。它们用不同的颜色来说明不同 mipmap 的边缘。

奖励:各向异性

second example 用于展示一种称为各向异性过滤的效果,这是在 mipmapping 之上的进一步增强;它根据从相机 到相机的视 Angular 的距离选择要使用的纹理大小。当远离相机倾斜时,这可以使远处的纹理看起来更好。
var maxAnisotropy = renderer.getMaxAnisotropy();

var texture1 = THREE.ImageUtils.loadTexture( "textures/crate.gif" );
// no need to generate mipmaps here, we get them automatically!
texture1.anisotropy = maxAnisotropy;
texture1.wrapS = texture1.wrapT = THREE.RepeatWrapping;
texture1.repeat.set( 512, 512 );

你有没有注意到左边的 crate 纹理( texture1 )比右边的( texture2 )更清晰,更不模糊?

结果

我在 plunker 中整理了一个更深入的示例,希望能更清楚地说明所有这些场景中发生的事情。一些注意事项:
  • 当您向上倾斜相机时,左上 Angular (无 mipmapping)具有非常明显的莫尔条纹。这就是为什么我们需要mipmapping!
  • 右上 Angular (mipmapping)看起来更好,但在远处仍然模糊。这是为什么?
  • 左下 Angular (彩色 mipmap)向我们展示了原因。模糊是由线性过滤器将所有 mipmap 插值在一起造成的。随着我们离相机越远,使用的图像越小,用颜色表示。
  • 右下 Angular (各向异性过滤)应该看起来最好,使纹理无论距离多远都看起来很清晰。
  • 关于javascript - 在three.js中Mipmap一个行星?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34040978/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com