Pixi.js: Невозможно визуализировать фигуры без графики

Созданный на 9 сент. 2016  ·  18Комментарии  ·  Источник: pixijs/pixi.js

Эй, я думаю, что я должен иметь возможность отображать прямоугольники без необходимости рисовать графические объекты. Это сделало бы мой код намного проще! :)

Stale 💾 v4.x (Legacy) 📢 Accepting PRs 🥶 Low Priority

Самый полезный комментарий

@GoodBoyDigital Конечно. В настоящее время команда занимается созданием социальной сети и инфраструктуры обмена сообщениями в реальном времени для совместной работы/сообщества/социального аспекта нашего приложения, и поэтому мы не выйдем из бета-версии не раньше декабря, поэтому я не могу позволить у кого-нибудь есть игра сейчас. Но как только мы это сделаем, мы настроим блог разработчиков, описывающий наш путь, проблемы, методы и т. д. Как только это будет сделано, я поделюсь с вами, ребята.

И как только мы перейдем на PIXI версии 4, мы начнем рассматривать то, что мы потенциально можем вернуть в PIXI с точки зрения плагинов и т. д. Я думаю, что макет текста и рендеринг шрифтов SDF будут огромным подспорьем для вас, ребята, для начинающих.

Все 18 Комментарий

Наверняка есть на что посмотреть :)

Что ж, вы можете использовать подход «Graphics._renderSpriteRect». Graphics использует renderTexture и спрайты для простых прямоугольников, вы можете сделать то же самое: создать renderTexture, а затем использовать спрайты.

var rect = this.graphicsData[0].shape;
    if(!this._spriteRect)
    {
        if(!Graphics._SPRITE_TEXTURE)
        {
            Graphics._SPRITE_TEXTURE = RenderTexture.create(10, 10);

            var currentRenderTarget = renderer._activeRenderTarget;
            renderer.bindRenderTexture(Graphics._SPRITE_TEXTURE);
            renderer.clear([1,1,1,1]);
            renderer.bindRenderTarget(currentRenderTarget);
        }

        this._spriteRect = new Sprite(Graphics._SPRITE_TEXTURE);
    }
    if (this.tint === 0xffffff) {
        this._spriteRect.tint = this.graphicsData[0].fillColor;
    } else {
        var t1 = tempColor1;
        var t2 = tempColor2;
        utils.hex2rgb(this.graphicsData[0].fillColor, t1);
        utils.hex2rgb(this.tint, t2);
        t1[0] *= t2[0];
        t1[1] *= t2[1];
        t1[2] *= t2[2];
        this._spriteRect.tint = utils.rgb2hex(t1);
    }
    this._spriteRect.alpha = this.graphicsData[0].fillAlpha;
    this._spriteRect.worldAlpha = this.worldAlpha * this._spriteRect.alpha;

    Graphics._SPRITE_TEXTURE._frame.width = rect.width;
    Graphics._SPRITE_TEXTURE._frame.height = rect.height;

    this._spriteRect.transform.worldTransform = this.transform.worldTransform;

    this._spriteRect.anchor.set(-rect.x / rect.width, -rect.y / rect.height);
    this._spriteRect.onAnchorUpdate();

    this._spriteRect._renderWebGL(renderer);

Мы визуализируем прямоугольники, треугольники и круги, используя только собственные шейдеры. Это намного быстрее, чем использование объектов Pixi Graphics, и все края полностью сглажены из-за использования вычисления поля расстояния в шейдере.

Добавление контуров, свечения, теней и других эффектов к этим формам тривиально. Мы просто настраиваем цвет, strokeWidth, strokeColor и униформы различных эффектов для шейдеров.

Я бы посоветовал изучить рендеринг форм/примитивов на основе шейдеров для будущей версии Pixi, поскольку он бесконечно превосходит текущий подход.

Да, но дело в том, что рендеринг-текстуры намного больше загружают процессор, чем должны быть простые примитивы (прямоугольник — это четырехугольник без текстур с шейдером), и если мне придется сильно изменить размер этой формы (что я обычно и делаю), то либо производительность упадет. принять удар или это потребует гораздо больше кода.

Звучит очень интересно @GordoRank ! Хотелось бы увидеть вашу реализацию!

@Dadibom - Графические прямоугольники в настоящее время супероптимизированы в pixi, поскольку они объединены в систему спрайтов. Все это делается за кадром :)

Я думаю, что вы просите, это короткий ручной способ создания прямоугольника?

Да, но мне по-прежнему приходится очищать текстуру и перерисовывать ее каждый кадр, а не просто перемещать отдельные прямоугольники.

Почему вам нужно очищать их каждый кадр?

@Dadibom использует несколько изображений, каждый раз меняя положение.

Что касается ваших примитивов, если у вас есть что-то нестандартное, сделайте это плагином. Особенно, если ваши вещи привязаны к сюжетам. https://github.com/pixijs/pixi-плагин-пример . Это поможет и другим.

Не работает, если я хочу изменить размер :(

Конечно, я могу использовать масштаб. Но это намного больше кода, чем должно быть.

По сути, у нас есть полноценное настольное издательское приложение на базе PIXI (рендеринг/форматирование текста SDF на основе шейдеров, редактирование фотографий, макет страницы, рисование, кривые Безье и т. д.). Мы просто значительно расширили PIXI, чтобы удовлетворить наши потребности.

Это старая версия PIXI 3.0 шейдера круга/эллипса, которая позволяет вам устанавливать ширину, высоту, непрозрачность, strokeWidth, fillColor и strokeColor.

Это немного грязно и может быть улучшено, но это работает отлично для нас. У нас есть похожие шейдеры для прямоугольников, треугольников и остроконечных звезд.

Эти шейдеры применяются к пользовательскому рендереру Pixi, который просто применяет шейдеры к четырехугольнику без текстуры.

PIXI.filters.CircleShader = function(shaderManager) {


    PIXI.Shader.call(this,
        shaderManager,
        // vertex shader
        [
            'precision lowp float;',
            'attribute vec2 aVertexPosition;',
            'attribute vec2 aTextureCoord;',
            'attribute vec4 aColor;',

            'uniform mat3 projectionMatrix;',

            'varying vec2 vTextureCoord;',
            'varying vec4 vColor;',

            'void main(void){',
            '   gl_Position = vec4((projectionMatrix * vec3(aVertexPosition, 1.0)).xy, 0.0, 1.0);',
            '   vTextureCoord = aTextureCoord;',
            '   vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
            '}'
        ].join('\n'),
        // fragment shader
        [
            '#extension GL_OES_standard_derivatives : enable',
            'precision mediump float;',

            'varying vec2 vTextureCoord;',

            'uniform float width;',
            'uniform float height;',
            'uniform float opacity;',
            'uniform vec4 fillColor;', 
            'uniform vec4 strokeColor;', 
            'uniform float strokeWidth;',

            'float texelSizeX = 1.0 / width;',
            'float texelSizeY = 1.0 / height;',

            'vec2 px = vec2(texelSizeX, texelSizeY);',
            'vec2 ab = vec2(width, height) / 2.0;',
            'vec2 center = vec2(0.5, 0.5);',


            'void main(void){',

            'vec2 pos = (vTextureCoord - center) / px;',
            'pos *= pos;',

            'float outerDist = dot(pos, 1.0 / (ab * ab));',

            'ab -= strokeWidth;',
            'float innerDist = dot(pos, 1.0 / (ab * ab));',

            'float outerDelta = length(vec2(dFdx(outerDist), dFdy(outerDist))) * 0.70710678118654757;',

            'float innerDelta = length(vec2(dFdx(innerDist), dFdy(innerDist))) * 0.70710678118654757;',

            'float innerAlpha = smoothstep(1.0 - innerDelta, 1.0 + innerDelta, innerDist);',
            'float outerAlpha = smoothstep(1.0 - outerDelta, 1.0 + outerDelta, outerDist);',


            'vec4 stroke = mix(strokeColor, vec4(0, 0, 0, 0), outerAlpha);',
            'vec4 fill = mix(fillColor, vec4(0, 0, 0, 0), innerAlpha);',

            'gl_FragColor = mix(vec4(0.0, 0.0, 0.0, 0.0), mix(fill, stroke, innerAlpha), opacity);',

            '}'
        ].join('\n'),
        // custom uniforms
        {
            dimensions: {
                type: '4fv',
                value: new Float32Array([0, 0, 0, 0])
            },
            projectionMatrix: { type: 'mat3', value: new Float32Array(9) },
            strokeWidth: {
                type: '1f',
                value: 0.0
            },
            strokeColor : { type: '4fv', value: new Float32Array([0, 0, 0, 0]) },
            fillColor : { type: '4fv', value: new Float32Array([0, 0, 0, 0]) },
            width : { type : '1f', value: 1.0},
            height : { type : '1f', value: 1.0},
            opacity : { type : '1f', value: 1.0}
        },
        // custom attributes
        {
            aTextureCoord:0,
            aVertexPosition:0,
            aColor:0
        }

    );


    this.strokeWidth = 0.0;
    this.strokeColor = new Float32Array([0, 0, 0, 0]);
    this.fillColor = new Float32Array([0, 0, 0, 0]);
    this.opacity = 1.0;


};

PIXI.filters.CircleShader.prototype = Object.create(PIXI.Shader.prototype);
PIXI.filters.CircleShader.prototype.constructor = PIXI.filters.CircleShader;

PIXI.ShaderManager.registerPlugin('circleShader', PIXI.filters.CircleShader);

Я убрал определения свойств, чтобы сделать этот комментарий кратким.

@GoodBoyDigital, потому что мне нужно избавиться от старого прямоугольника

@Dadibom хорошо. Вы на полпути к официальному плагину Pixi.

Для v4 вы можете удалить параметр "args" шейдера, аргументы будут извлекаться автоматически. Кроме того, вы не можете установить ничего в униформы, если шейдер не привязан. Когда рендерер устанавливает значение для униформ, оно должно быть примерно таким:

myShader.bind();
myShader.uniforms.strokeWidth = ...;

Посмотрите на пример рендерера.

Кроме того, код шейдера можно разделить на файлы «frag» и «vert», используя glsify, в примере это тоже есть.

@GordoRank Это действительно захватывающие вещи! Не могли бы вы поделиться тем, что у вас есть - я думаю, что многие пользователи пикси найдут то, что вы, ребята, создали, действительно потрясающим :)

@GoodBoyDigital Конечно. В настоящее время команда занимается созданием социальной сети и инфраструктуры обмена сообщениями в реальном времени для совместной работы/сообщества/социального аспекта нашего приложения, и поэтому мы не выйдем из бета-версии не раньше декабря, поэтому я не могу позволить у кого-нибудь есть игра сейчас. Но как только мы это сделаем, мы настроим блог разработчиков, описывающий наш путь, проблемы, методы и т. д. Как только это будет сделано, я поделюсь с вами, ребята.

И как только мы перейдем на PIXI версии 4, мы начнем рассматривать то, что мы потенциально можем вернуть в PIXI с точки зрения плагинов и т. д. Я думаю, что макет текста и рендеринг шрифтов SDF будут огромным подспорьем для вас, ребята, для начинающих.

Удивительно! Я (и я уверен, что остальная часть сообщества пикси) с нетерпением жду декабря :)
Удачи с выпуском бета-версии!

Эта проблема была автоматически помечена как устаревшая, поскольку в последнее время в ней не было активности. Он будет закрыт, если никакой дальнейшей активности не произойдет. Спасибо за ваш вклад.

Вдохнуть жизнь в эту старую ветку, так как меня интересуют два аспекта, которые упоминает @GordoRank .

  1. Рендеринг текста SDF на основе шейдеров
  2. рендеринг фигур на основе шейдеров

Вы когда-нибудь публиковали свои работы для широкой публики?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

softshape picture softshape  ·  3Комментарии

samueller picture samueller  ·  3Комментарии

Darker picture Darker  ·  3Комментарии

lucap86 picture lucap86  ·  3Комментарии

Makio64 picture Makio64  ·  3Комментарии