blender3d.org -- GLSL Pixel and Vertex shaders


GLSL ピクセル/バーテックスシェーダ


Blender に、OpenGL SL(シェーダランゲージ)のピクセル/バーテックスシェーダを Game Engine 用に割り当てることができるようになりました。もっとちゃんとしたドキュメントは Game Engine Documentation にあります。

シェーダは Python の使用により、単一の Material に適用できます。Object 上のそれぞれの Material ごとに、一つのシェーダに(その Material から)アクセスできます。少しの例外を除き、ほとんどの GLSL の関数にアクセスできます。Attribute の位置は利用できません。

実際には、下記のような宣言は動作しません。
//--
attribute vec3 variable;
//--

フラグメントシェーダでは、下記の Sampler のみ使用可能です。
// -- 
uniform sampler2D;
uniform samplerCube;
//-- 

sampler2D はImage タイプを参照し、samplerCube は Envmap を参照します。

プログラム中で uniform 変数にアクセスするには、その変数の名前/値を補う必要があります:shader.setUniform[if][v](name,value)

vec3 の場合、
shader.setUniform3f(name,f,f,f)
あるいは
shader.setUniformfv(name, [f,f,f] )

Sampler は取扱いに少し違いがあり、インデックスによりアクセスされます(0,2など)。このインデックスは Material パネル内で供給される Texture の順序を参照しています。もし Material がなければ、0を有効な Sampler のインデックスとして常に使用できます。

shader.setSampler(sampler_name, texture_index)

テンプレート
#------------------------------------------------------------------------------
import GameLogic
objects = GameLogic.getCurrentScene().getObjectList()

# -------------------------------------
ShaderObjects = [] # add objects
MaterialIndexList = [0] # material index
# -------------------------------------

VertexShader = """
void main(){
  gl_Position = ftransform();
}
"""

FragmentShader = """
void main(){
  gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0);
}
"""

def MainLoop ():
  for obj in ShaderObjects:
    mesh_index = 0
    mesh = obj.getMesh(mesh_index)
    while mesh != None:
      for mat in mesh.materials:
        if not hasattr(mat, "getMaterialIndex"):
          return
        mat_index = mat.getMaterialIndex()
        found = 0
        for i in range(len(MaterialIndexList)):
          if mat_index == MaterialIndexList[i]:
            found=1
            break
        if not found: continue
        shader = mat.getShader()
        if shader != None:
          if not shader.isValid():
            shader.setSource(VertexShader, FragmentShader,1)
          # set shader variables
          # --
        
      mesh_index += 1
      mesh = obj.getMesh(mesh_index)
# -------------------------------------
MainLoop()
#------------------------------------------------------------------------------
もしエラーが起こった場合、material.getShader()関数は None を返し、その Matarial 用のシェーダは使用されなくなります。


Last update: Jan 26 2006.
This section is maintained by Ton Roosendaal.