UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

74 lines (60 loc) 2.6 kB
//#region src/core/shaders/chunks/fragment/head/get-lights-infos.ts /** WGSL functions to get the {@link core/lights/DirectionalLight.DirectionalLight | DirectionalLight} or {@link core/lights/PointLight.PointLight | PointLight} informations. */ const getLightsInfos = ` struct LightContribution { diffuse: vec3f, specular: vec3f } struct ReflectedLight { directDiffuse: vec3f, directSpecular: vec3f, indirectDiffuse: vec3f, indirectSpecular: vec3f, } struct DirectLight { color: vec3f, direction: vec3f, visible: bool, } fn rangeAttenuation(range: f32, distance: f32, decay: f32) -> f32 { var distanceFalloff: f32 = 1.0 / max( pow( distance, decay ), EPSILON ); if ( range > 0.0 ) { distanceFalloff *= pow2( saturate( 1.0 - pow4( distance / range )) ); } return distanceFalloff; } fn spotAttenuation(coneCosine: f32, penumbraCosine: f32, angleCosine: f32) -> f32 { return smoothstep( coneCosine, penumbraCosine, angleCosine ); } fn getDirectionalLightInfo(directionalLight: DirectionalLightsElement, ptr_light: ptr<function, DirectLight>) { (*ptr_light).color = directionalLight.color; (*ptr_light).direction = -directionalLight.direction; // already normalized on the CPU (*ptr_light).visible = length((*ptr_light).color) > EPSILON; } fn getPointLightInfo(pointLight: PointLightsElement, worldPosition: vec3f, ptr_light: ptr<function, DirectLight>) { let lightDirection: vec3f = pointLight.position - worldPosition; (*ptr_light).direction = normalize(lightDirection); let lightDistance: f32 = length(lightDirection); (*ptr_light).color = pointLight.color; (*ptr_light).color *= rangeAttenuation(pointLight.range, lightDistance, 2.0); (*ptr_light).visible = length((*ptr_light).color) > EPSILON; } fn getSpotLightInfo(spotLight: SpotLightsElement, worldPosition: vec3f, ptr_light: ptr<function, DirectLight>) { let lVector: vec3f = spotLight.position - worldPosition; let lightDirection: vec3f = normalize(lVector); (*ptr_light).direction = lightDirection; let angleCos: f32 = dot(lightDirection, -spotLight.direction); let spotAttenuation: f32 = spotAttenuation(spotLight.coneCos, spotLight.penumbraCos, angleCos); if (spotAttenuation > 0.0) { let lightDistance: f32 = length(lVector); (*ptr_light).color = spotLight.color * spotAttenuation; (*ptr_light).color *= rangeAttenuation(spotLight.range, lightDistance, 2.0); (*ptr_light).visible = length((*ptr_light).color) > EPSILON; } else { (*ptr_light).color = vec3(0.0); (*ptr_light).visible = false; } } `; //#endregion export { getLightsInfos };