A hackable template for creating small and fast browser games.
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 106 lines 3.3 kB view raw
1/** 2 * # Light 3 * 4 * The `Light` component allows an entity to emit light. 5 */ 6 7import {Vec3} from "../../lib/math.js"; 8import {Entity} from "../../lib/world.js"; 9import {LightKind} from "../../materials/light.js"; 10import {Game} from "../game.js"; 11import {Has} from "../world.js"; 12 13export type Light = LightAmbient | LightDirectional | LightPoint; 14 15export interface LightAmbient { 16 Kind: LightKind.Ambient; 17 Color: Vec3; 18 Intensity: number; 19} 20 21/** 22 * Add `LightAmbient` component to an entity. 23 * 24 * Ambient lights are only supported in 25 * [`sys_render_deferred`](sys_render_deferred.html). The entity's transform is 26 * ignored during shading. 27 * 28 * @param color The color of the light. 29 * @param intensity The intensity of the light, multiplied by the color. 30 */ 31export function light_ambient(color: Vec3 = [1, 1, 1], intensity: number = 0.2) { 32 return (game: Game, entity: Entity) => { 33 game.World.Signature[entity] |= Has.Light; 34 game.World.Light[entity] = { 35 Kind: LightKind.Ambient, 36 Color: color, 37 Intensity: intensity, 38 }; 39 }; 40} 41 42export interface LightDirectional { 43 Kind: LightKind.Directional; 44 Color: Vec3; 45 Intensity: number; 46} 47 48/** 49 * Add `LightDirectional` to an entity. 50 * 51 * The position of directional lights is ignored during shading. The direction 52 * in which the light shines is _the opposite_ of the forward vector of the 53 * entity's transform. In other words, directional lights shine backwards. This 54 * is done for consistency with the way cameras look at the scene. Add a depth 55 * camera components to the directional light to make it a shadow source. 56 * 57 * @param color The color of the light. 58 * @param intensity The intensity of the light, multiplied by the color. 59 */ 60export function light_directional(color: Vec3 = [1, 1, 1], intensity: number = 1) { 61 return (game: Game, entity: Entity) => { 62 game.World.Signature[entity] |= Has.Light; 63 game.World.Light[entity] = { 64 Kind: LightKind.Directional, 65 Color: color, 66 Intensity: intensity, 67 }; 68 }; 69} 70 71export interface LightPoint { 72 Kind: LightKind.Point; 73 Color: Vec3; 74 Intensity: number; 75} 76 77/** 78 * Add `LightPoint` to an entity. 79 * 80 * The position of the entity is used as the position of the light during shading. 81 * 82 * @param color The color of the light. 83 * @param intensity The intensity of the light at 1 world unit away. The 84 * intensity of 1 results in 100% of the object's color being visible, adjusted for 85 * the angle. The intensity is attenuated exponentially. 86 */ 87export function light_point(color: Vec3 = [1, 1, 1], intensity: number = 1) { 88 return (game: Game, entity: Entity) => { 89 game.World.Signature[entity] |= Has.Light; 90 game.World.Light[entity] = { 91 Kind: LightKind.Point, 92 Color: color, 93 Intensity: intensity, 94 }; 95 }; 96} 97 98/** 99 * Compute the radius of a light given the minimum desired intensity. 100 * 101 * @param base_intensity The base intensity of the light. 102 * @param min_intensity The minimum desired intensity at the computed radius. 103 */ 104export function light_radius(base_intensity: number, min_intensity: number = 0.005) { 105 return (base_intensity / min_intensity) ** 0.5; 106}