Quantcast
Channel: Pixi.js Latest Topics
Viewing all articles
Browse latest Browse all 3978

Structs as uniform type (in fragment shader)

$
0
0

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

 


Viewing all articles
Browse latest Browse all 3978

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>