How to map texture image onto a part of a sphere,

2019-04-17 06:39发布

I am working with WebGL using three.js and I have an image that I want to project onto the (inner) surface of a sphere. The problem I am facing is how to limit the extent of that mapping to a horizontal and vertical field of view. Imagine projecting an image from the centre of a sphere onto a rectangular section of it.

I suspect I can do this one of 2 ways, but am unsure about how to do either...

1) Map the texture onto the sphere based on the field of view angles. Mapping the image straight onto the sphere as below does a 360x180 degree wrap. Is there a UV mapping trick involved, or some other technique available?

var sphere = new THREE.Mesh( 
    new THREE.SphereGeometry(radius, 60, 40), 
    new THREE.MeshBasicMaterial( 
        { map: THREE.ImageUtils.loadTexture( filename ) }
    )
);

2) Chop up a sphere so that it only has the subset of the surface covered by the angles given (ie intersecting with a rectangular pyramid), or producing an equivalent curved surface. Any ideas?

1条回答
叼着烟拽天下
2楼-- · 2019-04-17 07:32

The easiest way to scale down the projection is to tweak the UV coords in the fragment shader:

// how large the projection should be
uniform vec2 uScale;
...

// this is the color for pixels outside the mapped texture
vec4 texColor = vec4(0.0, 0.0, 0.0, 1.0);

vec2 scale = vec2(1.0/uScale.s, 1.0/uScale.t);
vec2 mappedUv = vUv*scale + vec2(0.5,0.5)*(vec2(1.0,1.0)-scale);

// if the mapped uv is inside the texture area, read from texture
if (mappedUv.s >= 0.0 && mappedUv.s <= 1.0 && 
    mappedUv.t >= 0.0 && mappedUv.t <= 1.0) {
  texColor = texture2D(map, mappedUv);
}

For THREE.SphereGeometry UVs the full field of view in radians is 2pi for x and pi for y. The scale factor for a reduced field is vec2(fovX/2pi, fovY/pi).

You can also do the UV scaling in the vertex shader. Other ways are to copypaste https://github.com/mrdoob/three.js/blob/master/src/extras/geometries/SphereGeometry.js and change the generated UVs to match your scaling factors (uv*1/scale + 0.5*(1-1/scale))

Lemme know if this helps.

查看更多
登录 后发表回答