Tutorials

Пользовательские пост-эффекты

В этом учебнике используется пользовательский пост-эффект для создания эффекта в GLSL

Обзор

Вы можете создавать собственные пост-эффекты в PlayCanvas с помощью немного Javascript и GLSL. Пост-эффекты - это шейдеры, которые работают с 2D отрендеренным изображением из камеры. Вы можете применять несколько пост-эффектов к вашему изображению - каждый эффект использует выход предыдущего эффекта в качестве своего входа.

В следующих абзацах мы продемонстрируем, как создать собственные пост-эффекты. Вы можете увидеть примеры существующих пост-эффектов здесь.

Скрипт

Сначала нам нужно создать новый скрипт. В этом скрипте будет содержаться определение шейдера для нашего пост-эффекта, а также код, который добавит пост-эффект к камере. Этот скрипт должен быть прикреплен к объекту Entity с компонентом камеры. Мы назовем этот скрипт posteffect_example.js:

Эффект

Теперь нам нужно создать новый класс для нашего пост-эффекта. Этот класс будет наследоваться от pc.posteffect.PostEffect. Мы определим этот класс внутри нашего скрипта posteffect_example.js прямо перед определением скрипта:

pc.extend(pc, function () {
    // Конструктор - создает экземпляр нашего пост-эффекта
    var ExamplePostEffect = function (graphicsDevice, vs, fs) {
        // это определение шейдера для нашего эффекта
        this.shader = new pc.Shader(graphicsDevice, {
            attributes: {
                aPosition: pc.SEMANTIC_POSITION
            },
            vshader: vs,
            fshader: fs
        });
    };

    // Наш эффект должен наследоваться от pc.PostEffect
    ExamplePostEffect = pc.inherits(ExamplePostEffect, pc.PostEffect);

    ExamplePostEffect.prototype = pc.extend(ExamplePostEffect.prototype, {
        // Каждый пост-эффект должен реализовывать метод render, который
        // устанавливает любые параметры, которые могут потребоваться шейдеру, и
        // также отображает эффект на экране
        render: function (inputTarget, outputTarget, rect) {
            var device = this.device;
            var scope = device.scope;

            // Установите входную цель рендеринга для шейдера. Это изображение, отображаемое с нашей камеры
            scope.resolve("uColorBuffer").setValue(inputTarget.colorBuffer);

            // Нарисуйте полноэкранный квадрат на выходной цели. В данном случае выходная цель - экран.
            // Рисование полноэкранного квадрата запустит шейдер, который мы определили выше
            pc.drawFullscreenQuad(device, outputTarget, this.vertexBuffer, this.shader, rect);
        }
    });

    return {
        ExamplePostEffect: ExamplePostEffect
    };
}());

Завершение

Теперь у нас есть все необходимые компоненты для нашего пост-эффекта. Все, что нам нужно сделать, это добавить экземпляр ExamplePostEffect, который мы определили выше, в очередь пост-эффектов нашей камеры. Вот полный список:

//--------------- ОПРЕДЕЛЕНИЕ POST EFFECT ------------------------//
pc.extend(pc, function () {
    // Конструктор - создает экземпляр нашего пост-эффекта
    var ExamplePostEffect = function (graphicsDevice, vs, fs) {
        // это определение шейдера для нашего эффекта
        this.shader = new pc.Shader(graphicsDevice, {
            attributes: {
                aPosition: pc.SEMANTIC_POSITION
            },
            vshader: vs,
            fshader: fs
        });
    };

    // Наш эффект должен наследоваться от pc.PostEffect
    ExamplePostEffect = pc.inherits(ExamplePostEffect, pc.PostEffect);

    ExamplePostEffect.prototype = pc.extend(ExamplePostEffect.prototype, {
        // Каждый пост-эффект должен реализовывать метод render, который
        // устанавливает любые параметры, которые могут потребоваться шейдеру, и
        // также отображает эффект на экране
        render: function (inputTarget, outputTarget, rect) {
            var device = this.device;
            var scope = device.scope;

            // Устанавливаем входной рендер-таргет для шейдера. Это изображение, отрендеренное нашей камерой
            scope.resolve("uColorBuffer").setValue(inputTarget.colorBuffer);

            // Рисуем полноэкранный квадрат на выходном таргете. В данном случае выходной таргет - это экран.
            // Рисование полноэкранного квадрата запустит шейдер, который мы определили выше
            pc.drawFullscreenQuad(device, outputTarget, this.vertexBuffer, this.shader, rect);
        }
    });

    return {
        ExamplePostEffect: ExamplePostEffect
    };
}());

//--------------- ОПРЕДЕЛЕНИЕ СКРИПТА ------------------------//
var PosteffectExample = pc.createScript('posteffectExample');

PosteffectExample.attributes.add('vs', {
    type: 'asset',
    assetType: 'shader',
    title: 'Vertex Shader'
});

PosteffectExample.attributes.add('fs', {
    type: 'asset',
    assetType: 'shader',
    title: 'Fragment Shader'
});

// инициализация кода, вызываемого один раз для каждой сущности
PosteffectExample.prototype.initialize = function() {
    var effect = new pc.ExamplePostEffect(this.app.graphicsDevice, this.vs.resource, this.fs.resource);

    // добавляем эффект в очередь postEffects камеры
    var queue = this.entity.camera.postEffects;
    queue.addEffect(effect);

    // когда скрипт включен, добавляем наш эффект в очередь postEffects камеры
    this.on('enable', function () {
        queue.addEffect(effect, false);
    });

    // когда скрипт отключен, удаляем наш эффект из очереди postEffects камеры
    this.on('disable', function () {
        queue.removeEffect(effect);
    });


};

Для большего количества учебников по пользовательским шейдерам смотрите здесь.

Посмотрите проект Custom Post Effects здесь.

This site is translated by the community. If you want to get involved visit this page