The Transform
class provides easy interface to perform Transform Feedback operations on given data. Applications can use this class to move data processing from CPU to GPU, where multiple parallel execution units will be used for processing. Data is handled in form of Buffer
objects, i.e. data resides in the GPU memory. Output of this class can directly set as attributes on Model
or VertexArray
for regular rendering operations, CPU access is not required hence avoids expensive CPU and GPU sync.
Transform
class creates and holds Model
and TransformFeedback
instances.
This class is only supported when using WebGL2RenderingContext
.
Create a Transform
object by passing, vs (vertex shader), source buffer(s), varyings (output variable names in vertex shader) and destination buffers. Then call run
to perform one transform feedback iteration.
const VS = `\
#version 300 es
attribute float inValue;
varying float outValue;
void main()
{
outValue = 2.0 * inValue;
}
`;
const sourceData = new Float32Array([10, 20, 31, 0, -57]);
const sourceBuffer = new Buffer(gl, {data: sourceData});
// Default values applied for size (1) and type (gl.FLOAT)
const feedbackBuffer = new Buffer(gl, {byteLength: sourceData.length * 4});
const transform = new Transform(gl2, {
sourceBuffers: {
inValue: sourceBuffer
},
feedbackBuffers: {
outValue: feedbackBuffer
},
vs: VS,
varyings: ['outValue'],
elementCount: 5
});
// Perform one transform feedback iteration
transform.run();
Transform
can internally create destination buffers (i.e. feedback buffers), when feedbackMap
is provided. Each destination buffer is created with same settings and layout as corresponding source buffer as per feedbackMap
.
const transform = new Transform(gl2, {
sourceBuffers: {
inValue: sourceBuffer
},
feedbackMap: {
inValue: 'outValue'
},
vs: VS,
varyings: ['outValue'],
elementCount: 5
});
When feedbackMap
is specified buffers can be swapped using a single call to swap()
, this is useful for cases like particle simulation, where output of one transform feedback iteration is piped as input to the next iteration.
// Setup Transform with `feedbackMap` as above
transform.run();
let bufferWithNewValues = transform.getBuffer('outValue');
...
// Render using 'bufferWithNewValues'
...
//swap buffers
transform.swap();
transform.run();
bufferWithNewValues = transform.getBuffer('outValue');
...
// Render using 'bufferWithNewValues'
...
Once Transform
object is constructed and used, one or more source or destination buffers can be updated using update
.
// transform is set up as above
...
// update buffer binding for 'inValue' attribute
const newSourceBuffer = new Buffer(gl, {data: newSourceData});
transform.update({
sourceBuffers: {
inValue: newSourceBuffer
}
});
// now data is provided from newly bound buffer.
transform.run();
In addition to reading data from Buffer objects, Transform can read from texture objects. Transform allows to access texture data in the same way as buffer data and internally generates required texture co-ordinates and sample instructions.
// simple shader that adds data from a buffer and texture to generate new buffer.
const vs = `\
#version 300 es
in float inBuffer;
in float inTexture;
out float outBuffer;
void main()
{
outBuffer = inTexture + inBuffer;
}`;
const sourceBuffer = new Buffer(...);
const sourceTexture = new Texture2D(...);
const transform = new Transform(gl2, {
sourceBuffers: {
inBuffer: sourceBuffer
},
// specify source texture object using input attribute name
_sourceTextures: {
inTexture: sourceTexture
},
vs,
feedbackMap: {
inBuffer: 'outBuffer'
},
elementCount
});
transform.run();
// resulting buffer contains sum of input buffer and texture data.
const outData = transform.getBuffer('outBuffer').getData();
In addition to reading data from a texture object, Transform can generate texture object, by rendering data into it offline. Source data can be either buffer(s), texture(s) or any combination.
const vs = `\
#version 300 es
in vec4 inTexture;
out vec4 outTexture;
void main()
{
outTexture = 2. * inTexture;
}
`
const sourceTexture = new Texture2D(...);
const transform = new Transform(gl2, {
_sourceTextures: {
inTexture: sourceTexture
},
_targetTexture: 'inTexture',
_targetTextureVarying: 'outTexture',
vs,
elementCount
});
transform.run();
const outTexture = transform._getTargetTexture();
Constructs a Transform
object. It then creates destination buffers if needed and binds the buffers to Model
and TransformFeedback
objects.
gl
(WebGL2RenderingContext
) gl - contextprops.sourceBuffers
(Object
) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding Attribute
, Buffer
or attribute descriptor object.props.feedbackBuffers
(Object
, Optional) - key and value pairs, where key is the name of vertex shader varying and value is the corresponding Buffer
object or buffer params object. If a buffer params object is specified, it will contain following fields, these can be used to capture data into the buffer a particular offset and size.buffer
=(Buffer) - Buffer object to be bound.byteOffset
=(Number, default: 0) - Byte offset that is used to start recording the data in the buffer.byteSize
=(Number, default: remaining buffer size) - Size in bytes that is used for recording the data.props.vs
(String
) - vertex shader string.props.modules
- shader modules to be applied.props.varyings
(Array
) - Array of vertex shader varyings names. When not provided this can be deduced from feedbackMap
. Either varyings
or feedbackMap
must be provided.props.feedbackMap
(Object
, Optional) - key and value pairs, where key is a vertex shader attribute name and value is a vertex shader varying name.props.drawMode
(GLEnum
= gl.POINTS, Optional) - Draw mode to be set on Model
and TransformFeedback
objects during draw/render time.props.elementCount
(Integer
) - Number set to vertex count when rendering the model.props._sourceTextures
(Object
) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding Texture2D
object.props._targetTexture
(Texture2D
or String
) - Defines texture object that is used as color attachment for rendering. If Texture2D
object, it is used as is, if String
, it must be one of the source texture attributes name, a new texture object is cloned from corresponding texture and used as color attachment.props._targetTextureVarying
(String
) : varying name used in vertex shader who's data should go into target texture.props._swapTexture
(String
) : source texture attribute name, that is swapped with target texture every time swap()
is called.props._fs
(String
, Optional) - fragment shader string, when rendering to a texture, fragments can be processed using this custom shader, when not specified, pass through fragment shader will be used.Notes:
Model
, TransformFeedback
and Framebuffer
instances.Deletes all owned resources, Model
, TransformFeedback
and any Buffer
objects that are crated internally.
Returns current destination buffer corresponding to given varying name.
varyingName
(String
) - varying name.Reads and returns data from current destination buffer corresponding to the given varying name. When no 'varyingName' is provided, it reads and returns data from current target texture.
options.varyingName
(String
, Optional) - when specified, first checks if there is a corresponding feedback buffer, if so reads data from this buffer and returns. When not specified, there must be target texture and data is read from this texture and returned.options.packed
(Boolean, Optional, Default: false) - applicable only when reading data from target texture, when true, data is packed to the actual size varyings. When false return array contains 4 values (R, G, B and A) for each element. Un-used element value will be 0 for R, G and B and 1 for A channel.When rendering to a texture, i.e. _targetTexture
is set, Transform
class internally setups a Framebuffer
object. getFramebuffer()
returns this Framebuffer
object.
Performs one transform feedback iteration.
uniforms
=null
(Object
= {}, Optional) - Sets uniforms before rendering.unbindModels
=[]
(Model[]) - Array of models whose VertexAttributes will be temporarily unbound during the transform feedback to avoid triggering a possible Khronos/Chrome bug.Updates buffer bindings with provided buffer objects for one or more source or destination buffers.
props.sourceBuffers
(Object
) - key and value pairs, where key is the name of vertex shader attribute and value is the corresponding Attribute
, Buffer
or attribute descriptor object.props.feedbackBuffers
(Object
, Optional) - key and value pairs, where key is the name of vertex shader varying and value is the corresponding Buffer
object.props.elementCount
(Integer
, Optional) - Number set to vertex count when rendering the model. If not supplied, the previously set element count is used.Swaps source and destination buffers and textures. Buffer swapping is performed when feedbackMap
is provided and texture swapping is performed when _swapTexture
is provided. If buffer swapping is needed, sourceBuffers
and feedbackBuffers
supplied to the constructor and/or the update
method must be Buffer
objects.
When transform is setup to render to a texture, returns current target texture, otherwise null.