Pixi.js: Keine Möglichkeit, Formen ohne Grafiken zu rendern

Erstellt am 9. Sept. 2016  ·  18Kommentare  ·  Quelle: pixijs/pixi.js

Hey, ich denke, ich sollte in der Lage sein, Rechtecke zu rendern, ohne auf Grafikobjekte zeichnen zu müssen. Es würde eine Menge meines Codes so viel einfacher machen! :)

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

Hilfreichster Kommentar

@GoodBoyDigital Natürlich. Das Team ist derzeit damit beschäftigt, eine soziale Netzwerk- und Echtzeit-Messaging-Infrastruktur für die Zusammenarbeit/Community/sozialen Aspekte unserer App aufzubauen, und wir werden daher frühestens im Dezember aus der Beta-Phase herauskommen, also kann ich das nicht wirklich zulassen hat jemand jetzt ein Spiel. Aber sobald wir das sind, werden wir einen Entwickler-Blog einrichten, der unsere Reise, Herausforderungen und Techniken usw. beschreibt. Sobald das soweit ist, werde ich es mit euch teilen.

Und sobald wir auf PIXI Version 4 migriert sind, werden wir anfangen zu prüfen, was wir in Bezug auf Plugins usw. möglicherweise wieder in PIXI einbauen können. Ich denke, das Textlayout und die Darstellung von SDF-Schriftarten wären für den Anfang ein großer Segen für euch.

Alle 18 Kommentare

Sicherlich etwas, das wir uns ansehen könnten :)

Nun, Sie können den Ansatz "Graphics._renderSpriteRect" verwenden. Graphics verwendet renderTexture und Sprites für einfache Rechtecke, Sie können dasselbe tun: Erstellen Sie renderTexture und verwenden Sie dann Sprites.

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

Wir rendern Rechtecke, Dreiecke und Kreise nur mit benutzerdefinierten Shadern. Es ist viel schneller als die Verwendung von Pixi Graphics-Objekten und alle Kanten werden vollständig geglättet, da eine Abstandsfeldberechnung im Shader verwendet wird.

Das Hinzufügen von Umrissen, Glühen, Schatten und anderen Effekten zu diesen Formen ist trivial. Wir passen einfach Farbe, Strichbreite, Strichfarbe und verschiedene Effektuniformen für die Shader an.

Ich würde vorschlagen, Shader-basiertes Rendern von Formen/Primitiven für eine zukünftige Version von Pixi zu prüfen, da es dem aktuellen Ansatz unendlich überlegen ist.

Ja, aber die Sache ist, dass Rendertexturen viel CPU-lastiger sind als einfache Primitiven (ein Rechteck ist ein texturloses Quad mit einem Shader), und wenn ich diese Form stark skalieren muss (was ich normalerweise tue), dann wird es beides tun Leistung Nehmen Sie einen Treffer oder es wird viel mehr Code erfordern.

Das klingt wirklich interessant @GordoRank ! Würde gerne deine Umsetzung sehen!

@Dadibom - Graphics Rectangles sind im Moment in Pixi super optimiert, da sie in das Sprite-System gestapelt werden. Das passiert alles hinter den Kulissen :)

Ich denke, wonach Sie fragen, ist eine kurze Methode zum Erstellen eines Rechtecks?

Ja, aber ich muss immer noch eine Textur löschen und sie in jedem Frame neu zeichnen, anstatt nur die einzelnen Rechtecke zu verschieben

Wie kommt es, dass Sie sie in jedem Frame löschen müssen?

@Dadibom verwendet mehrere Grafiken, ändert jedes Mal die Position.

Wenn Sie etwas benutzerdefiniertes Set haben, machen Sie es bitte zu einem Plugin. Vor allem, wenn Ihre Sachen an Plots gebunden sind. https://github.com/pixijs/pixi-plugin-example . Es wird auch anderen helfen.

Funktioniert nicht, wenn ich die Größe ändern möchte :(

Sicher, ich kann Skala verwenden. Aber es ist viel mehr Code, als es sein muss

Wir haben im Grunde eine komplette PIXI-gestützte Desktop-Publishing-Anwendung (Shader-basiertes SDF-Text-Rendering / -Formatierung, Fotobearbeitung, Seitenlayout, Zeichnen, Bezierkurven usw.). Wir haben PIXI einfach stark erweitert, um unseren Anforderungen gerecht zu werden.

Dies ist eine alte PIXI 3.0-Version eines Kreis-/Ellipsen-Shaders, mit dem Sie Breite, Höhe, Deckkraft, Strichbreite, Füllfarbe und Strichfarbe festlegen können.

Es ist ein bisschen chaotisch und könnte verbessert werden, aber es funktioniert perfekt für uns. Wir haben ähnliche Shader für Rechtecke, Dreiecke und spitze Sterne.

Diese Shader werden auf einen benutzerdefinierten Pixi-Renderer angewendet, der die Shader einfach auf ein texturloses Quad anwendet.

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

Ich habe die Eigenschaftsdefinitionen entfernt, um diesen Kommentar kurz zu halten.

@GoodBoyDigital , weil ich das alte Rechteck loswerden muss

@Dadibom gut. Sie sind auf halbem Weg zum offiziellen Pixi-Plugin.

Für v4 können Sie den "args"-Parameter des Shaders entfernen, Argumente werden automatisch extrahiert. Außerdem können Sie nichts auf Uniformen setzen, es sei denn, der Shader ist gebunden. Wenn der Renderer Wert auf Uniformen legt, muss es ungefähr so ​​sein:

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

Sehen Sie sich den Beispiel-Renderer an.

Außerdem kann Shader-Code mit glsify in "frag"- und "vert"-Dateien aufgeteilt werden, Beispiel hat es auch.

@GordoRank Das ist wirklich aufregend! Würdest du in Betracht ziehen, das zu teilen, was du hast - ich denke, viele Pixi-Benutzer würden das, was du geschaffen hast, wirklich großartig finden :)

@GoodBoyDigital Natürlich. Das Team ist derzeit damit beschäftigt, eine soziale Netzwerk- und Echtzeit-Messaging-Infrastruktur für die Zusammenarbeit/Community/sozialen Aspekte unserer App aufzubauen, und wir werden daher frühestens im Dezember aus der Beta-Phase herauskommen, also kann ich das nicht wirklich zulassen hat jemand jetzt ein Spiel. Aber sobald wir das sind, werden wir einen Entwickler-Blog einrichten, der unsere Reise, Herausforderungen und Techniken usw. beschreibt. Sobald das soweit ist, werde ich es mit euch teilen.

Und sobald wir auf PIXI Version 4 migriert sind, werden wir anfangen zu prüfen, was wir in Bezug auf Plugins usw. möglicherweise wieder in PIXI einbauen können. Ich denke, das Textlayout und die Darstellung von SDF-Schriftarten wären für den Anfang ein großer Segen für euch.

Tolle! Ich (und ich bin mir sicher, der Rest der Pixi-Community) freue mich auf den Dezember :)
Viel Glück mit Ihrem Beta-Release!

Dieses Problem wurde automatisch als veraltet markiert, da es in letzter Zeit keine Aktivität gab. Es wird geschlossen, wenn keine weiteren Aktivitäten stattfinden. Vielen Dank für Ihre Beiträge.

Ich bringe Leben in diesen alten Thread, da mich zwei Aspekte interessieren, die @GordoRank erwähnt.

  1. Shader-basiertes SDF-Text-Rendering
  2. Shader-basiertes Rendern von Formen

Haben Sie jemals eine Ihrer Arbeiten öffentlich veröffentlicht?

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen