本文的重点是演示如何使用WxGL光照模式,以及如何通过设置漫反射系数、镜面反射系数、高光系数、透光系数等参数来模拟不同的材质。所谓的分子模型,只是笔者凭空想象出来的由圆球和圆管组成的类似积木的玩具,希望不会因此而造成误会。
除了点、线和2D文本,WxGL的其他实体模型默认使用户外光照(wxgl.SkyLight)模式,主光束自上而下以模拟来自天空的光线,而来自地面的反射光线相对较弱。
import wxgl
app = wxgl.App(bg='#f0f0f0', fovy=40)
app.sphere((-2,0,0), 0.35, color='#d8d8d8')
app.sphere((0,0,0), 0.35, color='#d8d8d8')
app.sphere((2,0,0), 0.35, color='#d8d8d8')
app.sphere((-1,-1,0), 0.35, color='#d8d8d8')
app.sphere((1,-1,0), 0.35, color='#d8d8d8')
app.show()
上面的代码使用默认的光照模式绘制了5个灰色的圆球,在浅灰背景下,中灰的圆球明显缺乏立体感。
太阳光照模式(wxgl.SunLight),也称为平行光照模式,是最常用的一种光照模式,默认平行光线从背后向前方照射。
wxgl.SunLight(direction=(0.0,0.0,-1.0), lightcolor=(1.0,1.0,1.0), ambient=(0.3,0.3,0.3), **kwds)
主要参数如下:
direction - 太阳光方向
lightcolor - 太阳光颜色
ambient - 环境光颜色
kwds - 关键字参数
diffuse - 漫反射系数:值域范围[0.0, 1.0],数值越大,表面越亮。默认值0.8
specular - 镜面反射系数:值域范围[0.0, 1.0],数值越大,高光越亮。默认值0.6
shiny - 高光系数:值域范围[1, 3000],数值越大,高光区域越小。默认值50
pellucid - 透光系数:值域范围[0.0,1.0],数值越大,背面越亮。默认值0.5
下面的代码将默认光照改为wxgl.SunLight,同时调整了漫反射系数、镜面反射系数、高光系数、透光系数的默认值,模拟出了塑料的质感。
import wxgl
light = wxgl.SunLight(direction=(0.5,-0.5,-1.0), diffuse=0.7, specular=0.98, shiny=100, pellucid=0.9)
app = wxgl.App(bg='#f0f0f0', fovy=40)
app.sphere((-2,0,0), 0.35, color='#d8d8d8', light=light)
app.sphere((0,0,0), 0.35, color='#d8d8d8', light=light)
app.sphere((2,0,0), 0.35, color='#d8d8d8', light=light)
app.sphere((-1,-1,0), 0.35, color='#d8d8d8', light=light)
app.sphere((1,-1,0), 0.35, color='#d8d8d8', light=light)
app.show()
再画上几个其他颜色的小球,将其中的几个圆球用圆管串起来。
import wxgl
c1, c2, c3, c4, c5 = '#d8d8d8', '#00d0d0', '#6060f0', '#903030', '#90C090'
light = wxgl.SunLight(direction=(0.5,-0.5,-1.0), diffuse=0.7, specular=0.98, shiny=100, pellucid=0.9)
app = wxgl.App(bg='#f0f0f0', azim=-30, elev=20, fovy=40)
app.sphere((-2,0,0), 0.35, color=c1, light=light)
app.sphere((0,0,0), 0.35, color=c1, light=light)
app.sphere((2,0,0), 0.35, color=c1, light=light)
app.sphere((-1,-1,0), 0.35, color=c1, light=light)
app.sphere((1,-1,0), 0.35, color=c1, light=light)
app.cylinder((-2,0,0), (-1,-1,0), 0.17, color=c2, light=light)
app.cylinder((0,0,0), (-1,-1,0), 0.17, color=c2, light=light)
app.cylinder((0,0,0), (1,-1,0), 0.17, color=c2, light=light)
app.cylinder((2,0,0), (1,-1,0), 0.17, color=c2, light=light)
app.sphere((-2,1.2,-0.6), 0.35, color=c3, light=light)
app.sphere((-3,-0.6,0.6), 0.35, color=c3, light=light)
app.sphere((2.6,0.5,1), 0.35, color=c3, light=light)
app.sphere((2.6,0.5,-1), 0.35, color=c3, light=light)
app.sphere((1,-1.5,1), 0.35, color=c5, light=light)
app.cylinder((-2,0,0), (-2,1.2,-0.6), 0.17, color=c4, light=light)
app.cylinder((-2,0,0), (-3,-0.6,0.6), 0.17, color=c2, light=light)
app.cylinder((2,0,0), (2.6,0.5,1), 0.17, color=c4, light=light)
app.cylinder((2,0,0), (2.6,0.5,-1), 0.17, color=c2, light=light)
app.cylinder((1,-1,0), (1,-1.5,1), 0.17, color=c2, light=light)
app.sphere((0,0.7,-0.8), 0.15, color=c2, light=light)
app.sphere((0,0.7,0.8), 0.15, color=c2, light=light)
app.sphere((-1,-1.7,-0.8), 0.15, color=c2, light=light)
app.sphere((-1,-1.7,0.8), 0.15, color=c2, light=light)
app.cylinder((0,0,0), (0,0.7,-0.8), 0.08, color=c2, light=light)
app.cylinder((0,0,0), (0,0.7,0.8), 0.08, color=c2, light=light)
app.cylinder((-1,-1,0), (-1,-1.7,-0.8), 0.08, color=c2, light=light)
app.cylinder((-1,-1,0), (-1,-1.7,0.8), 0.08, color=c2, light=light)
app.show()
看起来是不是像一个分子模型了呢?