Skip to content

Commit

Permalink
feat(geo-layers): Private MeshLayer with pbr material support (I3S) (v…
Browse files Browse the repository at this point in the history
…isgl#5761)

Co-authored-by: Victor Belomestnov <belom88@yandex.ru>
  • Loading branch information
ibgreen and belom88 authored May 26, 2021
1 parent 26635d3 commit 0a5dc22
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 9 deletions.
1 change: 1 addition & 0 deletions modules/geo-layers/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"@loaders.gl/mvt": "^3.0.0-alpha.16",
"@loaders.gl/terrain": "^3.0.0-alpha.16",
"@loaders.gl/tiles": "^3.0.0-alpha.16",
"@luma.gl/experimental": "^8.5.0-alpha.1",
"@math.gl/culling": "^3.4.2",
"@math.gl/web-mercator": "^3.4.2",
"h3-js": "^3.6.0",
Expand Down
55 changes: 55 additions & 0 deletions modules/geo-layers/src/mesh-layer/mesh-layer-fragment.glsl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
export default `#version 300 es
#define SHADER_NAME simple-mesh-layer-fs
precision highp float;
uniform bool hasTexture;
uniform sampler2D sampler;
uniform bool flatShading;
uniform float opacity;
in vec2 vTexCoord;
in vec3 cameraPosition;
in vec3 normals_commonspace;
in vec4 position_commonspace;
in vec4 vColor;
out vec4 fragColor;
void main(void) {
#ifdef MODULE_PBR
fragColor = vColor * pbr_filterColor(vec4(0));
geometry.uv = pbr_vUV;
fragColor.a *= opacity;
#else
geometry.uv = vTexCoord;
vec3 normal;
if (flatShading) {
// NOTE(Tarek): This is necessary because
// headless.gl reports the extension as
// available but does not support it in
// the shader.
#ifdef DERIVATIVES_AVAILABLE
normal = normalize(cross(dFdx(position_commonspace.xyz), dFdy(position_commonspace.xyz)));
#else
normal = vec3(0.0, 0.0, 1.0);
#endif
} else {
normal = normals_commonspace;
}
vec4 color = hasTexture ? texture(sampler, vTexCoord) : vColor;
vec3 lightColor = lighting_getLightColor(color.rgb, cameraPosition, position_commonspace.xyz, normal);
fragColor = vec4(lightColor, color.a * opacity);
#endif
DECKGL_FILTER_COLOR(fragColor, geometry);
}
`;
67 changes: 67 additions & 0 deletions modules/geo-layers/src/mesh-layer/mesh-layer-vertex.glsl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
export default `#version 300 es
#define SHADER_NAME simple-mesh-layer-vs
// Scale the model
uniform float sizeScale;
uniform bool composeModelMatrix;
// Primitive attributes
in vec3 positions;
in vec3 normals;
in vec3 colors;
in vec2 texCoords;
// Instance attributes
in vec4 instanceColors;
in vec3 instancePickingColors;
in mat3 instanceModelMatrix;
// Outputs to fragment shader
out vec2 vTexCoord;
out vec3 cameraPosition;
out vec3 normals_commonspace;
out vec4 position_commonspace;
out vec4 vColor;
void main(void) {
geometry.uv = texCoords;
geometry.pickingColor = instancePickingColors;
#ifdef MODULE_PBR
// set PBR data
#ifdef HAS_NORMALS
pbr_vNormal = project_normal(instanceModelMatrix * normals);
geometry.normal = pbr_vNormal;
#endif
#ifdef HAS_UV
pbr_vUV = texCoords;
#else
pbr_vUV = vec2(0., 0.);
#endif
geometry.uv = pbr_vUV;
#endif
vTexCoord = texCoords;
cameraPosition = project_uCameraPosition;
normals_commonspace = project_normal(instanceModelMatrix * normals);
vColor = vec4(colors * instanceColors.rgb, instanceColors.a);
geometry.normal = normals_commonspace;
vec3 pos = (instanceModelMatrix * positions) * sizeScale;
vec3 projectedPosition = project_position(positions);
position_commonspace = vec4(projectedPosition, 1.0);
gl_Position = project_common_position_to_clipspace(position_commonspace);
geometry.position = position_commonspace;
#ifdef MODULE_PBR
// set PBR data
pbr_vPosition = geometry.position.xyz;
#endif
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
DECKGL_FILTER_COLOR(vColor, geometry);
}
`;
89 changes: 89 additions & 0 deletions modules/geo-layers/src/mesh-layer/mesh-layer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {GLTFMaterialParser} from '@luma.gl/experimental';
import {Model, pbr} from '@luma.gl/core';
import {SimpleMeshLayer} from '@deck.gl/mesh-layers';

import vs from './mesh-layer-vertex.glsl';
import fs from './mesh-layer-fragment.glsl';

function validateGeometryAttributes(attributes) {
const hasColorAttribute = attributes.COLOR_0 || attributes.colors;
if (!hasColorAttribute) {
attributes.colors = {constant: true, value: new Float32Array([1, 1, 1])};
}
}

const defaultProps = {
// PBR material object. _lighting must be pbr for this to work
pbrMaterial: {type: 'object', value: null}
};

export default class _MeshLayer extends SimpleMeshLayer {
getShaders() {
const shaders = super.getShaders();
const modules = shaders.modules;
modules.push(pbr);
return {...shaders, vs, fs};
}

updateState({props, oldProps, changeFlags}) {
super.updateState({props, oldProps, changeFlags});
if (props.pbrMaterial !== oldProps.pbrMaterial) {
this.updatePbrMaterialUniforms(props.pbrMaterial);
}
}

draw(opts) {
if (!this.state.model) {
return;
}
this.state.model.setUniforms({
// Needed for PBR (TODO: find better way to get it)
u_Camera: this.state.model.getUniforms().project_uCameraPosition
});
super.draw(opts);
}

getModel(mesh) {
const pbrMaterial = this.props.pbrMaterial;
const materialParser = this.parseMaterial(pbrMaterial, mesh);
const shaders = this.getShaders();
validateGeometryAttributes(mesh.attributes);
const model = new Model(this.context.gl, {
...this.getShaders(),
id: this.props.id,
geometry: mesh,
defines: {...shaders.defines, ...materialParser?.defines},
parameters: materialParser?.parameters,
isInstanced: true
});

return model;
}

updatePbrMaterialUniforms(pbrMaterial) {
const {model} = this.state;
if (model) {
const {mesh} = this.props;
const materialParser = this.parseMaterial(pbrMaterial, mesh);
model.setUniforms(materialParser.uniforms);
}
}

parseMaterial(pbrMaterial, mesh) {
const unlit = Boolean(
pbrMaterial.pbrMetallicRoughness && pbrMaterial.pbrMetallicRoughness.baseColorTexture
);
const materialParser = new GLTFMaterialParser(this.context.gl, {
attributes: {NORMAL: mesh.attributes.normals, TEXCOORD_0: mesh.attributes.texCoords},
material: {unlit, ...pbrMaterial},
pbrDebug: false,
imageBasedLightingEnvironment: null,
lights: true,
useTangents: false
});
return materialParser;
}
}

_MeshLayer.layerName = '_MeshLayer';
_MeshLayer.defaultProps = defaultProps;
10 changes: 5 additions & 5 deletions modules/geo-layers/src/tile-3d-layer/tile-3d-layer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import GL from '@luma.gl/constants';
import {Geometry} from '@luma.gl/core';
import {COORDINATE_SYSTEM, CompositeLayer} from '@deck.gl/core';
import {PointCloudLayer} from '@deck.gl/layers';
import {ScenegraphLayer, SimpleMeshLayer} from '@deck.gl/mesh-layers';
import {ScenegraphLayer} from '@deck.gl/mesh-layers';
import {default as _MeshLayer} from '../mesh-layer/mesh-layer';
import {log} from '@deck.gl/core';

import {load} from '@loaders.gl/core';
Expand Down Expand Up @@ -228,7 +229,7 @@ export default class Tile3DLayer extends CompositeLayer {

_makeSimpleMeshLayer(tileHeader, oldLayer) {
const content = tileHeader.content;
const {attributes, indices, modelMatrix, cartographicOrigin, texture} = content;
const {attributes, indices, modelMatrix, cartographicOrigin, material} = content;
const {getSimpleMeshLayerColor} = this.props;

const geometry =
Expand All @@ -239,7 +240,7 @@ export default class Tile3DLayer extends CompositeLayer {
indices
});

const SubLayerClass = this.getSubLayerClass('mesh', SimpleMeshLayer);
const SubLayerClass = this.getSubLayerClass('mesh', _MeshLayer);

return new SubLayerClass(
this.getSubLayerProps({
Expand All @@ -249,9 +250,8 @@ export default class Tile3DLayer extends CompositeLayer {
id: `${this.id}-mesh-${tileHeader.id}`,
mesh: geometry,
data: SINGLE_DATA,
getPosition: [0, 0, 0],
getColor: getSimpleMeshLayerColor(tileHeader),
texture,
pbrMaterial: material,
modelMatrix,
coordinateOrigin: cartographicOrigin,
coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
Expand Down
13 changes: 9 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,11 @@
resolved "https://registry.yarnpkg.com/@luma.gl/constants/-/constants-8.5.0-alpha.1.tgz#6e237a48f6de670b99d1f064e80c91e3b80c9382"
integrity sha512-2NWGtLhmzCbe7wX4l9S7BO7cQc7gu2xQsOrkJ58axUkHh7C514iTelQXlrdBNGnCR47bAmMWnG5rEhemDwRxdQ==

"@luma.gl/constants@8.5.0-alpha.2":
version "8.5.0-alpha.2"
resolved "https://registry.yarnpkg.com/@luma.gl/constants/-/constants-8.5.0-alpha.2.tgz#4adb909f7e89e1acd82bfae4397bdc542f0dd5d1"
integrity sha512-ehcsIa7lpO66IqRBIKeeiiukNZTVzMTJQ9m6mxtxy/HJAlA3+8bIeMjJs40Y6aWn8fmbxFO6aOYGAi+VFwljWg==

"@luma.gl/constants@^8.4.0":
version "8.4.0"
resolved "https://registry.yarnpkg.com/@luma.gl/constants/-/constants-8.4.0.tgz#07584e76fbb184f8b26d323b8d52e3a6c8815ce8"
Expand Down Expand Up @@ -2151,11 +2156,11 @@
probe.gl "^3.2.1"

"@luma.gl/experimental@^8.5.0-alpha.1":
version "8.5.0-alpha.1"
resolved "https://registry.yarnpkg.com/@luma.gl/experimental/-/experimental-8.5.0-alpha.1.tgz#f33a75a7b4ea0ad30a9569e0b4ab10997c50e909"
integrity sha512-kY7LMx1w08tpbdXbRm9aCPDmmkfLT7WyIV8f0p6Wfb9d/eE0qtUfzx275SUBh07PdfDIetfQBvdNPxO6fcUszA==
version "8.5.0-alpha.2"
resolved "https://registry.yarnpkg.com/@luma.gl/experimental/-/experimental-8.5.0-alpha.2.tgz#729f0a19a777268379663c67f1694bf4caf3b77d"
integrity sha512-eHp9VetIcU+Oj+/QxZWfr6CUjWGvBFgLpzqyQLk7nqqU5K/loLr+RPUJeZgn878jMao0WeP54j8QxrpQ6K6MYw==
dependencies:
"@luma.gl/constants" "8.5.0-alpha.1"
"@luma.gl/constants" "8.5.0-alpha.2"
"@math.gl/core" "^3.4.1"
earcut "^2.0.6"

Expand Down

0 comments on commit 0a5dc22

Please sign in to comment.