import bpy
from math import pi,sin,cos
tau=pi*2
M=64
N=M*2
Md=M+1
Nd=N+1
def cm(name,verts,vert_uvs,faces):
me = bpy.data.meshes.new(name)
ob = bpy.data.objects.new(name, me)
scn = bpy.context.scene
scn.objects.link(ob)
scn.objects.active = ob
ob.select = True
me.from_pydata(verts, [], faces)
me.update()
# vertex index : vertex value pair
vi_uv = {i: uv for i, uv in enumerate(vert_uvs)}
#initialize an empty list
per_loop_list = [0.0] * len(me.loops)
for loop in me.loops:
per_loop_list[loop.index] = vi_uv.get(loop.vertex_index)
# flattening
per_loop_list = [uv for pair in per_loop_list for uv in pair]
# creating the uvs
me.uv_textures.new("UVMap")
me.uv_layers[0].data.foreach_set("uv", per_loop_list)
me.update()
avert=[]
aface=[]
auv=[]
bvert=[]
bface=[]
buv=[]
# verts = ((x,x,-1), (x,-x,-1), (-x,-x,-1), (-x,x,-1), (0,0,1))
# faces = ((1,0,4), (4,2,1), (4,3,2), (4,0,3), (0,1,2,3))
for m in range(Md):
for n in range(Nd):
x,y,z=(sin(pi*m/M)*cos(tau*n/N),sin(pi*m/M)*sin(tau*n/N),cos(pi*m/M))
if z>0.000001:
avert.append((x/z*-102,y/z*-102,100))
auv.append((1-n/N,1-m/M))
i=len(avert)-1
if i>Nd:
if i%Nd>0:
aface.append((i,i-1,i-1-Nd,i-Nd))
else:
aface.append((i,i+Nd-1,i-1,i-Nd))
if z<-0.000001:
bvert.append((x/z*-2,y/z*-2,0))
buv.append((1-n/N,1-m/M))
i=len(bvert)-1
if i>Nd:
if i%Nd>0:
bface.append((i,i-1,i-1-Nd,i-Nd))
else:
bface.append((i,i+Nd-1,i-1,i-Nd))
cm('ground',bvert,buv,bface)
cm('sky',avert,auv,aface)
It will add sky and ground planes assuming that a photographer is two meters tall.
Soon I will release a perspective shrinkwrap script.
Here the ground is replaced with a sea.
Shaders may be not so good but hey, it gives a possibility to make towns at sea!
Some pixels, thought, have infinite depth and were clipped. So for horizon an environment texture is still required.
Example blend file is included.