-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Spritesheet Block, Tint Block, and Fireworks updates (#52)
Co-authored-by: AmoebaChant <[email protected]>
- Loading branch information
1 parent
362dc35
commit 3d4f4ad
Showing
10 changed files
with
322 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
packages/demo/src/configuration/blocks/effects/spritesheetBlock.fragment.glsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
uniform sampler2D input; // main | ||
uniform float time; | ||
uniform float rows; | ||
uniform float cols; | ||
uniform float frames; | ||
|
||
vec4 mainImage(vec2 vUV) { // main | ||
float invRows = 1.0 / rows; | ||
float invCols = 1.0 / cols; | ||
|
||
// Get offset of frame | ||
float frame = mod(floor(time), frames); | ||
float row = (rows - 1.0) - floor(frame * invCols); // Reverse row direction b/c UVs start from bottom | ||
float col = mod(frame, cols); | ||
|
||
// Add offset, then scale UV down to frame size | ||
vUV = vec2( | ||
(vUV.x + col) * invCols, | ||
(vUV.y + row) * invRows | ||
); | ||
|
||
return texture2D(input, vUV); | ||
} |
123 changes: 123 additions & 0 deletions
123
packages/demo/src/configuration/blocks/effects/spritesheetBlock.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
import type { Effect } from "@babylonjs/core/Materials/effect"; | ||
import { type SmartFilter, type IDisableableBlock, type RuntimeData, createStrongRef } from "@babylonjs/smart-filters"; | ||
import { ShaderBlock, ConnectionPointType, ShaderBinding } from "@babylonjs/smart-filters"; | ||
import { BlockNames } from "../blockNames"; | ||
import { shaderProgram, uniforms } from "./spritesheetBlock.shader"; | ||
|
||
/** | ||
* The shader bindings for the Spritesheet block. | ||
*/ | ||
export class SpritesheetShaderBinding extends ShaderBinding { | ||
private readonly _inputTexture: RuntimeData<ConnectionPointType.Texture>; | ||
private readonly _time: RuntimeData<ConnectionPointType.Float>; | ||
private readonly _rows: RuntimeData<ConnectionPointType.Float>; | ||
private readonly _cols: RuntimeData<ConnectionPointType.Float>; | ||
private readonly _frames: RuntimeData<ConnectionPointType.Float>; | ||
|
||
/** | ||
* Creates a new shader binding instance for the SpriteSheet block. | ||
* @param parentBlock - The parent block | ||
* @param inputTexture - The input texture | ||
* @param time - The time passed since the start of the effect | ||
* @param rows - The number of rows in the sprite sheet | ||
* @param cols - The number of columns in the sprite sheet | ||
* @param frames - The number of frames to show | ||
*/ | ||
constructor( | ||
parentBlock: IDisableableBlock, | ||
inputTexture: RuntimeData<ConnectionPointType.Texture>, | ||
time: RuntimeData<ConnectionPointType.Float>, | ||
rows: RuntimeData<ConnectionPointType.Float>, | ||
cols: RuntimeData<ConnectionPointType.Float>, | ||
frames: RuntimeData<ConnectionPointType.Float> | ||
) { | ||
super(parentBlock); | ||
this._inputTexture = inputTexture; | ||
this._time = time; | ||
this._rows = rows; | ||
this._cols = cols; | ||
this._frames = frames; | ||
} | ||
|
||
/** | ||
* Binds all the required data to the shader when rendering. | ||
* @param effect - defines the effect to bind the data to | ||
*/ | ||
public override bind(effect: Effect): void { | ||
super.bind(effect); | ||
effect.setTexture(this.getRemappedName(uniforms.input), this._inputTexture.value); | ||
effect.setFloat(this.getRemappedName(uniforms.time), this._time.value); | ||
effect.setFloat(this.getRemappedName(uniforms.rows), this._rows.value); | ||
effect.setFloat(this.getRemappedName(uniforms.cols), this._cols.value); | ||
|
||
// Apply default value for frame count if it was not provided | ||
effect.setFloat( | ||
this.getRemappedName(uniforms.frames), | ||
this._frames.value > 0 ? this._frames.value : this._rows.value * this._cols.value | ||
); | ||
} | ||
} | ||
|
||
/** | ||
* A block that animates a sprite sheet texture. | ||
*/ | ||
export class SpritesheetBlock extends ShaderBlock { | ||
/** | ||
* The class name of the block. | ||
*/ | ||
public static override ClassName = BlockNames.spritesheet; | ||
|
||
/** | ||
* The input texture connection point | ||
*/ | ||
public readonly input = this._registerInput("input", ConnectionPointType.Texture); | ||
|
||
/** | ||
* The time connection point to animate the effect. | ||
*/ | ||
public readonly time = this._registerOptionalInput("time", ConnectionPointType.Float, createStrongRef(0.0)); | ||
|
||
/** | ||
* The number of rows in the sprite sheet, as a connection point. | ||
*/ | ||
public readonly rows = this._registerOptionalInput("rows", ConnectionPointType.Float, createStrongRef(1.0)); | ||
|
||
/** | ||
* The number of columns in the sprite sheet, as a connection point. | ||
*/ | ||
public readonly columns = this._registerOptionalInput("columns", ConnectionPointType.Float, createStrongRef(1.0)); | ||
|
||
/** | ||
* The number of frames to animate from the beginning, as a connection point. | ||
* Defaults to rows * columns at runtime. | ||
*/ | ||
public readonly frames = this._registerOptionalInput("frames", ConnectionPointType.Float, createStrongRef(0.0)); | ||
|
||
/** | ||
* The shader program (vertex and fragment code) to use to render the block | ||
*/ | ||
public static override ShaderCode = shaderProgram; | ||
|
||
/** | ||
* Instantiates a new Block. | ||
* @param smartFilter - The smart filter this block belongs to | ||
* @param name - The friendly name of the block | ||
*/ | ||
constructor(smartFilter: SmartFilter, name: string) { | ||
super(smartFilter, name); | ||
} | ||
|
||
/** | ||
* Get the class instance that binds all the required data to the shader (effect) when rendering. | ||
* @returns The class instance that binds the data to the effect | ||
*/ | ||
public getShaderBinding(): ShaderBinding { | ||
const input = this._confirmRuntimeDataSupplied(this.input); | ||
const rows = this.rows.runtimeData; | ||
const columns = this.columns.runtimeData; | ||
const time = this.time.runtimeData; | ||
const frames = this.frames.runtimeData; | ||
|
||
return new SpritesheetShaderBinding(this, input, time, rows, columns, frames); | ||
} | ||
} |
9 changes: 9 additions & 0 deletions
9
packages/demo/src/configuration/blocks/effects/tintBlock.fragment.glsl
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
uniform sampler2D input; // main | ||
uniform vec3 tint; | ||
uniform float amount; | ||
|
||
vec4 mainImage(vec2 vUV) { // main | ||
vec4 color = texture2D(input, vUV); | ||
vec3 tinted = mix(color.rgb, tint, amount); | ||
return vec4(tinted, color.a); | ||
} |
100 changes: 100 additions & 0 deletions
100
packages/demo/src/configuration/blocks/effects/tintBlock.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import type { Effect } from "@babylonjs/core/Materials/effect"; | ||
import type { SmartFilter, IDisableableBlock, RuntimeData } from "@babylonjs/smart-filters"; | ||
import { ShaderBlock, ConnectionPointType, ShaderBinding, createStrongRef } from "@babylonjs/smart-filters"; | ||
import { BlockNames } from "../blockNames"; | ||
import { uniforms, shaderProgram } from "./tintBlock.shader"; | ||
import { Color3 } from "@babylonjs/core/Maths/math.color"; | ||
|
||
/** | ||
* The shader bindings for the Tint block. | ||
*/ | ||
export class TintShaderBinding extends ShaderBinding { | ||
private readonly _inputTexture: RuntimeData<ConnectionPointType.Texture>; | ||
private readonly _tint: RuntimeData<ConnectionPointType.Color3>; | ||
private readonly _amount: RuntimeData<ConnectionPointType.Float>; | ||
|
||
/** | ||
* Creates a new shader binding instance for the Tint block. | ||
* @param parentBlock - The parent block | ||
* @param inputTexture - the input texture | ||
* @param tint - the tint to apply | ||
* @param amount - the amount of tint to apply | ||
*/ | ||
constructor( | ||
parentBlock: IDisableableBlock, | ||
inputTexture: RuntimeData<ConnectionPointType.Texture>, | ||
tint: RuntimeData<ConnectionPointType.Color3>, | ||
amount: RuntimeData<ConnectionPointType.Float> | ||
) { | ||
super(parentBlock); | ||
this._inputTexture = inputTexture; | ||
this._tint = tint; | ||
this._amount = amount; | ||
} | ||
|
||
/** | ||
* Binds all the required data to the shader when rendering. | ||
* @param effect - defines the effect to bind the data to | ||
*/ | ||
public override bind(effect: Effect): void { | ||
super.bind(effect); | ||
effect.setTexture(this.getRemappedName(uniforms.input), this._inputTexture.value); | ||
effect.setColor3(this.getRemappedName(uniforms.tint), this._tint.value); | ||
effect.setFloat(this.getRemappedName(uniforms.amount), this._amount.value); | ||
} | ||
} | ||
|
||
/** | ||
* A simple block to apply a tint to a texture | ||
*/ | ||
export class TintBlock extends ShaderBlock { | ||
/** | ||
* The class name of the block. | ||
*/ | ||
public static override ClassName = BlockNames.tint; | ||
|
||
/** | ||
* The input texture connection point. | ||
*/ | ||
public readonly input = this._registerInput("input", ConnectionPointType.Texture); | ||
|
||
/** | ||
* The tint color connection point. | ||
*/ | ||
public readonly tint = this._registerOptionalInput( | ||
"tint", | ||
ConnectionPointType.Color3, | ||
createStrongRef(new Color3(1, 0, 0)) | ||
); | ||
|
||
/** | ||
* The strength of the tint, as a connection point. | ||
*/ | ||
public readonly amount = this._registerOptionalInput("amount", ConnectionPointType.Float, createStrongRef(0.25)); | ||
|
||
/** | ||
* The shader program (vertex and fragment code) to use to render the block | ||
*/ | ||
public static override ShaderCode = shaderProgram; | ||
|
||
/** | ||
* Instantiates a new Block. | ||
* @param smartFilter - The smart filter this block belongs to | ||
* @param name - The friendly name of the block | ||
*/ | ||
constructor(smartFilter: SmartFilter, name: string) { | ||
super(smartFilter, name); | ||
} | ||
|
||
/** | ||
* Get the class instance that binds all the required data to the shader (effect) when rendering. | ||
* @returns The class instance that binds the data to the effect | ||
*/ | ||
public getShaderBinding(): ShaderBinding { | ||
const input = this._confirmRuntimeDataSupplied(this.input); | ||
const tint = this.tint.runtimeData; | ||
const amount = this.amount.runtimeData; | ||
|
||
return new TintShaderBinding(this, input, tint, amount); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.