Here's a simple example showing the current capabilities of the PyStream compiler. These shinny cows were drawn using a shader that was written in Python and then compiled into GLSL. The actual shading algorithm is pretty simple: phong shading, a point light, and gamma correction. The kicker is that Python's semantics are wildly different from GLSL's. Compiling Python code into GLSL is therefore a pretty neat trick.
An advantage of writing shaders in Python is that the same functions can be called on both the CPU and the GPU. For example, in the following code the function
rgb2srgb is used to gamma correct colors on the GPU. The same function is also used to gamma correct the clear color on the CPU, so it matches the colors output by the shader. In general, arbitrary color processing could be applied in the shader: tone mapping, etc. Unless the same processing is applied to the clear color (which is not processed by the shader), the rendered objects may "pop out" from the background. For example, if fog is used and the clear color is not processed the same way as pixels, distant objects will fade to a color that does not match the background.
This is the original Python code:
def shadeVertex(self, context, pos, normal): trans = self.worldToCamera*self.objectToWorld newpos = trans*pos newnormal = trans*vec4(normal, 0.0) context.position = self.projection*newpos return newpos.xyz, newnormal.xyz def shadeFragment(self, context, pos, normal): n = normal.normalize() e = -pos.normalize() # Light into camera space trans = self.worldToCamera lightPos = trans*self.lightPos lightDir = lightPos.xyz-pos lightDist2 = lightDir.dot(lightDir) lightDist = lightDist2**0.5 l = lightDir/lightDist lightAtten = 1.0/(0.01+lightDist2*(1.0/(100.0**2))) transfer = self.material.transfer(n, l, e) modulated = transfer*lightAtten mainColor = self.material.color*(self.ambient+modulated) mainColor = rgb2srgb(mainColor) mainColor = vec4(mainColor, 1.0) context.colors = (mainColor,)