This beta release is experimental in the sense that there are known bugs described below. Feel free to play with the exciting new features, but be aware that you may encounter problems.
There is a new example program texture_and_lighting.py that displays many of the new features: a swinging spotlight illuminates a translucent beach ball that rolls on a wood-texture table.
You can make most objects be partially transparent by specifying a value from 0-1 inclusive for the attribute "opacity". For example, box(color=color.red, opacity=0.8) is slightly transparent. An opacity value of 0 means totally transparent, and 1 means totally opaque. Currently curves and helixes do not allow transparency. (Currently you can use the synonym "alpha" for "opacity", but "alpha" is deprecated.)
You can create a texture object and then apply it to the surface of an object. This capability is currently limited to boxes and spheres. A surface texture is an M by N array of 1, 2, 3, or 4 numerical values (a list or tuple). M and N must be powers of 2 (1, 2, 4, 8, 16, 32, etc.). Here are the possible values for each slot in the array:
1 value: texture type must be "luminance" (how bright) or "opacity"
2 values (opacity,luminance): texture type must be "opacity_luminance"
3 values (red,green,blue): texture type must be "rgb"
4 values (red,green,blue,opacity or alpha): texture type must be "rgbo"
A VPython texture is basically a mask. For example, if you apply a texture to a box that is red, any cyan region of the texture will display as black, because the cyan (0,1,1) doesn't overlap at all with the red (1,0,0).
You can create a numeric array of zeros in various formats, then assign values:
zeros([...], ubyte) means an 8-bit unsigned integer 0-255
zeros([...], short) means a 16-bit iinteger plus or minus 0-32767
zeros([...], int) means a 32-bit integer plus or minus 0-2147483648
zeros([...], float) means a floating-point (fractional) number
Here is an example program in which a checkerboard texture is created and applied to a box:
from visual import *
M=4 # must be a power of 2 (1, 2, 4, 8, 16, 32, etc.)
N=4 # must be a power of 2 (1, 2, 4, 8, 16, 32, etc.)
checks = zeros([M,N], float) # create a numeric array of floating-point zeros
(0.0)
for i in range(M):
for j in range(N):
if ((i&1) ^ (j&1)):
# true for every alternate square of the checkerboard
checks[i][j]
= 1.0
print checks
lum = texture(data=checks, type="luminance")
box(color=color.cyan, texture=lum)
If you wanted to create a texture containing "rgb" values, you would start with zeros([M,N,3], float), and entries into this array would be the usual (red,green,blue) triples, with values for each color in the range 0-1 inclusive.
See the contributed section of vpython.org for an example of a program to create, save, and use a wood-grain texture. Such a texture is included in the examples and used by the program texture_and_lighting.py.
Some objects now have a "shininess" attribute which by default is 0.5 (box, sphere, cylinder, cone, ring). A shininess of 0 means no specular highlights. A shininess of 1 means strong specular highlights. You can also for special purposes specify an attribute "lit" to False (or 0) in which case lights have no effect on it.
For compatibility with past programs, there is still a list of lights in scene.lights, and you can still manipulate those lights as before. However, those lights were restricted to being very far ("at infinity") from the scene. Now you can create lights that are nearby, and if you wish they can be spotlights with directed beams. The following statement creates a local blue light positioned at (x,y,z):
bl = light(pos=(x,y,z), color=color.blue, local=True)
Note that if you continually update bl.pos, the light will move.
By default, local is True. If you set local = False, the light is at infinity, in a direction given by pos.
Other attributes are spot_direction (a vector), spot_cutoff (half angle of the beam in degrees), diffuse_color, and specular_color. The attribute attentuation=(const, linear, quadratic) makes the light diminish with distance d according to the formula 1/(const + linear*d +quadratic*d). The default is (1,0,0). OpenGL guarantees to permit a minimum of seven lights.
If you want to disable all of the old lights, say scene.lights = [], making an empty list of old lights.
A new points object can be plotted in "screen" size as well as the usual "world" coordinates. Like curve, the pos attribute is a list of points, as is color. If antialias is True, the points are round; by default they are square. The size attribute is in screen pixels if the type attribute is "screen" (the default), but if type is "world", the size is in the usual coordinates. A good use for the new object is for the gdots displayed using visual.graph. These used to be awkward labels using the letter "o" but have been replaced with screen-pixel points.
Technical caveats: If the "GL_ARB_point_parameters" property is shown in scene.info() then type = "world" will work. Otherwise the type is silently ignored and considered to be "screen". There is an implementation-defined size range for either round or square points, which is not easily visible to programs at this time. Specifying a size outside this range will cause it to be silently clamped internally to whatever range that the hardware supports.
You can now make a frame visible or invisible, and all objects in the frame will be affected. And you can set the vector "scale" attribute of a frame to change the size of the combined object.
The option scene.uniform = False now facilitates making graphs of functions and is used by the module visual.graph. The option is useful for making 2D displays whose x and y scale factors are different. The only objects supported are curve, faces, points, and label. Set the scale factors with scene.range.
You can now specify font='times' or 'system' or 'symbol' etc. in a label object.
For convenience you can now say color=0.7 to mean color=(0.7,0.7,0.7).
There is one major known bug still being worked on: Depending on the graphics card and driver, performance with some programs on Windows may be poor (but performance may be okay on another computer). This problem is not yet understood.
Here are known bugs that are less serious:
Autoscaling is pretty good but occasionally positions the camera farther from the scene than you would prefer.
In a column of many rings along the x axis, at least on Windows, occasionally a ring is briefly rendered wrong.
Rendering of curves isn't quite right. This can be seen in the example program tictac.py, where one of the grid lines doesn't show until you rotate the view.
Spotlights created in a frame don't change with changes in the frame orientation.
scene.cursor is not implemented and gives an error (used in old programs to make cursor visible/invisible).
Stereo mode "crosseyed" is not implemented.