在Three.js中将图像映射到球体上

19

我目前正在使用Three.js尝试创建一些东西。我有一个球体,我试图将这里的眼球图像映射到它上面。

问题在于结果看起来像这样:

输入图像描述

如何使它正确地映射而不会被拉伸?

我用于创建球体和映射纹理的代码如下:

var geometry = new THREE.SphereGeometry(0.5,100,100);
var material = new THREE.MeshPhongMaterial( { map: THREE.ImageUtils.loadTexture('eyeballmap.jpg',THREE.SphericalRefractionMapping) } );
var eyeball = new THREE.Mesh( geometry, material );
eyeball.overdraw = true;
eyeball.castShadow = true;
scene.add( eyeball );
3个回答

44

回答你问题的关键是你链接的图片

那张图片类似于球形环境映射中使用的MatCap图像。

适用于这种环境映射的着色器是使用(球体法线的函数)作为UV索引进入纹理映射的着色器。

<script id="vertex_shader" type="x-shader/x-vertex">

varying vec3 vNormal;

void main() {

    vNormal = normal;

    gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

}

</script>

<script id="fragment_shader" type="x-shader/x-fragment">

uniform sampler2D tex;

varying vec3 vNormal;

void main() {

    vec2 uv = normalize( vNormal ).xy * 0.5 + 0.5;

    vec3 color = texture2D( tex, uv ).rgb;

    if ( vNormal.z < - 0.85 ) color = vec3( 0.777, 0.74, 0.74 ); // back of eye
    
    gl_FragColor = vec4( color, 1.0 );

}

</script>
const uniforms = {
    "tex": { value: texture }   
};

const material = new THREE.ShaderMaterial( {
    uniforms        : uniforms,
    vertexShader    : document.getElementById( 'vertex_shader' ).textContent,
    fragmentShader  : document.getElementById( 'fragment_shader' ).textContent
} );

scene.add( new THREE.Mesh( new THREE.SphereGeometry( 30, 32, 16 ), material ) );

在MatCap纹理球上渲染的眼睛

three.js版本为r.147


1
您所拥有的纹理只代表眼睛的可见部分,而不是整个球体。您需要在现有纹理周围添加白色空间,以容纳未显示的球体部分。

1
我认为我的纹理的一般形状可能有问题 - 我应该把空白放在哪里?空白也不会影响图像中虹膜/瞳孔部分的扭曲,对吗? - Mat Richardson
你的纹理尺寸为512x512,因此你可能需要在其周围添加足够的白色空间(每个方向都要添加),以便瞳孔占用的空间较小(作为纹理尺寸的百分比)。这样可以减少扭曲。另一个选择是更改球体的UV坐标,使得你的图像(原样)落在正确的位置。 - gaitat
1
创建一个2048x2048的纹理,并将其放置在中心位置。 - gaitat
是的,但可能没有失真。 - gaitat
创建一个2048x512的图像并将您的图像放在中心位置 :) - mrdoob
显示剩余4条评论

1

不需要更改任何代码,解决方案在于使用适当的图像,大小为1024x512而不是512x512:

Full equirectangular eye

实际上,原始的正方形图像代表了略多于半个球体:半个球体只是中心处的圆形,半径为256像素:

Actual hemisphere


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接