@luma.gl/shadertools
Version:
Shader module system for luma.gl
86 lines (72 loc) • 2.45 kB
text/typescript
// luma.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
export const lightingUniformsWGSL = /* wgsl */ `\
// #if (defined(SHADER_TYPE_FRAGMENT) && defined(LIGHTING_FRAGMENT)) || (defined(SHADER_TYPE_VERTEX) && defined(LIGHTING_VERTEX))
const MAX_LIGHTS: i32 = 5;
struct AmbientLight {
color: vec3<f32>,
};
struct PointLight {
color: vec3<f32>,
position: vec3<f32>,
attenuation: vec3<f32>, // 2nd order x:Constant-y:Linear-z:Exponential
};
struct SpotLight {
color: vec3<f32>,
position: vec3<f32>,
direction: vec3<f32>,
attenuation: vec3<f32>,
coneCos: vec2<f32>,
};
struct DirectionalLight {
color: vec3<f32>,
direction: vec3<f32>,
};
struct UniformLight {
color: vec3<f32>,
position: vec3<f32>,
direction: vec3<f32>,
attenuation: vec3<f32>,
coneCos: vec2<f32>,
};
struct lightingUniforms {
enabled: i32,
directionalLightCount: i32,
pointLightCount: i32,
spotLightCount: i32,
ambientColor: vec3<f32>,
lights: array<UniformLight, 5>,
};
@group(2) @binding(auto) var<uniform> lighting : lightingUniforms;
fn lighting_getPointLight(index: i32) -> PointLight {
let light = lighting.lights[index];
return PointLight(light.color, light.position, light.attenuation);
}
fn lighting_getSpotLight(index: i32) -> SpotLight {
let light = lighting.lights[lighting.pointLightCount + index];
return SpotLight(light.color, light.position, light.direction, light.attenuation, light.coneCos);
}
fn lighting_getDirectionalLight(index: i32) -> DirectionalLight {
let light = lighting.lights[lighting.pointLightCount + lighting.spotLightCount + index];
return DirectionalLight(light.color, light.direction);
}
fn getPointLightAttenuation(pointLight: PointLight, distance: f32) -> f32 {
return pointLight.attenuation.x
+ pointLight.attenuation.y * distance
+ pointLight.attenuation.z * distance * distance;
}
fn getSpotLightAttenuation(spotLight: SpotLight, positionWorldspace: vec3<f32>) -> f32 {
let lightDirection = normalize(positionWorldspace - spotLight.position);
let coneFactor = smoothstep(
spotLight.coneCos.y,
spotLight.coneCos.x,
dot(normalize(spotLight.direction), lightDirection)
);
let distanceAttenuation = getPointLightAttenuation(
PointLight(spotLight.color, spotLight.position, spotLight.attenuation),
distance(spotLight.position, positionWorldspace)
);
return distanceAttenuation / max(coneFactor, 0.0001);
}
`;