Crafty.WebGLShader()

public Crafty.WebGLShader Crafty.WebGLShader(String vertexShaderCode, String fragmentShaderCode, Array attributeList, Function drawCallback(e, entity))
vertexShaderCode

对于顶点着色器的GLSL代码

fragmentShaderCode

在片段着色器的GLSL代码

attributeList

变量名称的顶点长度列表

drawCallback

将所有属性值映射到WebGL的函数

为组件分配或获取默认着色器。

这允许对组件的默认着色器进行重写,从而允许开发人员使用更复杂的着色器覆盖默认着色器行为。

例子

当我们设置一个grayscale: true属性时,我们想要扩展精灵来绘制一个有灰度级别的图片。

var recoloredSprite = new Crafty.WebGLShader(
  // The vertex shader
  "attribute vec2 aPosition;\n" +
  "attribute vec3 aOrientation;\n" +
  "attribute vec2 aLayer;\n" +
  "attribute vec2 aTextureCoord;\n" +
  "attribute vec2 aGrayscale;\n" + // Addition of our grayscale
  "varying mediump vec3 vTextureCoord;\n" +
  "varying mediump vec2 vGrayscale;\n" + // passing attribute to fragment shader
  "uniform vec4 uViewport;\n" +
  "uniform mediump vec2 uTextureDimensions;\n" +
  "mat4 viewportScale = mat4(2.0 / uViewport.z, 0, 0, 0,    0, -2.0 / uViewport.w, 0,0,    0, 0,1,0,    -1,+1,0,1);\n" +
  "vec4 viewportTranslation = vec4(uViewport.xy, 0, 0);\n" +
  "void main() {\n" +
  "  vec2 pos = aPosition;\n" +
  "  vec2 entityOrigin = aOrientation.xy;\n" +
  "  mat2 entityRotationMatrix = mat2(cos(aOrientation.z), sin(aOrientation.z), -sin(aOrientation.z), cos(aOrientation.z));\n" +
  "  pos = entityRotationMatrix * (pos - entityOrigin) + entityOrigin ;\n" +
  "  gl_Position = viewportScale * (viewportTranslation + vec4(pos, 1.0/(1.0+exp(aLayer.x) ), 1) );\n" +
  "  vTextureCoord = vec3(aTextureCoord, aLayer.y);\n" +
  "  vGrayscale = aGrayscale;\n" + // Assigning the grayscale for fragment shader
  "}",
  // The fragment shader
  "precision mediump float;\n" +
  "varying mediump vec3 vTextureCoord;\n" +
  "varying mediump vec2 vGrayscale;\n" +
  "uniform sampler2D uSampler;\n " +
  "uniform mediump vec2 uTextureDimensions;\n" +
  "void main() {\n" +
  "  highp vec2 coord =   vTextureCoord.xy / uTextureDimensions;\n" +
  "  mediump vec4 base_color = texture2D(uSampler, coord);\n" +
  "  if (vGrayscale.x == 1.0) {\n" +
  "    mediump float lightness = (0.2126*base_color.r + 0.7152*base_color.g + 0.0722*base_color.b);\n" +
  "    lightness *= base_color.a * vTextureCoord.z; // Premultiply alpha\n" +
  "    gl_FragColor = vec4(lightness, lightness, lightness, base_color.a*vTextureCoord.z);\n" +
  "  } else {\n" +
  "    gl_FragColor = vec4(base_color.rgb*base_color.a*vTextureCoord.z, base_color.a*vTextureCoord.z);\n" +
  "  }\n" +
  "}",
  [
    { name: "aPosition",     width: 2 },
    { name: "aOrientation",  width: 3 },
    { name: "aLayer",        width: 2 },
    { name: "aTextureCoord", width: 2 },
    { name: "aGrayscale",    width: 2 }
  ],
  function(e, entity) {
    var co = e.co;
    // Write texture coordinates
    e.program.writeVector("aTextureCoord",
      co.x, co.y,
      co.x, co.y + co.h,
      co.x + co.w, co.y,
      co.x + co.w, co.y + co.h
    );
    // Write our grayscale attribute
    e.program.writeVector("aGrayscale",
      entity.grayscale ? 1.0 : 0.0,
      0.0
    );
  }
);

这似乎是一个很大的工作,但上面的代码大部分是默认的Crafty着色器代码。当你掌握它的时候,很容易扩展你自己的效果。记住你只需要写一次,然后所有的精灵实体都有额外的效果。