DNIWE

Members
  • Content Count

    4
  • Joined

  • Last visited

About DNIWE

  • Rank
    Newbie
  • Birthday December 27

Profile Information

  • Gender
    Male
  1. Too bad that the forum was down for so long... anyway I peeked at the problem that Ivan encountered in his V5 demos, and found out that syncUniformsGeneration function generates empty function (full story can be found here). Having done that I went back to v4 and got the thing working, with one little caveat that I feel like is worth mentioning. When testing out filters I found out by default the last shader is set active.So if you have multiple shaders setup, you'd have to manually "activate" appropriate shader before writing to uniforms, otherwise webgl would swear at you in console with red errors. In order to do that, however, you'd need access to shader created by this line (cached one will also be fine) 19478: shader = new _Shader2.default(this.gl, filter.vertexSrc, filter.fragmentSrc); However, it is a local variable of FilterManager's applyFilter function, so I ended up using this monstrocity as a workaround PIXI.InjectedApplication = class InjectedApplication extends PIXI.Application { constructor({width = arguments[0], height = arguments[1], options = arguments[2], noWebGL = arguments[3], sharedTicker = arguments[4], sharedLoader = arguments[5]}) { super(width, height, options, noWebGL, sharedTicker, sharedLoader); var oldSyncUniforms = this.renderer.filterManager.syncUniforms; this.renderer.filterManager.syncUniforms = function(shader, filter) { //shader is NOT of type PIXI.Shader but of _Shader2 ! //Call "vanilla" sync uniforms oldSyncUniforms.call(this, shader, filter); //Then call custom one if(filter.syncUniforms) { filter.syncUniforms(shader); } //Save references to filter //in order to be able to switch active shader. filter.__program = shader.program; filter.__shader = shader; }; } updateShader(shader, func) { //this.shaders is just a map of PIXI.Filter shaders let shdr = this.shaders[shader] || shader; let prev = this.renderer._activeShader; this.renderer.bindShader(shdr.__shader); //Make shader use program (openGL terms) func(shdr); //Execute function app.renderer.bindShader(prev); //Bind previous original shader back } } And the use example is simply this: function mouseMoveHandler(e) { let newpos = e.data.getLocalPosition(app.stage); app.updateShader('squareshader', function(shader) { //_uniforms are my custom uniforms and squares is array of structs in GLSL shader._uniforms['squares[0].coords'] = new Float32Array([newpos.x, newpos.y]); }); } Thank you, I already knew that. To my knowelage this also applies to arrays, ex. struct SomeInfo { vec4 color; }; uniform SomeInfo c[2]; to access 1st color the correct string for position getter would be "c[0].color"
  2. Thank you. I'm not bound to use v4, it's just the latest tag I checked out from repo that looked like a full release rather than rc.
  3. Hello. I'm making example filter with custom fragment shader. This is what I have in terms of shader code so far: //fragShader struct SomeInfo { vec4 color; }; uniform SomeInfo c; void main() { gl_FragColor = c.color; } The idea is to (eventually) make c into an array of Infos, which would be then operated on by the shader. What I'm struggling with is the definition of filter: how do I declare the uniform to be of type SomeInfo in Js code? I assume in plain WebGL, I'd have to bind uniform location (of c's property) by calling gl.getUniformLocation(program, "c.color") and create a uniform with appropriate gl.uniform4f(location, /* bunch of values*/), but can I do something similar via the existing filters means? Relevant part of my Js code looks like this: //Define base filter class for our future shaders/filters PIXI.filters.CustomFilterBase = class CustomFilterBase extends PIXI.Filter { constructor({ vertexSrc = null, fragmentSrc = null, uniforms = {}, enabled = true, debug = false, name = null } = {}) { if(debug && fragmentSrc !== null) { fragmentSrc = "#define DEBUG \r\n" + fragmentSrc; } //Add dimensions for scaling uniforms.dimensions = { type: 'vec2', value: { x: 0.0, y: 0.0 } }; super(vertexSrc, fragmentSrc, uniforms); name ? this._name = name : this._name = "CustomFilterBase"; this.autoFit = false; this.enabled = enabled; } apply(filterManager, input, output) { this.uniforms.dimensions.x = input.sourceFrame.width; this.uniforms.dimensions.y = input.sourceFrame.height; // draw the filter... filterManager.applyFilter(this, input, output); } } //Shader for prototyping and testing PIXI.filters.TestFilter = class TestFilter extends PIXI.filters.CustomFilterBase { constructor() { let fragmentSrc = document.getElementById('fragShader').innerHTML; let uniforms = { //What do I do here?! c: { type: 'vec4', //Judging by GLSL_SINGLE_SETTERS, only GLSL's primitives are recognized value: new Float32Array([0.0, 1.0, 0.0, 1.0]) } }; super({ vertexSrc: null, fragmentSrc: fragmentSrc, uniforms: uniforms, name: 'testfilter' }); } } (using pixijs v4.8.7) The expected result is green screen, as it is if I declare c as vec4 in shader code, but alas the screen is black, hinting on c's value being default constructed / not properly assigned Any help is appreciated, cheers! P.S. I tried to find similar cases from this forum and stackoverflow, but it seems that few people use structs in GLSL code. P.P.S. If it is of any help, I found that PIXI.glCore.shader removes specific characters from uniform's name (which looks like a hotfix rather than a feature) and that in fact one of iterations uniformData's name is 'c.color'. /** * Extracts the uniforms * @class * @memberof PIXI.glCore.shader * @param gl {WebGLRenderingContext} The current WebGL rendering context * @param program {WebGLProgram} The shader program to get the uniforms from * @return uniforms {Object} */ var extractUniforms = function(gl, program) { var uniforms = {}; var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); for (var i = 0; i < totalUniforms; i++) { var uniformData = gl.getActiveUniform(program, i); var name = uniformData.name.replace(/\[.*?\]/, ""); //<----- Here it is!! var type = mapType(gl, uniformData.type ); uniforms[name] = { type:type, size:uniformData.size, location:gl.getUniformLocation(program, name), value:defaultValue(type, uniformData.size) }; } return uniforms; };