mirror of https://gitee.com/antv-l7/antv-l7
feat: 渲染流程清理
This commit is contained in:
parent
383ba2df7e
commit
f519a6dce0
|
@ -1302,17 +1302,13 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
}
|
||||
|
||||
public renderModels(isPicking?: boolean) {
|
||||
// TODO: this.getEncodedData().length > 0 这个判断是为了解决在 2.5.x 引入数据纹理后产生的 空数据渲染导致 texture 超出上限问题
|
||||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.hooks.beforeRender.call();
|
||||
this.models.forEach((model) => {
|
||||
model.draw(
|
||||
{
|
||||
uniforms: {},
|
||||
},
|
||||
isPicking,
|
||||
}
|
||||
);
|
||||
});
|
||||
this.hooks.afterRender.call();
|
||||
|
|
|
@ -48,54 +48,6 @@ export default class DataMappingPlugin implements ILayerPlugin {
|
|||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
// remapping before render
|
||||
layer.hooks.beforeRender.tap('DataMappingPlugin', () => {
|
||||
const source = layer.getSource();
|
||||
if (layer.layerModelNeedUpdate || !source || !source.inited) {
|
||||
return;
|
||||
}
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||
const { dataArray } = source.data;
|
||||
// TODO 数据为空的情况
|
||||
if (Array.isArray(dataArray) && dataArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const attributesToRemapping = attributes.filter(
|
||||
(attribute) => attribute.needRemapping, // 如果filter变化
|
||||
);
|
||||
let filterData = dataArray;
|
||||
// 数据过滤完 再执行数据映射
|
||||
if (filter?.needRemapping && filter?.scale) {
|
||||
filterData = dataArray.filter((record: IParseDataItem) => {
|
||||
return this.applyAttributeMapping(filter, record)[0];
|
||||
});
|
||||
}
|
||||
|
||||
if (attributesToRemapping.length) {
|
||||
// 过滤数据
|
||||
if (filter?.needRemapping) {
|
||||
const encodeData = this.mapping(
|
||||
layer,
|
||||
attributes,
|
||||
filterData,
|
||||
undefined,
|
||||
);
|
||||
layer.setEncodedData(encodeData);
|
||||
filter.needRemapping = false;
|
||||
} else {
|
||||
const encodeData = this.mapping(
|
||||
layer,
|
||||
attributesToRemapping,
|
||||
filterData,
|
||||
layer.getEncodedData(),
|
||||
);
|
||||
layer.setEncodedData(encodeData);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private generateMaping(
|
||||
layer: ILayer,
|
||||
|
|
|
@ -78,27 +78,6 @@ export default class FeatureScalePlugin implements ILayerPlugin {
|
|||
return true;
|
||||
},
|
||||
);
|
||||
|
||||
layer.hooks.beforeRender.tap('FeatureScalePlugin', () => {
|
||||
if (layer.layerModelNeedUpdate) {
|
||||
return;
|
||||
}
|
||||
this.scaleOptions = layer.getScaleOptions();
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes();
|
||||
const dataArray = layer.getSource().data.dataArray;
|
||||
|
||||
if (Array.isArray(dataArray) && dataArray.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (attributes) {
|
||||
const attributesToRescale = attributes.filter(
|
||||
(attribute) => attribute.needRescale,
|
||||
);
|
||||
if (attributesToRescale.length) {
|
||||
this.caculateScalesForAttributes(attributesToRescale, dataArray);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
private isNumber(n: any) {
|
||||
return !isNaN(parseFloat(n)) && isFinite(n);
|
||||
|
|
|
@ -5,16 +5,5 @@ import 'reflect-metadata';
|
|||
@injectable()
|
||||
export default class LayerAnimateStylePlugin implements ILayerPlugin {
|
||||
public apply(layer: ILayer) {
|
||||
layer.hooks.beforeRender.tap('LayerAnimateStylePlugin', () => {
|
||||
// @ts-ignore
|
||||
const animateStatus = layer.animateStatus;
|
||||
if (animateStatus) {
|
||||
layer.models.forEach((model: IModel) => {
|
||||
model.addUniforms({
|
||||
...layer.layerModel.getAnimateUniforms(),
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,16 +106,6 @@ export function generateLightingUniforms(
|
|||
@injectable()
|
||||
export default class LightingPlugin implements ILayerPlugin {
|
||||
public apply(layer: ILayer) {
|
||||
layer.hooks.beforeRender.tap('LightingPlugin', () => {
|
||||
const { enableLighting } = layer.getLayerConfig();
|
||||
if (enableLighting) {
|
||||
layer.models.forEach((model) =>
|
||||
// @ts-ignore
|
||||
model.addUniforms({
|
||||
...generateLightingUniforms(),
|
||||
}),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,13 +57,5 @@ export default class MultiPassRendererPlugin implements ILayerPlugin {
|
|||
layer.multiPassRenderer.setRenderFlag(true);
|
||||
}
|
||||
});
|
||||
|
||||
layer.hooks.beforeRender.tap('MultiPassRendererPlugin', () => {
|
||||
if (this.enabled) {
|
||||
// 渲染前根据 viewport 调整 FBO size
|
||||
const { width, height } = rendererService.getViewportSize();
|
||||
layer.multiPassRenderer.resize(width, height);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,5 @@ import 'reflect-metadata';
|
|||
@injectable()
|
||||
export default class UpdateModelPlugin implements ILayerPlugin {
|
||||
public apply(layer: ILayer) {
|
||||
layer.hooks.beforeRender.tap('UpdateModelPlugin', () => {});
|
||||
layer.hooks.afterRender.tap('UpdateModelPlugin', () => {
|
||||
layer.layerModelNeedUpdate = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,42 +16,6 @@ export default class UpdateStyleAttributePlugin implements ILayerPlugin {
|
|||
layer.hooks.init.tapPromise('UpdateStyleAttributePlugin', () => {
|
||||
this.initStyleAttribute(layer, { styleAttributeService });
|
||||
});
|
||||
|
||||
layer.hooks.beforeRender.tap('UpdateStyleAttributePlugin', () => {
|
||||
if (layer.layerModelNeedUpdate) {
|
||||
return;
|
||||
}
|
||||
if (layer.inited) {
|
||||
this.updateStyleAttribute(layer, { styleAttributeService });
|
||||
}
|
||||
});
|
||||
}
|
||||
private updateStyleAttribute(
|
||||
layer: ILayer,
|
||||
{
|
||||
styleAttributeService,
|
||||
}: { styleAttributeService: IStyleAttributeService },
|
||||
) {
|
||||
const attributes = styleAttributeService.getLayerStyleAttributes() || [];
|
||||
const filter = styleAttributeService.getLayerStyleAttribute('filter');
|
||||
if (filter && filter.needRegenerateVertices) {
|
||||
layer.layerModelNeedUpdate = true;
|
||||
attributes.forEach((attr) => (attr.needRegenerateVertices = false));
|
||||
return;
|
||||
}
|
||||
attributes
|
||||
.filter((attribute) => attribute.needRegenerateVertices)
|
||||
.forEach((attribute) => {
|
||||
// 精确更新某个/某些 feature(s),需要传入 featureIdx d
|
||||
styleAttributeService.updateAttributeByFeatureRange(
|
||||
attribute.name,
|
||||
layer.getEncodedData(), // 获取经过 mapping 最新的数据
|
||||
attribute.featureRange.startIndex,
|
||||
attribute.featureRange.endIndex,
|
||||
layer,
|
||||
);
|
||||
attribute.needRegenerateVertices = false;
|
||||
});
|
||||
}
|
||||
|
||||
private initStyleAttribute(
|
||||
|
|
|
@ -0,0 +1,117 @@
|
|||
export const vert = `
|
||||
|
||||
|
||||
#define TILE_SIZE 512.0
|
||||
#define PI 3.1415926536
|
||||
#define WORLD_SCALE TILE_SIZE / (PI * 2.0)
|
||||
|
||||
#define COORDINATE_SYSTEM_P20 5.0 // amap
|
||||
#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset
|
||||
|
||||
attribute vec3 a_Position;
|
||||
attribute vec3 a_Extrude;
|
||||
|
||||
uniform mat4 u_ModelMatrix;
|
||||
|
||||
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
|
||||
uniform float u_Zoom;
|
||||
|
||||
uniform float u_ZoomScale;
|
||||
|
||||
uniform float u_CoordinateSystem;
|
||||
|
||||
uniform vec2 u_ViewportCenter;
|
||||
|
||||
uniform vec4 u_ViewportCenterProjection;
|
||||
|
||||
uniform vec3 u_PixelsPerDegree;
|
||||
|
||||
uniform vec3 u_PixelsPerDegree2;
|
||||
|
||||
uniform vec3 u_PixelsPerMeter;
|
||||
|
||||
vec2 project_mercator(vec2 lnglat) {
|
||||
float x = lnglat.x;
|
||||
return vec2(
|
||||
radians(x) + PI,
|
||||
PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5))
|
||||
);
|
||||
}
|
||||
|
||||
float project_scale(float meters) {
|
||||
return meters * u_PixelsPerMeter.z;
|
||||
}
|
||||
|
||||
|
||||
vec4 project_offset(vec4 offset) {
|
||||
float dy = offset.y;
|
||||
dy = clamp(dy, -1., 1.);
|
||||
vec3 pixels_per_unit = u_PixelsPerDegree + u_PixelsPerDegree2 * dy;
|
||||
return vec4(offset.xyz * pixels_per_unit, offset.w);
|
||||
}
|
||||
|
||||
|
||||
vec4 project_position(vec4 position) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
|
||||
return vec4(
|
||||
(project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.),
|
||||
project_scale(position.z),
|
||||
position.w
|
||||
);
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
vec2 project_pixel(vec2 pixel) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||
}
|
||||
return pixel * -1.;
|
||||
}
|
||||
|
||||
|
||||
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
|
||||
return viewProjectionMatrix * position + center;
|
||||
}
|
||||
|
||||
vec4 project_common_position_to_clipspace(vec4 position) {
|
||||
return project_common_position_to_clipspace(
|
||||
position,
|
||||
u_ViewProjectionMatrix,
|
||||
u_ViewportCenterProjection
|
||||
);
|
||||
}
|
||||
|
||||
vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjectionMatrix) {
|
||||
vec4 pos = u_InverseViewProjectionMatrix * (clipspacePos - u_ViewportCenterProjection);
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 offset = a_Extrude.xy * 10.0;
|
||||
|
||||
offset = project_pixel(offset);
|
||||
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
}
|
||||
`;
|
||||
|
||||
export const frag = `
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
`;
|
|
@ -8,29 +8,19 @@ import {
|
|||
IUniform,
|
||||
} from '@antv/l7-core';
|
||||
import regl from 'l7regl';
|
||||
import { cloneDeep, isPlainObject, isTypedArray } from 'lodash';
|
||||
import { isPlainObject, isTypedArray } from 'lodash';
|
||||
import {
|
||||
blendEquationMap,
|
||||
blendFuncMap,
|
||||
cullFaceMap,
|
||||
depthFuncMap,
|
||||
primitiveMap,
|
||||
stencilFuncMap,
|
||||
stencilOpMap,
|
||||
} from './constants';
|
||||
import ReglAttribute from './ReglAttribute';
|
||||
import ReglElements from './ReglElements';
|
||||
import ReglFramebuffer from './ReglFramebuffer';
|
||||
import ReglTexture2D from './ReglTexture2D';
|
||||
|
||||
/**
|
||||
* adaptor for regl.DrawCommand
|
||||
*/
|
||||
export default class ReglModel implements IModel {
|
||||
private reGl: regl.Regl;
|
||||
private destroyed: boolean = false;
|
||||
private drawCommand: regl.DrawCommand;
|
||||
private drawPickCommand: regl.DrawCommand;
|
||||
private drawParams: regl.DrawConfig;
|
||||
private options: IModelInitializationOptions;
|
||||
private uniforms: {
|
||||
|
@ -40,22 +30,16 @@ export default class ReglModel implements IModel {
|
|||
constructor(reGl: regl.Regl, options: IModelInitializationOptions) {
|
||||
this.reGl = reGl;
|
||||
const {
|
||||
pick = true,
|
||||
vs,
|
||||
fs,
|
||||
attributes,
|
||||
uniforms,
|
||||
primitive,
|
||||
count,
|
||||
elements,
|
||||
depth,
|
||||
blend,
|
||||
stencil,
|
||||
cull,
|
||||
instances,
|
||||
} = options;
|
||||
const reglUniforms: { [key: string]: IUniform } = {};
|
||||
this.options = options;
|
||||
|
||||
if (uniforms) {
|
||||
this.uniforms = this.extractUniforms(uniforms);
|
||||
Object.keys(uniforms).forEach((uniformName) => {
|
||||
|
@ -64,6 +48,7 @@ export default class ReglModel implements IModel {
|
|||
reglUniforms[uniformName] = reGl.prop(uniformName);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
const reglAttributes: { [key: string]: regl.Attribute } = {};
|
||||
Object.keys(attributes).forEach((name: string) => {
|
||||
|
@ -78,80 +63,9 @@ export default class ReglModel implements IModel {
|
|||
primitive:
|
||||
primitiveMap[primitive === undefined ? gl.TRIANGLES : primitive],
|
||||
};
|
||||
if (instances) {
|
||||
drawParams.instances = instances;
|
||||
}
|
||||
|
||||
// Tip:
|
||||
// elements 中可能包含 count,此时不应传入
|
||||
// count 和 elements 相比、count 优先
|
||||
if (count) {
|
||||
drawParams.count = count;
|
||||
} else if (elements) {
|
||||
drawParams.elements = (elements as ReglElements).get();
|
||||
}
|
||||
|
||||
this.initDepthDrawParams({ depth }, drawParams);
|
||||
this.initBlendDrawParams({ blend }, drawParams);
|
||||
this.initStencilDrawParams({ stencil }, drawParams);
|
||||
this.initCullDrawParams({ cull }, drawParams);
|
||||
|
||||
drawParams.elements = (elements as ReglElements).get();
|
||||
this.drawCommand = reGl(drawParams);
|
||||
|
||||
if (pick) {
|
||||
const pickDrawParams = cloneDeep(drawParams);
|
||||
|
||||
pickDrawParams.blend = {
|
||||
...pickDrawParams.blend,
|
||||
enable: false,
|
||||
};
|
||||
|
||||
this.drawPickCommand = reGl(pickDrawParams);
|
||||
}
|
||||
this.drawParams = drawParams;
|
||||
}
|
||||
|
||||
public updateAttributesAndElements(
|
||||
attributes: { [key: string]: IAttribute },
|
||||
elements: IElements,
|
||||
) {
|
||||
const reglAttributes: { [key: string]: regl.Attribute } = {};
|
||||
Object.keys(attributes).forEach((name: string) => {
|
||||
reglAttributes[name] = (attributes[name] as ReglAttribute).get();
|
||||
});
|
||||
this.drawParams.attributes = reglAttributes;
|
||||
this.drawParams.elements = (elements as ReglElements).get();
|
||||
|
||||
this.drawCommand = this.reGl(this.drawParams);
|
||||
if (this.options.pick) {
|
||||
const pickDrawParams = cloneDeep(this.drawParams);
|
||||
pickDrawParams.blend = {
|
||||
...pickDrawParams.blend,
|
||||
enable: false,
|
||||
};
|
||||
|
||||
this.drawPickCommand = this.reGl(pickDrawParams);
|
||||
}
|
||||
}
|
||||
|
||||
public updateAttributes(attributes: { [key: string]: IAttribute }) {
|
||||
const reglAttributes: { [key: string]: regl.Attribute } = {};
|
||||
Object.keys(attributes).forEach((name: string) => {
|
||||
reglAttributes[name] = (attributes[name] as ReglAttribute).get();
|
||||
});
|
||||
this.drawParams.attributes = reglAttributes;
|
||||
this.drawCommand = this.reGl(this.drawParams);
|
||||
|
||||
if (this.options.pick) {
|
||||
const pickDrawParams = cloneDeep(this.drawParams);
|
||||
|
||||
pickDrawParams.blend = {
|
||||
...pickDrawParams.blend,
|
||||
enable: false,
|
||||
};
|
||||
|
||||
this.drawPickCommand = this.reGl(pickDrawParams);
|
||||
}
|
||||
}
|
||||
|
||||
public addUniforms(uniforms: { [key: string]: IUniform }) {
|
||||
|
@ -161,178 +75,11 @@ export default class ReglModel implements IModel {
|
|||
};
|
||||
}
|
||||
|
||||
public draw(options: IModelDrawOptions, pick?: boolean) {
|
||||
// console.log('options', this.drawParams)
|
||||
if (
|
||||
this.drawParams.attributes &&
|
||||
Object.keys(this.drawParams.attributes).length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
const uniforms: {
|
||||
[key: string]: IUniform;
|
||||
} = {
|
||||
...this.uniforms,
|
||||
...this.extractUniforms(options.uniforms || {}),
|
||||
};
|
||||
const reglDrawProps: {
|
||||
[key: string]:
|
||||
| regl.Framebuffer
|
||||
| regl.Texture2D
|
||||
| number
|
||||
| number[]
|
||||
| boolean;
|
||||
} = {};
|
||||
Object.keys(uniforms).forEach((uniformName: string) => {
|
||||
const type = typeof uniforms[uniformName];
|
||||
if (
|
||||
type === 'boolean' ||
|
||||
type === 'number' ||
|
||||
Array.isArray(uniforms[uniformName]) ||
|
||||
// @ts-ignore
|
||||
uniforms[uniformName].BYTES_PER_ELEMENT
|
||||
) {
|
||||
reglDrawProps[uniformName] = uniforms[uniformName] as
|
||||
| number
|
||||
| number[]
|
||||
| boolean;
|
||||
} else {
|
||||
reglDrawProps[uniformName] = (
|
||||
uniforms[uniformName] as ReglFramebuffer | ReglTexture2D
|
||||
).get();
|
||||
}
|
||||
});
|
||||
// 在进行拾取操作的绘制中,不应该使用叠加模式 - picking 根据拾取的颜色作为判断的输入,而叠加模式会产生新的,在 id 序列中不存在的颜色
|
||||
if (!pick) {
|
||||
this.drawCommand(reglDrawProps);
|
||||
} else {
|
||||
if (this.drawPickCommand) {
|
||||
this.drawPickCommand(reglDrawProps);
|
||||
}
|
||||
}
|
||||
// this.drawCommand(reglDrawProps);
|
||||
// this.drawPickCommand(reglDrawProps);
|
||||
}
|
||||
public draw(options: IModelDrawOptions) {
|
||||
|
||||
public destroy() {
|
||||
// @ts-ignore
|
||||
this.drawParams?.elements?.destroy();
|
||||
if (this.options.attributes) {
|
||||
Object.values(this.options.attributes).forEach((attr: any) => {
|
||||
// @ts-ignore
|
||||
(attr as ReglAttribute)?.destroy();
|
||||
});
|
||||
}
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/regl-project/regl/blob/gh-pages/API.md#depth-buffer
|
||||
*/
|
||||
private initDepthDrawParams(
|
||||
{ depth }: Pick<IModelInitializationOptions, 'depth'>,
|
||||
drawParams: regl.DrawConfig,
|
||||
) {
|
||||
if (depth) {
|
||||
drawParams.depth = {
|
||||
enable: depth.enable === undefined ? true : !!depth.enable,
|
||||
mask: depth.mask === undefined ? true : !!depth.mask,
|
||||
func: depthFuncMap[depth.func || gl.LESS],
|
||||
range: depth.range || [0, 1],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/regl-project/regl/blob/gh-pages/API.md#blending
|
||||
*/
|
||||
private initBlendDrawParams(
|
||||
{ blend }: Pick<IModelInitializationOptions, 'blend'>,
|
||||
drawParams: regl.DrawConfig,
|
||||
) {
|
||||
if (blend) {
|
||||
const { enable, func, equation, color = [0, 0, 0, 0] } = blend;
|
||||
// @ts-ignore
|
||||
drawParams.blend = {
|
||||
enable: !!enable,
|
||||
func: {
|
||||
srcRGB: blendFuncMap[(func && func.srcRGB) || gl.SRC_ALPHA],
|
||||
srcAlpha: blendFuncMap[(func && func.srcAlpha) || gl.SRC_ALPHA],
|
||||
dstRGB: blendFuncMap[(func && func.dstRGB) || gl.ONE_MINUS_SRC_ALPHA],
|
||||
dstAlpha:
|
||||
blendFuncMap[(func && func.dstAlpha) || gl.ONE_MINUS_SRC_ALPHA],
|
||||
},
|
||||
equation: {
|
||||
rgb: blendEquationMap[(equation && equation.rgb) || gl.FUNC_ADD],
|
||||
alpha: blendEquationMap[(equation && equation.alpha) || gl.FUNC_ADD],
|
||||
},
|
||||
color,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/regl-project/regl/blob/gh-pages/API.md#stencil
|
||||
*/
|
||||
private initStencilDrawParams(
|
||||
{ stencil }: Pick<IModelInitializationOptions, 'stencil'>,
|
||||
drawParams: regl.DrawConfig,
|
||||
) {
|
||||
if (stencil) {
|
||||
const {
|
||||
enable,
|
||||
mask = -1,
|
||||
func = {
|
||||
cmp: gl.ALWAYS,
|
||||
ref: 0,
|
||||
mask: -1,
|
||||
},
|
||||
opFront = {
|
||||
fail: gl.KEEP,
|
||||
zfail: gl.KEEP,
|
||||
zpass: gl.KEEP,
|
||||
},
|
||||
opBack = {
|
||||
fail: gl.KEEP,
|
||||
zfail: gl.KEEP,
|
||||
zpass: gl.KEEP,
|
||||
},
|
||||
} = stencil;
|
||||
drawParams.stencil = {
|
||||
enable: !!enable,
|
||||
mask,
|
||||
func: {
|
||||
...func,
|
||||
cmp: stencilFuncMap[func.cmp],
|
||||
},
|
||||
opFront: {
|
||||
fail: stencilOpMap[opFront.fail],
|
||||
zfail: stencilOpMap[opFront.zfail],
|
||||
zpass: stencilOpMap[opFront.zpass],
|
||||
},
|
||||
opBack: {
|
||||
fail: stencilOpMap[opBack.fail],
|
||||
zfail: stencilOpMap[opBack.zfail],
|
||||
zpass: stencilOpMap[opBack.zpass],
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see https://github.com/regl-project/regl/blob/gh-pages/API.md#culling
|
||||
*/
|
||||
private initCullDrawParams(
|
||||
{ cull }: Pick<IModelInitializationOptions, 'cull'>,
|
||||
drawParams: regl.DrawConfig,
|
||||
) {
|
||||
if (cull) {
|
||||
const { enable, face = gl.BACK } = cull;
|
||||
drawParams.cull = {
|
||||
enable: !!enable,
|
||||
face: cullFaceMap[face],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
this.drawCommand(this.uniforms);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue