Better handle uniform locations in shaders

This commit is contained in:
Olivier Guyot
2018-11-14 14:02:09 +01:00
parent 66efee9e22
commit fc20dc986c
2 changed files with 77 additions and 50 deletions

View File

@@ -8,46 +8,46 @@ import WebGLContext, {DefaultUniform} from '../../webgl/Context';
import WebGLVertex from "../../webgl/Vertex"; import WebGLVertex from "../../webgl/Vertex";
import WebGLFragment from "../../webgl/Fragment"; import WebGLFragment from "../../webgl/Fragment";
const VERTEX_SHADER = const VERTEX_SHADER = `
'attribute vec2 a_position;' + attribute vec2 a_position;
'attribute vec2 a_texCoord;' + attribute vec2 a_texCoord;
'attribute float a_opacity;' + attribute float a_opacity;
'attribute float a_rotateWithView;' + attribute float a_rotateWithView;
'' +
'uniform mat4 u_projectionMatrix;' + uniform mat4 u_projectionMatrix;
'uniform mat4 u_offsetScaleMatrix;' + uniform mat4 u_offsetScaleMatrix;
'uniform mat4 u_offsetRotateMatrix;' + uniform mat4 u_offsetRotateMatrix;
'' +
'varying vec2 v_texCoord;' + varying vec2 v_texCoord;
'varying float v_opacity;' + varying float v_opacity;
'' +
'void main(void) {' + void main(void) {
' mat4 offsetMatrix = u_offsetScaleMatrix;' + mat4 offsetMatrix = u_offsetScaleMatrix;
' if (a_rotateWithView == 1.0) {' + if (a_rotateWithView == 1.0) {
' offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;' + offsetMatrix = u_offsetScaleMatrix * u_offsetRotateMatrix;
' }' + }
' vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);' + vec4 offsets = offsetMatrix * vec4(a_offsets, 0.0, 0.0);
' gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;' + gl_Position = u_projectionMatrix * vec4(a_position, 0.0, 1.0) + offsets;
' v_texCoord = a_texCoord;' + v_texCoord = a_texCoord;
' v_opacity = a_opacity;' + v_opacity = a_opacity;
'}'; }`;
const FRAGMENT_SHADER = const FRAGMENT_SHADER = `
'uniform float u_opacity;' + uniform float u_opacity;
'uniform sampler2D u_image;' + uniform sampler2D u_image;
'' +
'varying vec2 v_texCoord;' + varying vec2 v_texCoord;
'varying float v_opacity;' + varying float v_opacity;
'' +
'void main(void) {' + void main(void) {
' vec4 texColor = texture2D(u_image, v_texCoord);' + vec4 texColor = texture2D(u_image, v_texCoord);
' gl_FragColor.rgb = texColor.rgb;' + gl_FragColor.rgb = texColor.rgb;
' float alpha = texColor.a * v_opacity * u_opacity;' + float alpha = texColor.a * v_opacity * u_opacity;
' if (alpha == 0.0) {' + if (alpha == 0.0) {
' discard;' + discard;
' }' + }
' gl_FragColor.a = alpha;' + gl_FragColor.a = alpha;
'}'; }`;
/** /**
* @classdesc * @classdesc
@@ -100,8 +100,8 @@ class WebGLPointsLayerRenderer extends LayerRenderer {
* @inheritDoc * @inheritDoc
*/ */
prepareFrame(frameState) { prepareFrame(frameState) {
const vectorLayer = this.getLayer(); const vectorLayer = /** @type {import("../../layer/Vector.js").default} */ (this.getLayer());
const vectorSource = vectorLayer.getSource(); const vectorSource = /** @type {import("../../source/Vector.js").default} */ (vectorLayer.getSource());
if (this.sourceRevision_ >= vectorSource.getRevision()) { if (this.sourceRevision_ >= vectorSource.getRevision()) {
return false; return false;

View File

@@ -28,7 +28,7 @@ import {create, fromTransform} from "../vec/mat4";
export const DefaultUniform = { export const DefaultUniform = {
PROJECTION_MATRIX: 'u_projectionMatrix', PROJECTION_MATRIX: 'u_projectionMatrix',
SCALE_MATRIX: 'u_offsetScaleMatrix', OFFSET_SCALE_MATRIX: 'u_offsetScaleMatrix',
OFFSET_ROTATION_MATRIX: 'u_offsetRotateMatrix', OFFSET_ROTATION_MATRIX: 'u_offsetRotateMatrix',
OPACITY: 'u_opacity' OPACITY: 'u_opacity'
}; };
@@ -115,9 +115,17 @@ class WebGLContext extends Disposable {
*/ */
this.offsetScaleMatrix_ = createTransform(); this.offsetScaleMatrix_ = createTransform();
/**
* @private
* @type {Array<number>}
*/
this.tmpMat4_ = create(); this.tmpMat4_ = create();
this.locations_ = {}; /**
* @private
* @type {Object.<string, WebGLUniformLocation>}
*/
this.locations_;
} }
/** /**
@@ -284,12 +292,21 @@ class WebGLContext extends Disposable {
rotateTransform(offsetRotateMatrix, -rotation); rotateTransform(offsetRotateMatrix, -rotation);
} }
this.getGL().uniformMatrix4fv(locations.u_projectionMatrix, false, this.setUniformMatrixValue(DefaultUniform.PROJECTION_MATRIX, fromTransform(this.tmpMat4_, projectionMatrix));
fromTransform(this.tmpMat4_, projectionMatrix)); this.setUniformMatrixValue(DefaultUniform.OFFSET_SCALE_MATRIX, fromTransform(this.tmpMat4_, offsetScaleMatrix));
this.getGL().uniformMatrix4fv(locations.u_offsetScaleMatrix, false, this.setUniformMatrixValue(DefaultUniform.OFFSET_ROTATION_MATRIX, fromTransform(this.tmpMat4_, offsetRotateMatrix));
fromTransform(this.tmpMat4_, offsetScaleMatrix)); }
this.getGL().uniformMatrix4fv(locations.u_offsetRotateMatrix, false,
fromTransform(this.tmpMat4_, offsetRotateMatrix)); /**
* Will get the location from the shader or the cache
* @param {string} name Uniform name
* @return {WebGLUniformLocation} uniformLocation
*/
getUniformLocation(name) {
if (!this.locations_[name]) {
this.locations_[name] = this.getGL().getUniformLocation(this.currentProgram_, name);
}
return this.locations_[name];
} }
/** /**
@@ -298,7 +315,16 @@ class WebGLContext extends Disposable {
* @param {number} value Value * @param {number} value Value
*/ */
setUniformFloatValue(uniform, value) { setUniformFloatValue(uniform, value) {
this.getGL().uniformMatrix4fv(this.locations_[uniform], false, value); this.getGL().uniform1f(this.getUniformLocation(uniform), value);
}
/**
* Give a value for a standard matrix4 uniform
* @param {string} uniform Uniform name
* @param {Array<number>} value Matrix value
*/
setUniformMatrixValue(uniform, value) {
this.getGL().uniformMatrix4fv(this.getUniformLocation(uniform), false, value);
} }
/** /**
@@ -330,6 +356,7 @@ class WebGLContext extends Disposable {
const gl = this.getGL(); const gl = this.getGL();
gl.useProgram(program); gl.useProgram(program);
this.currentProgram_ = program; this.currentProgram_ = program;
this.locations_ = {};
return true; return true;
} }
} }