Support expressions for band arguments

This commit is contained in:
Tim Schaub
2021-12-03 17:23:55 -07:00
parent 4ed1226411
commit f5803ad6ca
9 changed files with 254 additions and 44 deletions
+15 -11
View File
@@ -105,6 +105,7 @@ function parseStyle(style, bandCount) {
variables: [],
attributes: [],
stringLiteralsMap: {},
functions: {},
bandCount: bandCount,
};
@@ -203,14 +204,15 @@ function parseStyle(style, bandCount) {
});
const textureCount = Math.ceil(bandCount / 4);
const colorAssignments = new Array(textureCount);
for (let textureIndex = 0; textureIndex < textureCount; ++textureIndex) {
const uniformName = Uniforms.TILE_TEXTURE_PREFIX + textureIndex;
uniformDeclarations.push(`uniform sampler2D ${uniformName};`);
colorAssignments[
textureIndex
] = `vec4 color${textureIndex} = texture2D(${uniformName}, v_textureCoord);`;
}
uniformDeclarations.push(
`uniform sampler2D ${Uniforms.TILE_TEXTURE_ARRAY}[${textureCount}];`
);
const functionDefintions = Object.keys(context.functions).map(function (
name
) {
return context.functions[name];
});
const fragmentShader = `
#ifdef GL_FRAGMENT_PRECISION_HIGH
@@ -228,10 +230,12 @@ function parseStyle(style, bandCount) {
${uniformDeclarations.join('\n')}
void main() {
${colorAssignments.join('\n')}
${functionDefintions.join('\n')}
vec4 color = color0;
void main() {
vec4 color = texture2D(${
Uniforms.TILE_TEXTURE_ARRAY
}[0], v_textureCoord);
${pipeline.join('\n')}
+2 -2
View File
@@ -31,7 +31,7 @@ import {numberSafeCompareFunction} from '../../array.js';
import {toSize} from '../../size.js';
export const Uniforms = {
TILE_TEXTURE_PREFIX: 'u_tileTexture',
TILE_TEXTURE_ARRAY: 'u_tileTextures',
TILE_TRANSFORM: 'u_tileTransform',
TRANSITION_ALPHA: 'u_transitionAlpha',
DEPTH: 'u_depth',
@@ -516,7 +516,7 @@ class WebGLTileLayerRenderer extends WebGLLayerRenderer {
++textureIndex
) {
const textureProperty = 'TEXTURE' + textureIndex;
const uniformName = Uniforms.TILE_TEXTURE_PREFIX + textureIndex;
const uniformName = `${Uniforms.TILE_TEXTURE_ARRAY}[${textureIndex}]`;
gl.activeTexture(gl[textureProperty]);
gl.bindTexture(gl.TEXTURE_2D, tileTexture.textures[textureIndex]);
gl.uniform1i(
+34 -25
View File
@@ -184,6 +184,7 @@ export function isTypeUnique(valueType) {
* @property {Array<string>} variables List of variables used in the expression; contains **unprefixed names**
* @property {Array<string>} attributes List of attributes used in the expression; contains **unprefixed names**
* @property {Object<string, number>} stringLiteralsMap This object maps all encountered string values to a number
* @property {Object<string, string>} functions Lookup of functions used by the style.
* @property {number} [bandCount] Number of bands per pixel.
*/
@@ -417,6 +418,8 @@ Operators['var'] = {
},
};
const GET_BAND_VALUE_FUNC = 'getBandValue';
Operators['band'] = {
getReturnType: function (args) {
return ValueTypes.NUMBER;
@@ -425,32 +428,38 @@ Operators['band'] = {
assertArgsMinCount(args, 1);
assertArgsMaxCount(args, 3);
const band = args[0];
if (typeof band !== 'number') {
throw new Error('Band index must be a number');
}
const zeroBasedBand = band - 1;
const colorIndex = Math.floor(zeroBasedBand / 4);
let bandIndex = zeroBasedBand % 4;
if (band === context.bandCount && bandIndex === 1) {
// LUMINANCE_ALPHA - band 1 assigned to rgb and band 2 assigned to alpha
bandIndex = 3;
}
if (args.length === 1) {
return `color${colorIndex}[${bandIndex}]`;
} else {
const xOffset = args[1];
const yOffset = args[2] || 0;
assertNumber(xOffset);
assertNumber(yOffset);
const uniformName = Uniforms.TILE_TEXTURE_PREFIX + colorIndex;
return `texture2D(${uniformName}, v_textureCoord + vec2(${expressionToGlsl(
context,
xOffset
)} / ${Uniforms.TEXTURE_PIXEL_WIDTH}, ${expressionToGlsl(
context,
yOffset
)} / ${Uniforms.TEXTURE_PIXEL_HEIGHT}))[${bandIndex}]`;
if (!(GET_BAND_VALUE_FUNC in context.functions)) {
let ifBlocks = '';
const bandCount = context.bandCount || 1;
for (let i = 0; i < bandCount; i++) {
const colorIndex = Math.floor(i / 4);
let bandIndex = i % 4;
if (bandIndex === bandCount - 1 && bandIndex === 1) {
// LUMINANCE_ALPHA - band 1 assigned to rgb and band 2 assigned to alpha
bandIndex = 3;
}
const textureName = `${Uniforms.TILE_TEXTURE_ARRAY}[${colorIndex}]`;
ifBlocks += `
if (band == ${i + 1}.0) {
return texture2D(${textureName}, v_textureCoord + vec2(dx, dy))[${bandIndex}];
}
`;
}
context.functions[GET_BAND_VALUE_FUNC] = `
float getBandValue(float band, float xOffset, float yOffset) {
float dx = xOffset / ${Uniforms.TEXTURE_PIXEL_WIDTH};
float dy = yOffset / ${Uniforms.TEXTURE_PIXEL_HEIGHT};
${ifBlocks}
}
`;
}
const bandExpression = expressionToGlsl(context, band);
const xOffsetExpression = expressionToGlsl(context, args[1] || 0);
const yOffsetExpression = expressionToGlsl(context, args[2] || 0);
return `${GET_BAND_VALUE_FUNC}(${bandExpression}, ${xOffsetExpression}, ${yOffsetExpression})`;
},
};
+2
View File
@@ -441,6 +441,7 @@ export function parseLiteralStyle(style) {
variables: [],
attributes: [],
stringLiteralsMap: {},
functions: {},
};
const parsedSize = expressionToGlsl(
vertContext,
@@ -471,6 +472,7 @@ export function parseLiteralStyle(style) {
variables: vertContext.variables,
attributes: [],
stringLiteralsMap: vertContext.stringLiteralsMap,
functions: {},
};
const parsedColor = expressionToGlsl(fragContext, color, ValueTypes.COLOR);
const parsedOpacity = expressionToGlsl(