我创建了一个glsl着色器:
<script id="player-fragment-shader" type="x-shader/x-fragment">
precision highp float;
varying vec3 fNormal;
uniform vec2 resolution;
float circle(in vec2 _pos, in float _radius) {
vec2 dist = _pos - vec2(0.5);
return 1.-smoothstep(_radius - (_radius * 0.5),
_radius + (_radius * 0.5),
dot(dist, dist) * 20.0);
}
void main() {
vec2 pos = gl_FragCoord.xy/resolution.xy;
// Subtract the inverse of orange from white to get an orange glow
vec3 color = vec3(circle(pos, 0.8)) - vec3(0.0, 0.25, 0.5);
gl_FragColor = vec4(color, 0.8);
}
</script>
<script id="player-vertex-shader" type="x-shader/x-vertex">
precision highp float;
attribute vec3 position;
attribute vec3 normal;
uniform mat3 normalMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
void main() {
vec4 pos = modelViewMatrix * vec4(position, 0.25);
gl_Position = projectionMatrix * pos;
}
</script>
我通过运行来在游戏加载中初始化它:
var vertShader = document.getElementById("player-vertex-shader").text;
var fragShader = document.getElementById("player-fragment-shader").text;
var shader = me.video.shader.createShader(me.video.renderer.compositor.gl, vertShader, fragShader);
这是在视频初始化之后完成的,并且似乎编译着色器程序并加载正常。在shaderfrog.com和其他类似网站上加载时,着色器似乎也能正常工作。
问题是,在我移动角色并重绘之前,它会让我看到一个全黑的屏幕。我已经阅读了webgl基础知识网站,而我似乎缺少的是将字符位置绑定到GL缓冲区。
我如何在melonjs中这样做。
答案 0 :(得分:0)
嗨,我为melonJS编写了原始的WebGL合成器。
tl; dr:通过从角色的true
方法返回entity.update()
来强制重绘帧。 (或者,增加动画帧速率以匹配游戏帧速率。)
覆盖update
方法的示例:
update: function (dt) {
this._super(me.Entity, "update", [dt]);
return true;
}
这允许更新继续正常运行(例如更新动画状态等),但返回true
以强制每次重绘帧。
了解合成器的工作原理以及着色器如何与melonJS实体进行交互可能会有所帮助。这描述了WebGL与melonJS集成的内部工作原理。简而言之,没有明确的步骤将位置绑定到着色器。位置通过顶点属性缓冲区发送,该缓冲区被批量处理(通常用于整个帧)并作为一个大数组发送到WebGL。
如果您需要更多地控制构建顶点缓冲区,或者您想要执行其他自定义渲染过程,则可以替换默认合成器。这是通过在me.video.init
参数中将类引用传递给options.compositor
来完成的。默认值为me.WebGLRenderer.Compositor
:
me.video.init(width, height, {
wrapper: "screen",
renderer : me.video.WEBGL,
compositor: me.WebGLRenderer.Compositor
});
在绘制循环期间,默认合成器为每个me.WebGLRenderer.drawImage
调用向顶点属性数组缓冲区添加一个新的四元素。此方法模拟同名的DOM canvas method。实施非常简单;它只是将参数转换为四元组并调用合成器的addQuad
方法。这是实际填充顶点属性缓冲区的地方。
顶点属性缓冲区完成后,将调用flush
方法,该方法使用gl.drawElements
将顶点缓冲区发送到GPU。
melonJS将绘图优化发挥到极致。它不仅可以批量渲染,而且可以减少绘制调用的次数(如上所述),但如果没有任何内容可以绘制,它也不会发送任何绘制调用。当帧与绘制的最后一帧相同时,会发生这种情况。例如,没有实体移动,视口没有滚动,空闲动画没有前进到下一个状态,屏幕上的计时器没有经过一整秒等等。
可以通过让场景中的任何实体从其true
方法返回update
来强制重绘帧。这是游戏引擎发出的信号,需要重新绘制框架。该过程在the wiki上有更详细的描述。