Answers
要精确地把图像对应到到曲面是很难的,一般采用线性化的方法,也就是首先把曲面细分使得每个小块都接近平面,然后算出每个顶点对应贴图的坐标,最后把细分成一个一个小三角形或者四边形的图像贴到对应的小块曲面上。这也就是OpenGL或者Direct3D把一幅世界地图贴到一个球体上变成一个地球仪时候用的算法。把三角形映射到三角形的时候只要用普通的线性变换就行了。
如果是要让曲面显示出来的图形就像一张纸扭曲了之后的效果那样(也就是曲面距离保持不变),可以用某种uv坐标系;如果是要让曲面显示出来看起来跟平面一样,可以这样建立贴图坐标:将曲面的3D模型在目标视点的Camera下面做透视变换,变换后的透视空间中的顶点坐标的x、y分量作为贴图坐标。这样贴图完成之后,这个视点下面看到的就刚好是一个平面的效果。
如果曲面是液晶屏之类的形成的话到这里差不多就行了,如果是某个投影仪产生的图像,还需要再做一步计算投影图像,这个可以这样完成:
在OpenGL之类的环境下将曲面的3D模型按照上面说的方法贴上贴图,然后构造一个投影仪位置的Camera。从这个Camera的位置渲染贴好图的3D模型,得到的结果就是投影仪应该投出的图像。要求更高的时候,因为投影仪投出的单位面积光通量是个固定值,距离远的时候投出的图像会变暗,可以预先根据视空间的z坐标来修正亮度,让不同距离的图像亮度一致。
整个过程在Direct3D下面用HLSL或者OpenGL下面用GLSL应该可以一遍完成,即使是投影视频应该也没有大的问题。唯一的问题可能就是投影亮度了吧……
曲面的视角太广的时候这个方法也会有问题,因为人的视野只有中间区域近似是平的,两头也是非线性的。再就是这个方法投出来的只有一个位置看修正是精确的,在这附近近似精确,远一点之后还是弯曲的,这个也是没办法的。