Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generic module props handling in Layer class #9192

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

Pessimistress
Copy link
Collaborator

@Pessimistress Pessimistress commented Sep 28, 2024

For #9056

Change List

  • Remove hard-coded mapping of module props in Layer.draw
  • LayersPass merges nested module settings
  • Effects/passes getModuleParameters methods return namespaced settings
    • LayersPass
    • PickLayersPass
    • TerrainEffect/TerrainPass
    • CollisionFilterEffect/CollisionFilterPass
    • MaskEffect
    • LightingEffect/ShadowPass

@@ -72,7 +72,7 @@ const inject = {
collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0);
if (collision_fade < 0.0001) {
// Position outside clip space bounds to discard
position = vec4(0.0, 0.0, 2.0, 1.0);
// position = vec4(0.0, 0.0, 2.0, 1.0);
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@felixpalmer Please give this a check - I can't get it to work with this line enabled

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must not run when drawing to the collision map, where we never want to hide the features: 458b1f8

modules/extensions/src/mask/shader-module.ts Show resolved Hide resolved
shadow_uShadowMap0: opts.dummyShadowMap,
shadow_uShadowMap1: opts.dummyShadowMap
shadow_uShadowMap0: opts.dummyShadowMap!,
shadow_uShadowMap1: opts.dummyShadowMap!
};
}
const projectUniforms = project.getUniforms(opts) as ProjectUniforms;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibgreen In v8 getUniforms can access uniforms created by this shader module's dependencies (project in this case). As of the latest master, several shader modules are calling project.getUniforms themselves, which technically is incorrect, because they do not receive the full set of project module props (modelMatrix, coordinateOrigin, etc.). Is this by design, or is it a regression?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I wasn't really aware of this usage, so I suppose it was at most semi-intentional, the goal was simply to have a clean, simple-to-understand API.
  • If it is a crucial feature we can consider adding it back, but I fear that making types of dependency modules flow into a dependent module could require more typescript machinery than it is worth.
  • Perhaps we can look at the cases where it is used and see what are options are.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related: visgl/luma.gl#2138

My view is that it is too much magic to have the dependent module uniforms be available, and not as flexible. I started adding the project.getUniforms pattern as it feels more clear what is going on and all the uniform generation logic is then happening in one place and at the same time. I don't think it is a problem to pass the project module props where needed

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, I am not opposed to adding back the previous behavior, but it would be nice to find another way to handle this. My concernsL

  • To me, giving the shader modules access to other uniforms felt like opaque and non-obvious behavior.
  • It was compounded by this not being the props that are forwarded, but the calculated uniforms with seems more internal.
  • This mainly seems to be a use case for the projection module, so a fairly heavy solution for a limited problem.

Generally, projection is a pretty complex topic and a very central concern.

  • One can easily end up with lots of derived uniforms that may need to be calculated for various shaders, inverse matrices, inverse uniform matrices etc etc.
  • Calculating new uniforms from a set of primary JS values rather than a set of derived uniforms makes a lot of sense to me.
  • A solution may be having a central ProjectionState type class that generates values that can be used as properties for dependent shader modules.
  • That ProjectionState class could technically be exported by the shader module (shadertools), but would perhaps best be located in the luma.gl engine module.
  • I have already have such helper classes in engine module for the new "advanced" picking module and of course the ShaderPasses.

@coveralls
Copy link

coveralls commented Sep 28, 2024

Coverage Status

coverage: 91.639%. remained the same
when pulling 479f1c7 on x/module-props
into 2e9d6dc on master.

Copy link
Collaborator

@ibgreen ibgreen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid consolidation!

  • Could be nice to follow up with a renaming of the moduleSettings and moduleParameters (perhaps we can offer backwards compatibility)?
  • Maybe align on moduleProps or shaderModuleProps?

@@ -13,7 +13,7 @@ import shadow from '../../shaderlib/shadow/shadow';

import type Layer from '../../lib/layer';
import type {Effect, EffectContext, PreRenderOptions} from '../../lib/effect';
import {LightingProps} from '@luma.gl/shadertools';
import type Viewport from '../../viewports/viewport';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I have remove all default exports inside other frameworks... just a suggestion to try to avoid them in new deck code.

modules/core/src/effects/lighting/lighting-effect.ts Outdated Show resolved Hide resolved
modules/core/src/lib/layer.ts Outdated Show resolved Hide resolved
modules/core/src/passes/layers-pass.ts Outdated Show resolved Hide resolved
modules/core/src/passes/layers-pass.ts Show resolved Hide resolved

if (effects) {
for (const effect of effects) {
Object.assign(moduleParameters, effect.getModuleParameters?.(layer));
mergeModuleParameters(moduleParameters, effect.getModuleParameters?.(layer));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we offer this function in luma.gl? loaders.gl has a similar two-level mergeOptions export.

shadow_uShadowMap0: opts.dummyShadowMap,
shadow_uShadowMap1: opts.dummyShadowMap
shadow_uShadowMap0: opts.dummyShadowMap!,
shadow_uShadowMap1: opts.dummyShadowMap!
};
}
const projectUniforms = project.getUniforms(opts) as ProjectUniforms;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • I wasn't really aware of this usage, so I suppose it was at most semi-intentional, the goal was simply to have a clean, simple-to-understand API.
  • If it is a crucial feature we can consider adding it back, but I fear that making types of dependency modules flow into a dependent module could require more typescript machinery than it is worth.
  • Perhaps we can look at the cases where it is used and see what are options are.

modules/extensions/src/mask/shader-module.ts Show resolved Hide resolved
@@ -72,7 +72,7 @@ const inject = {
collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0);
if (collision_fade < 0.0001) {
// Position outside clip space bounds to discard
position = vec4(0.0, 0.0, 2.0, 1.0);
// position = vec4(0.0, 0.0, 2.0, 1.0);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This must not run when drawing to the collision map, where we never want to hide the features: 458b1f8

if (opts.moduleParameters.viewport) {
opts.moduleParameters.viewport = this.state.aggregatorViewport;
if (opts.shaderModuleProps.project) {
opts.shaderModuleProps.project.viewport = this.state.aggregatorViewport;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to clone the project object to avoid mutating it in the calling code?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The project object is soft referenced by other dependent modules (shadow, terrain, etc.)

@Pessimistress Pessimistress marked this pull request as ready for review September 30, 2024 17:08
@Pessimistress
Copy link
Collaborator Author

I've pushed an alternative solution - instead of passing contextual uniforms to getUniforms, I'm sending contextual module props in Effect.getShaderModuleProps / Pass.getShaderModuleProps:

getShaderModuleProps(layer: Layer, effects: any, otherShaderModuleProps: Record<string, any>) {
return {
shadow: {
project: otherShaderModuleProps.project,
drawToShadowMap: true
}
};
}

@ibgreen
Copy link
Collaborator

ibgreen commented Sep 30, 2024

I've pushed an alternative solution - instead of passing contextual uniforms to getUniforms, I'm sending contextual module props in Effect.getShaderModuleProps / Pass.getShaderModuleProps:

Interesting... If I understand correctly, this sends the project module props instead of the calculated project module uniforms? So potentially a bit more work for the extension modules' `getUniforms()...? Or perhaps not?

If it works well then that seems like a reasonable way to handle this for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants