Skip to content

Commit

Permalink
feat(graphics): add color filters for textured components
Browse files Browse the repository at this point in the history
  • Loading branch information
tomaisthorpe committed Sep 16, 2024
1 parent fb01f13 commit 8689535
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 7 deletions.
5 changes: 5 additions & 0 deletions .changeset/clever-apes-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tedengine/ted': minor
---

Add color filters for textured components
58 changes: 57 additions & 1 deletion apps/docs/src/examples/2d/sprite-component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import asteroidTexture from '@assets/asteroid.png';
import { vec3 } from 'gl-matrix';
import { vec3, vec4 } from 'gl-matrix';
import type { TResourcePackConfig } from '@tedengine/ted';
import {
TGameState,
Expand All @@ -20,6 +20,61 @@ class Sprite extends TActor {

const box = new TSpriteComponent(engine, this, 1, 1, TOriginPoint.Center);
box.applyTexture(engine, asteroidTexture);
box.colorFilter = vec4.fromValues(1, 1, 1, 1);

const section = engine.debugPanel.addSection('Color Filter', true);
section.addInput(
'Red',
'range',
'1',
(value) => {
box.colorFilter[0] = parseFloat(value);
},
{
min: 0,
max: 1,
step: 0.01,
},
);
section.addInput(
'Green',
'range',
'1',
(value) => {
box.colorFilter[1] = parseFloat(value);
},
{
min: 0,
max: 1,
step: 0.01,
},
);
section.addInput(
'Blue',
'range',
'1',
(value) => {
box.colorFilter[2] = parseFloat(value);
},
{
min: 0,
max: 1,
step: 0.01,
},
);
section.addInput(
'Alpha',
'range',
'1',
(value) => {
box.colorFilter[3] = parseFloat(value);
},
{
min: 0,
max: 1,
step: 0.01,
},
);

this.rootComponent.transform.translation = vec3.fromValues(0, 0, -3);
}
Expand All @@ -45,6 +100,7 @@ const config = {
game: SpriteState,
},
defaultState: 'game',
debugPanelOpen: true,
};

new TEngine(config, self as DedicatedWorkerGlobalScope);
1 change: 1 addition & 0 deletions packages/ted/src/actor-components/sprite-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default class TSpriteComponent extends TTexturedMeshComponent {
type: 'textured',
options: {
texture: this.texture.uuid!,
colorFilter: this.colorFilter,
},
},
layer: this.layer,
Expand Down
4 changes: 4 additions & 0 deletions packages/ted/src/actor-components/textured-mesh-component.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { vec4 } from 'gl-matrix';
import type TActor from '../core/actor';
import type TEngine from '../engine/engine';
import TTexture from '../graphics/texture';
Expand All @@ -14,6 +15,8 @@ export default class TTexturedMeshComponent extends TSceneComponent {
protected mesh: TTexturedMesh = new TTexturedMesh();
public texture: TTexture = new TTexture();

public colorFilter?: vec4;

constructor(actor: TActor, bodyOptions?: TPhysicsBodyOptions) {
super(actor, bodyOptions);

Expand All @@ -38,6 +41,7 @@ export default class TTexturedMeshComponent extends TSceneComponent {
type: 'textured',
options: {
texture: this.texture.uuid!,
colorFilter: this.colorFilter,
},
},
};
Expand Down
3 changes: 2 additions & 1 deletion packages/ted/src/renderer/frame-params.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// TFrameParams is used to tell the rendered how to render a frame.
import type { mat4 } from 'gl-matrix';
import type { mat4, vec4 } from 'gl-matrix';
import type { TSpriteLayer } from '../actor-components/sprite-component';
import type { TCameraView } from '../cameras/camera-view';
import type { TPalette } from '../graphics/color-material';
Expand Down Expand Up @@ -65,5 +65,6 @@ export interface TSerializedTexturedMaterial {
options: {
texture: string;
instanceUVs?: number[];
colorFilter?: vec4;
};
}
12 changes: 11 additions & 1 deletion packages/ted/src/renderer/renderable-textured-mesh.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { mat4 } from 'gl-matrix';
import { vec4 } from 'gl-matrix';
import { v4 as uuidv4 } from 'uuid';
import type TProgram from './program';
import type TRenderableTexture from './renderable-texture';
Expand All @@ -22,6 +23,8 @@ export default class TRenderableTexturedMesh {
// Instance buffers, used to override the UVs of the mesh
private instanceUVBuffer?: WebGLBuffer;

private colorFilterUniformLocation?: WebGLUniformLocation;

private vao?: WebGLVertexArrayObject;

public render(
Expand All @@ -30,19 +33,24 @@ export default class TRenderableTexturedMesh {
texture: TRenderableTexture,
m: mat4,
instanceUVs?: number[],
colorFilter: vec4 = vec4.fromValues(1, 1, 1, 1),
) {
if (this.positionBuffer === undefined) {
this.createBuffers(gl);

// Create the VAO for the vertex and color buffers
this.createVAO(gl, texturedProgram.program!);

this.colorFilterUniformLocation =
texturedProgram.getColorFilterUniformLocation(gl);
}

if (
!this.vao ||
!this.indexBuffer ||
!this.uvBuffer ||
!this.normalBuffer
!this.normalBuffer ||
!this.colorFilterUniformLocation
) {
return;
}
Expand All @@ -61,6 +69,8 @@ export default class TRenderableTexturedMesh {
m,
);

gl.uniform4fv(this.colorFilterUniformLocation, colorFilter);

gl.uniform1f(
texturedProgram.program!.uniformLocations.uEnableInstanceUVs,
instanceUVs ? 1 : 0,
Expand Down
2 changes: 2 additions & 0 deletions packages/ted/src/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export default class TRenderer {
texture,
task.transform,
task.material.options.instanceUVs,
task.material.options.colorFilter,
);
}
}
Expand All @@ -219,6 +220,7 @@ export default class TRenderer {
texture,
task.transform,
task.material.options.instanceUVs,
task.material.options.colorFilter,
);
}
}
Expand Down
12 changes: 9 additions & 3 deletions packages/ted/src/renderer/textured-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,28 @@ export default class TTexturedProgram {

constructor(
private renderer: TRenderer,
private resourceManager: TResourceManager
private resourceManager: TResourceManager,
) {}

public async load() {
this.program = await this.resourceManager.load<TProgram>(
TProgram,
basicShader
basicShader,
);

const gl = this.renderer.context();
this.program.compile(gl);
}

public getTextureUniformLocation(
gl: WebGL2RenderingContext
gl: WebGL2RenderingContext,
): WebGLUniformLocation | undefined {
return this.program?.getUniformLocation(gl, 'uTexture');
}

public getColorFilterUniformLocation(
gl: WebGL2RenderingContext,
): WebGLUniformLocation | undefined {
return this.program?.getUniformLocation(gl, 'uColorFilter');
}
}
4 changes: 3 additions & 1 deletion packages/ted/src/shaders/textured.program
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ void main() {
precision mediump float;

uniform sampler2D uTexture;
uniform vec4 uColorFilter;

in highp vec2 vUV;

out vec4 outputColor;

void main() {
outputColor = texture(uTexture, vUV);
vec4 textureColor = texture(uTexture, vUV);
outputColor = textureColor * uColorFilter;
}

0 comments on commit 8689535

Please sign in to comment.