как привязать позицию игрока к шейдеру с помощью melonjs? - PullRequest
0 голосов
/ 25 апреля 2018

Я создал шейдер 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.

1 Ответ

0 голосов
/ 25 апреля 2018

Привет, я написал оригинальный композитор WebGL для melonJS.

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
});

Во время цикла отрисовки композитор по умолчанию добавляет новый элемент quad в буфер массива атрибутов вершины для каждого вызова me.WebGLRenderer.drawImage.Этот метод эмулирует метод холста DOM с тем же именем.Реализация очень проста;он просто преобразует аргументы в квадрат и вызывает метод композитора addQuad.Именно здесь фактически заполняется буфер атрибутов вершины.

После того, как буфер атрибутов вершины завершен, вызывается метод flush, который отправляет буфер вершин в графический процессор с помощью gl.drawElements.

melonJS доводит оптимизацию рисования до крайности.Он не только выполняет пакетную обработку с возможностью рендеринга, чтобы уменьшить количество вызовов отрисовки (как описано выше), но также не отправляет любые вызовы отрисовки, если отрисовать нечего.Это условие возникает, когда кадр идентичен последнему нарисованному кадру.Например, ни одна сущность не переместилась, область просмотра не прокрутилась, незанятые анимации не перешли в следующее состояние, экранный таймер не прошел целую секунду и т. Д.

Возможно принудительно вызвать кадрчтобы перерисовать, если какая-либо сущность в сцене возвращает true из ее метода update.Это сигнал игровому движку о том, что кадр нужно перерисовать.Этот процесс более подробно описан в вики .

...