Monday, November 16, 2009

Dissertation Status

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,)

0 comments:

Post a Comment