0
$\begingroup$

as the question suggests im looking to output to more than one canvas element in processing to speed up the calculations and limit shader draw calls. It has to be as simple as possible to be transferable to android as well.

This is the shader call. Is there a way to do this using layout, if I was to provide another sampler texture?

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
#define PROCESSING_TEXTURE_SHADER
uniform float v[10];
uniform sampler2D texture;
uniform sampler2D va0;
uniform sampler2D vb0;
uniform sampler2D va1;
uniform sampler2D vb1;
uniform sampler2D va2;
uniform sampler2D vb2;
uniform sampler2D va3;
uniform sampler2D vb3;
uniform float mult = 1.0;
uniform float type;
uniform float thresh;
uniform vec2 texOffset;
varying vec4 vertColor;
varying vec4 vertTexCoord;
uniform vec2 resolution;
uniform float w;
uniform int [1000]s;
uniform float [10]ops;
uniform float [1000]vars;
void main(void) {
float x = 1.0 / resolution.x;
float y = 1.0 / resolution.y;
vec2 tx = vertTexCoord.st;
vec4 via0 = texture2D(va0 , vertTexCoord.st);
vec4 vib0 = texture2D(vb0 , vertTexCoord.st);
vec4 via1 = texture2D(va1 , vertTexCoord.st);
vec4 vib1 = texture2D(vb1 , vertTexCoord.st);
vec4 via2 = texture2D(va2 , vertTexCoord.st);
vec4 vib2 = texture2D(vb2 , vertTexCoord.st);
vec4 via3 = texture2D(va3 , vertTexCoord.st);
vec4 vib3 = texture2D(vb3 , vertTexCoord.st);
float base = 256;
float b1 = base*base*255;
float b2 = base*255;
float b3 = 255;
float tva0 = (via0.r*b1 + via0.g*b2 + via0.b*b3);
float tva1 = (via1.r*b1 + via1.g*b2 + via1.b*b3);
float tva2 = (via2.r*b1 + via2.g*b2 + via2.b*b3);
float tva3 = (via3.r*b1 + via3.g*b2 + via3.b*b3);
float tvb0 = (vib0.r*b1 + vib0.g*b2 + vib0.b*b3 )/100000;
float tvb1 = (vib1.r*b1 + vib1.g*b2 + vib1.b*b3 )/100000;
float tvb2 = (vib2.r*b1 + vib2.g*b2 + vib2.b*b3 )/100000;
float tvb3 = (vib3.r*b1 + vib3.g*b2 + vib3.b*b3 )/100000;
float tvf0 = (tvb0+tva0);
float tvf1 = (tvb1+tva1);
float tvf2 = (tvb2+tva2);
float tvf3 = (tvb3+tva3);
if(via0.a<1.0)tvf0= (tvb0+(-(tva0)*0.0));
if(via1.a<1.0)tvf1= (tvb1+(-(tva1)*0.0));
if(via2.a<1.0)tvf2= (tvb2+(-(tva2)*0.0));
if(via3.a<1.0)tvf3= (tvb3+(-(tva3)*0.0));
float num = ((tvf0)/(tvf1)*(tvf2)/(tvf3))*1.0;
float numf = 0.0;
if(num<0.0) numf = int(-num);
else numf = int(num);
float rni = round(mod (numf/(base*base), base))/255;
float gni = round(mod ((numf/base), base))/255;
float bni = round(mod (numf, base))/255;
if(numf>0.0)gl_FragColor = vec4(rni, gni, bni, 1.0);
else  gl_FragColor = vec4(rni, gni, bni, 0.5);
}
$\endgroup$

1 Answer 1

2
$\begingroup$

The generic term for multiple outputs from a fragment shader is MRT (multiple render targets).

The fragment shader setup code is something along the lines of:

layout( location=0 ) out vec4 colorOutput;
layout( location=1 ) out vec4 outVelocity; // names are abritrary

Output 0 would replace the default gl_FragColor assignment. Then later to assign values it is simply:

colorOutput = vec4(color,1);
outVelocity = vec4(velocityResults, 0, 0);

In the opengl setup code the layout locations correspond to the buffers that are created.

Creating the framebuffers is just the usual glGenFrameBuffer, glBindFrameBuffer. Using the java code extensions.

$\endgroup$
1
  • 2
    $\begingroup$ I only want to add, that when using MRT, the output targets need to have the same pixel resolution. $\endgroup$
    – Thomas
    Nov 15, 2022 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.