Skip to content

Commit

Permalink
Update Simple Lightmap Filter
Browse files Browse the repository at this point in the history
  • Loading branch information
bbazukun123 committed Jan 3, 2024
1 parent 0076c3f commit 3831b72
Show file tree
Hide file tree
Showing 6 changed files with 166 additions and 88 deletions.
174 changes: 102 additions & 72 deletions filters/simple-lightmap/src/SimpleLightmapFilter.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
import { vertex } from '@tools/fragments';
import fragment from './simpleLightmap.frag';
import { Filter, GlProgram } from 'pixi.js';
import type { Texture, FilterSystem, RenderTexture, RenderSurface } from 'pixi.js';
import { vertex, wgslVertex } from '@tools/fragments';
import fragment from './simple-lightmap.frag';
import source from './simple-lightmap.wgsl';
import { Color, Filter, GlProgram, GpuProgram, Texture, FilterSystem, RenderSurface, ColorSource } from 'pixi.js';

type Color = number | number[];
export interface SimpleLightmapFilterOptions
{
/** A texture where your lightmap is rendered */
lightMap: Texture;
/**
* The color value of the ambient color
* @example [1.0, 1.0, 1.0] = 0xffffff
* @default 0x000000
*/
color?: ColorSource;
/**
* Coefficient for alpha multiplication
* @default 1
*/
alpha?: number;
}

/**
* SimpleLightmap, originally by Oza94
Expand All @@ -25,97 +40,112 @@ type Color = number | number[];
*/
export class SimpleLightmapFilter extends Filter
{
private _color = 0x0;
/** Default values for options. */
public static readonly DEFAULT_OPTIONS: SimpleLightmapFilterOptions = {
lightMap: Texture.WHITE,
color: 0x000000,
alpha: 1
};

/**
* @param {Texture} texture - a texture where your lightmap is rendered
* @param {Array<number>|number} [color=0x000000] - An RGBA array of the ambient color
* @param {number} [alpha=1] - Default alpha set independent of color (if it's a number, not array).
*/
constructor(texture: Texture, color: Color = 0x000000, alpha = 1)
public uniforms: {
uColor: Float32Array;
uAlpha: number;
uDimensions: Float32Array;
};

private _color: Color;
private _lightMap!: Texture;

constructor(options: SimpleLightmapFilterOptions)
{
options = { ...SimpleLightmapFilter.DEFAULT_OPTIONS, ...options };

if (!options.lightMap) throw Error('No light map texture source was provided to SimpleLightmapFilter');

const gpuProgram = new GpuProgram({
vertex: {
source: wgslVertex,
entryPoint: 'mainVertex',
},
fragment: {
source,
entryPoint: 'mainFragment',
},
});
const glProgram = new GlProgram({
vertex,
fragment,
name: 'simple-lightmap-filter',
});

super({
gpuProgram,
glProgram,
resources: {},
resources: {
simpleLightmapUniforms: {
uColor: { value: new Float32Array(3), type: 'vec3<f32>' },
uAlpha: { value: options.alpha, type: 'f32' },
uDimensions: { value: new Float32Array(2), type: 'vec2<f32>' },
},
uMapTexture: options.lightMap,
},
});

// this.uniforms.dimensions = new Float32Array(2);
// this.uniforms.ambientColor = new Float32Array([0, 0, 0, alpha]);
// this.texture = texture;
// this.color = color;
this.uniforms = this.resources.simpleLightmapUniforms.uniforms;

this._color = new Color();
this.color = options.color ?? 0x000000;

Object.assign(this, options);
}

/**
* Applies the filter.
* @private
* @param {FilterManager} filterManager - The manager.
* @param {RenderTarget} input - The input target.
* @param {RenderTarget} output - The output target.
* Override existing apply method in `Filter`
* @override
* @ignore
*/
apply(filterManager: FilterSystem, input: Texture, output: RenderSurface, clear: boolean): void
public override apply(
filterManager: FilterSystem,
input: Texture,
output: RenderSurface,
clearMode: boolean,
): void
{
// this.uniforms.dimensions[0] = input.filterFrame?.width;
// this.uniforms.dimensions[1] = input.filterFrame?.height;
this.uniforms.uDimensions[0] = input.frame.width;
this.uniforms.uDimensions[1] = input.frame.height;

// // draw the filter...
// filterManager.applyFilter(this, input, output, clear);
// draw the filter...
filterManager.applyFilter(this, input, output, clearMode);
}

/**
* a texture where your lightmap is rendered
* @member {Texture}
*/
// get texture(): Texture
// {
// return this.uniforms.uLightmap;
// }
// set texture(value: Texture)
// {
// this.uniforms.uLightmap = value;
// }
/** A sprite where your lightmap is rendered */
get lightMap(): Texture { return this._lightMap; }
set lightMap(value: Texture)
{
this._lightMap = value;
this.resources.uMapTexture = value.source;
}

/**
* An RGBA array of the ambient color or a hex color without alpha
* @member {Array<number>|number}
* The color value of the ambient color
* @example [1.0, 1.0, 1.0] = 0xffffff
* @default 0x000000
*/
// set color(value: Color)
// {
// const arr = this.uniforms.ambientColor;

// if (typeof value === 'number')
// {
// utils.hex2rgb(value, arr);
// this._color = value;
// }
// else
// {
// arr[0] = value[0];
// arr[1] = value[1];
// arr[2] = value[2];
// arr[3] = value[3];
// this._color = utils.rgb2hex(arr);
// }
// }
// get color(): Color
// {
// return this._color;
// }
get color(): ColorSource { return this._color.value as ColorSource; }
set color(value: ColorSource)
{
this._color.setValue(value);
const [r, g, b] = this._color.toArray();

this.uniforms.uColor[0] = r;
this.uniforms.uColor[1] = g;
this.uniforms.uColor[2] = b;
}

/**
* When setting `color` as hex, this can be used to set alpha independently.
* Coefficient for alpha multiplication
* @default 1
*/
// get alpha(): number
// {
// return this.uniforms.ambientColor[3];
// }
// set alpha(value: number)
// {
// this.uniforms.ambientColor[3] = value;
// }
get alpha(): number { return this.uniforms.uAlpha; }
set alpha(value: number) { this.uniforms.uAlpha = value; }
}
21 changes: 21 additions & 0 deletions filters/simple-lightmap/src/simple-lightmap.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
precision highp float;
in vec2 vTextureCoord;
out vec4 finalColor;

uniform sampler2D uSampler;
uniform sampler2D uMapTexture;
uniform vec3 uColor;
uniform float uAlpha;
uniform vec2 uDimensions;

uniform vec4 uInputSize;

void main() {
vec4 diffuseColor = texture(uSampler, vTextureCoord);
vec2 lightCoord = (vTextureCoord * uInputSize.xy) / uDimensions;
vec4 light = texture(uMapTexture, lightCoord);
vec3 ambient = uColor.rgb * uAlpha;
vec3 intensity = ambient + light.rgb;
vec3 color = diffuseColor.rgb * intensity;
finalColor = vec4(color, diffuseColor.a);
}
38 changes: 38 additions & 0 deletions filters/simple-lightmap/src/simple-lightmap.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
struct SimpleLightmapUniforms {
uColor: vec3<f32>,
uAlpha: f32,
uDimensions: vec2<f32>,
};

struct GlobalFilterUniforms {
uInputSize:vec4<f32>,
uInputPixel:vec4<f32>,
uInputClamp:vec4<f32>,
uOutputFrame:vec4<f32>,
uGlobalFrame:vec4<f32>,
uOutputTexture:vec4<f32>,
};

@group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms;

@group(0) @binding(1) var uSampler: texture_2d<f32>;
@group(1) @binding(0) var<uniform> simpleLightmapUniforms : SimpleLightmapUniforms;
@group(1) @binding(1) var uMapTexture: texture_2d<f32>;

@fragment
fn mainFragment(
@builtin(position) position: vec4<f32>,
@location(0) uv : vec2<f32>,
) -> @location(0) vec4<f32> {
let uColor = simpleLightmapUniforms.uColor;
let uAlpha = simpleLightmapUniforms.uAlpha;
let uDimensions = simpleLightmapUniforms.uDimensions;

let diffuseColor: vec4<f32> = textureSample(uSampler, uSampler, uv);
let lightCoord: vec2<f32> = (uv * gfu.uInputSize.xy) / simpleLightmapUniforms.uDimensions;
let light: vec4<f32> = textureSample(uMapTexture, uSampler, position);
let ambient: vec3<f32> = uColor * uAlpha;
let intensity: vec3<f32> = ambient + light.rgb;
let finalColor: vec3<f32> = diffuseColor.rgb * intensity;
return vec4<f32>(finalColor, diffuseColor.a);
}
15 changes: 0 additions & 15 deletions filters/simple-lightmap/src/simpleLightmap.frag

This file was deleted.

5 changes: 4 additions & 1 deletion tools/demo/src/filters/lightmap.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
export default function ()
{
this.addFilter('SimpleLightmapFilter', {
args: [this.resources.lightmap, 0x666666],
args: { lightMap: this.resources.lightmap, color: 0x666666 },
oncreate(folder)
{
folder.addColor(this, 'color');
folder.add(this, 'alpha', 0, 1);

this._noop = () => {};
folder.add(this, '_noop').name('<img src="./images/lightmap.png" width="220" height="13">');
},
});
}
1 change: 1 addition & 0 deletions tools/demo/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ const main = async () =>
filters.crt.call(app);
filters.godray.call(app);
filters.reflection.call(app);
filters.simpleLightmap.call(app);
// filters.kawaseBlur.call(app);

// TODO: Re-enable this in place of the above once v8 conversion is complete
Expand Down

0 comments on commit 3831b72

Please sign in to comment.