lingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
84 lines (78 loc) • 2.6 kB
JavaScript
import { Vector3, Vector2 } from "three";
import { shaderMaterial } from "@pmndrs/vanilla";
import { FAR, NEAR } from "../../../globals";
import { whiteColor } from "../../utils/reusables";
const SpotLightMaterial = shaderMaterial({
depth: null,
opacity: 1,
attenuation: 2.5,
anglePower: 12,
spotPosition: new Vector3(0, 0, 0),
lightColor: whiteColor,
cameraNear: NEAR,
cameraFar: FAR,
resolution: new Vector2(0, 0),
transparent: true,
depthWrite: false
},
/* glsl */ `
varying vec3 vNormal;
varying vec3 vWorldPosition;
varying float vViewZ;
varying float vIntensity;
uniform vec3 spotPosition;
uniform float attenuation;
void main() {
// compute intensity
vNormal = normalize( normalMatrix * normal );
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
vWorldPosition = worldPosition.xyz;
vec4 viewPosition = viewMatrix * worldPosition;
vViewZ = viewPosition.z;
float intensity = distance(worldPosition.xyz, spotPosition) / attenuation;
intensity = 1.0 - clamp(intensity, 0.0, 1.0);
vIntensity = intensity;
// set gl_Position
gl_Position = projectionMatrix * viewPosition;
}`,
/* glsl */ `
varying vec3 vNormal;
varying vec3 vWorldPosition;
uniform vec3 lightColor;
uniform vec3 spotPosition;
uniform float attenuation;
uniform float anglePower;
uniform sampler2D depth;
uniform vec2 resolution;
uniform float cameraNear;
uniform float cameraFar;
varying float vViewZ;
varying float vIntensity;
uniform float opacity;
float readDepth( sampler2D depthSampler, vec2 coord ) {
float fragCoordZ = texture2D( depthSampler, coord ).x;
float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);
return viewZ;
}
void main() {
float d = 1.0;
bool isSoft = resolution[0] > 0.0 && resolution[1] > 0.0;
if (isSoft) {
vec2 sUv = gl_FragCoord.xy / resolution;
d = readDepth(depth, sUv);
}
float intensity = vIntensity;
vec3 normal = vec3(vNormal.x, vNormal.y, abs(vNormal.z));
float angleIntensity = pow( dot(normal, vec3(0.0, 0.0, 1.0)), anglePower );
intensity *= angleIntensity;
// fades when z is close to sampled depth, meaning the cone is intersecting existing geometry
if (isSoft) {
intensity *= smoothstep(0., 1., vViewZ - d);
}
gl_FragColor = vec4(lightColor, intensity * opacity);
}`);
export { SpotLightMaterial };
//# sourceMappingURL=SpotLightMaterial.js.map