Skip to content

Allow lights to change without shader recompilation #16854

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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions packages/dev/core/src/Lights/areaLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,8 @@ export abstract class AreaLight extends Light {
/**
* Prepares the list of defines specific to the light type.
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["AREALIGHT" + lightIndex] = true;
public override prepareLightSpecificDefines(defines: any): void {
defines["AREALIGHTUSED"] = true;
}

Expand Down
22 changes: 2 additions & 20 deletions packages/dev/core/src/Lights/directionalLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,15 +280,6 @@ export class DirectionalLight extends ShadowLight {
);
}

protected _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightData", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);
this._uniformBuffer.addUniform("shadowsInfo", 3);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

/**
* Sets the passed Effect object with the DirectionalLight transformed position (or position if not parented) and the passed name.
* @param effect The effect to update
Expand All @@ -297,10 +288,10 @@ export class DirectionalLight extends ShadowLight {
*/
public transferToEffect(effect: Effect, lightIndex: string): DirectionalLight {
if (this.computeTransformedInformation()) {
this._uniformBuffer.updateFloat4("vLightData", this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z, 1, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", this.transformedDirection.x, this.transformedDirection.y, this.transformedDirection.z, 1, lightIndex);
return this;
}
this._uniformBuffer.updateFloat4("vLightData", this.direction.x, this.direction.y, this.direction.z, 1, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", this.direction.x, this.direction.y, this.direction.z, 1, lightIndex);
return this;
}

Expand Down Expand Up @@ -343,15 +334,6 @@ export class DirectionalLight extends ShadowLight {
const engine = this._scene.getEngine();
return engine.useReverseDepthBuffer && engine.isNDCHalfZRange ? 0 : 1;
}

/**
* Prepares the list of defines specific to the light type.
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["DIRLIGHT" + lightIndex] = true;
}
}

// Register Class Name
Expand Down
17 changes: 17 additions & 0 deletions packages/dev/core/src/Lights/disabledLight.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Light } from "./light";
import { LightConstants } from "./lightConstants";

export class DisabledLight extends Light {
// eslint-disable-next-line @typescript-eslint/naming-convention
public override getTypeID(): number {
return LightConstants.LIGHTTYPEID_DISABLED;
}

public transferToEffect(): Light {
return this;
}

public override transferToNodeMaterialEffect(): Light {
return this;
}
}
23 changes: 2 additions & 21 deletions packages/dev/core/src/Lights/hemisphericLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,6 @@ export class HemisphericLight extends Light {
this.direction = direction || Vector3.Up();
}

protected _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightData", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);
this._uniformBuffer.addUniform("vLightGround", 3);
this._uniformBuffer.addUniform("shadowsInfo", 3);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

/**
* Returns the string "HemisphericLight".
* @returns The class name
Expand Down Expand Up @@ -90,8 +80,8 @@ export class HemisphericLight extends Light {
*/
public transferToEffect(_effect: Effect, lightIndex: string): HemisphericLight {
const normalizeDirection = Vector3.Normalize(this.direction);
this._uniformBuffer.updateFloat4("vLightData", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0.0, lightIndex);
this._uniformBuffer.updateColor3("vLightGround", this.groundColor.scale(this.intensity), lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, 0.0, lightIndex);
this._uniformBuffer.updateColor4("vLightDataB", this.groundColor.scale(this.intensity), 1.0, lightIndex);
return this;
}

Expand Down Expand Up @@ -120,15 +110,6 @@ export class HemisphericLight extends Light {
public override getTypeID(): number {
return Light.LIGHTTYPEID_HEMISPHERICLIGHT;
}

/**
* Prepares the list of defines specific to the light type.
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["HEMILIGHT" + lightIndex] = true;
}
}

// Register Class Name
Expand Down
25 changes: 23 additions & 2 deletions packages/dev/core/src/Lights/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,26 @@ export abstract class Light extends Node implements ISortableLight {
this._resyncMeshes();
}

protected abstract _buildUniformLayout(): void;
private _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightType", 1);
this._uniformBuffer.addUniform("vLightPosition", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);

// | Type | Data A | Data B |
// | ----------- | --------- | ------- |
// | Point | - | Falloff |
// | Directional | Direction | - |
// | Spot | Direction | Falloff |
// | Hemispheric | Direction | Ground |
// | Area | Width | Height |
this._uniformBuffer.addUniform("vLightDataA", 4);
this._uniformBuffer.addUniform("vLightDataB", 4);

this._uniformBuffer.addUniform("shadowsInfo", 4);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

/**
* Sets the passed Effect "effect" with the Light information.
Expand Down Expand Up @@ -429,6 +448,8 @@ export abstract class Light extends Node implements ISortableLight {

this.transferToEffect(effect, iAsString);

this._uniformBuffer.updateFloat("vLightType", this.getTypeID(), iAsString);

this.diffuse.scaleToRef(scaledIntensity, TmpColors.Color3[0]);
this._uniformBuffer.updateColor4("vLightDiffuse", TmpColors.Color3[0], this.range, iAsString);
if (useSpecular) {
Expand Down Expand Up @@ -928,7 +949,7 @@ export abstract class Light extends Node implements ISortableLight {
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public abstract prepareLightSpecificDefines(defines: any, lightIndex: number): void;
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {}

/**
* @internal
Expand Down
1 change: 1 addition & 0 deletions packages/dev/core/src/Lights/lightConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export class LightConstants {
public static readonly INTENSITYMODE_LUMINANCE = 4;

// Light types ids const.
public static readonly LIGHTTYPEID_DISABLED = -1;
/**
* Light type const id of the point light.
*/
Expand Down
25 changes: 3 additions & 22 deletions packages/dev/core/src/Lights/pointLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,16 +171,6 @@ export class PointLight extends ShadowLight {
);
}

protected _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightData", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);
this._uniformBuffer.addUniform("vLightFalloff", 4);
this._uniformBuffer.addUniform("shadowsInfo", 3);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

/**
* Sets the passed Effect "effect" with the PointLight transformed position (or position, if none) and passed name (string).
* @param effect The effect to update
Expand All @@ -189,12 +179,12 @@ export class PointLight extends ShadowLight {
*/
public transferToEffect(effect: Effect, lightIndex: string): PointLight {
if (this.computeTransformedInformation()) {
this._uniformBuffer.updateFloat4("vLightData", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, 0.0, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, 0.0, lightIndex);
} else {
this._uniformBuffer.updateFloat4("vLightData", this.position.x, this.position.y, this.position.z, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this.position.x, this.position.y, this.position.z, 0, lightIndex);
}

this._uniformBuffer.updateFloat4("vLightFalloff", this.range, this._inverseSquaredRange, 0, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataB", this.range, this._inverseSquaredRange, 0, 0, lightIndex);
return this;
}

Expand All @@ -207,15 +197,6 @@ export class PointLight extends ShadowLight {

return this;
}

/**
* Prepares the list of defines specific to the light type.
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["POINTLIGHT" + lightIndex] = true;
}
}

// Register Class Name
Expand Down
23 changes: 6 additions & 17 deletions packages/dev/core/src/Lights/rectAreaLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,6 @@ export class RectAreaLight extends AreaLight {
return Light.LIGHTTYPEID_RECT_AREALIGHT;
}

protected _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightData", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);
this._uniformBuffer.addUniform("vLightWidth", 4);
this._uniformBuffer.addUniform("vLightHeight", 4);
this._uniformBuffer.addUniform("shadowsInfo", 3);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

protected _computeTransformedInformation(): boolean {
if (this.parent && this.parent.getWorldMatrix) {
Vector3.TransformCoordinatesToRef(this.position, this.parent.getWorldMatrix(), this._pointTransformedPosition);
Expand All @@ -115,20 +104,20 @@ export class RectAreaLight extends AreaLight {
*/
public transferToEffect(effect: Effect, lightIndex: string): RectAreaLight {
if (this._computeTransformedInformation()) {
this._uniformBuffer.updateFloat4("vLightData", this._pointTransformedPosition.x, this._pointTransformedPosition.y, this._pointTransformedPosition.z, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightWidth", this._pointTransformedWidth.x / 2, this._pointTransformedWidth.y / 2, this._pointTransformedWidth.z / 2, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this._pointTransformedPosition.x, this._pointTransformedPosition.y, this._pointTransformedPosition.z, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", this._pointTransformedWidth.x / 2, this._pointTransformedWidth.y / 2, this._pointTransformedWidth.z / 2, 0, lightIndex);
this._uniformBuffer.updateFloat4(
"vLightHeight",
"vLightDataB",
this._pointTransformedHeight.x / 2,
this._pointTransformedHeight.y / 2,
this._pointTransformedHeight.z / 2,
0,
lightIndex
);
} else {
this._uniformBuffer.updateFloat4("vLightData", this.position.x, this.position.y, this.position.z, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightWidth", this._width.x / 2, this._width.y / 2, this._width.z / 2, 0.0, lightIndex);
this._uniformBuffer.updateFloat4("vLightHeight", this._height.x / 2, this._height.y / 2, this._height.z / 2, 0.0, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this.position.x, this.position.y, this.position.z, 0, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", this._width.x / 2, this._width.y / 2, this._width.z / 2, 0.0, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataB", this._height.x / 2, this._height.y / 2, this._height.z / 2, 0.0, lightIndex);
}
return this;
}
Expand Down
22 changes: 5 additions & 17 deletions packages/dev/core/src/Lights/spotLight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -375,17 +375,6 @@ export class SpotLight extends ShadowLight {
this._projectionTextureMatrix.multiplyToRef(this._projectionTextureScalingMatrix, this._projectionTextureMatrix);
}

protected _buildUniformLayout(): void {
this._uniformBuffer.addUniform("vLightData", 4);
this._uniformBuffer.addUniform("vLightDiffuse", 4);
this._uniformBuffer.addUniform("vLightSpecular", 4);
this._uniformBuffer.addUniform("vLightDirection", 3);
this._uniformBuffer.addUniform("vLightFalloff", 4);
this._uniformBuffer.addUniform("shadowsInfo", 3);
this._uniformBuffer.addUniform("depthValues", 2);
this._uniformBuffer.create();
}

private _computeAngleValues(): void {
this._lightAngleScale = 1.0 / Math.max(0.001, Math.cos(this._innerAngle * 0.5) - this._cosHalfAngle);
this._lightAngleOffset = -this._cosHalfAngle * this._lightAngleScale;
Expand Down Expand Up @@ -428,18 +417,18 @@ export class SpotLight extends ShadowLight {
let normalizeDirection;

if (this.computeTransformedInformation()) {
this._uniformBuffer.updateFloat4("vLightData", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, this.exponent, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this.transformedPosition.x, this.transformedPosition.y, this.transformedPosition.z, this.exponent, lightIndex);

normalizeDirection = Vector3.Normalize(this.transformedDirection);
} else {
this._uniformBuffer.updateFloat4("vLightData", this.position.x, this.position.y, this.position.z, this.exponent, lightIndex);
this._uniformBuffer.updateFloat4("vLightPosition", this.position.x, this.position.y, this.position.z, this.exponent, lightIndex);

normalizeDirection = Vector3.Normalize(this.direction);
}

this._uniformBuffer.updateFloat4("vLightDirection", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, this._cosHalfAngle, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataA", normalizeDirection.x, normalizeDirection.y, normalizeDirection.z, this._cosHalfAngle, lightIndex);

this._uniformBuffer.updateFloat4("vLightFalloff", this.range, this._inverseSquaredRange, this._lightAngleScale, this._lightAngleOffset, lightIndex);
this._uniformBuffer.updateFloat4("vLightDataB", this.range, this._inverseSquaredRange, this._lightAngleScale, this._lightAngleOffset, lightIndex);
return this;
}

Expand Down Expand Up @@ -504,8 +493,7 @@ export class SpotLight extends ShadowLight {
* @param defines the list of defines
* @param lightIndex defines the index of the light for the effect
*/
public prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["SPOTLIGHT" + lightIndex] = true;
public override prepareLightSpecificDefines(defines: any, lightIndex: number): void {
defines["PROJECTEDLIGHTTEXTURE" + lightIndex] = this.projectionTexture && this.projectionTexture.isReady() ? true : false;
defines["IESLIGHTTEXTURE" + lightIndex] = this._iesProfileTexture && this._iesProfileTexture.isReady() ? true : false;
}
Expand Down
Loading
Loading