I managed to figure out spotlights. I’m still trying to figure out point lights.

```
let aspect = Float(view.bounds.width) / Float(view.bounds.height)
scene.uniforms.projectionMatrix = float4x4(projectionFov: radians(fromDegrees: 70), near: 0.01, far: 16, aspect: aspect)
let position: float3 = [-sunlight.position.x, -sunlight.position.y, -sunlight.position.z]
let center: float3 = [0, 0, 0]
let lookAt = float4x4(eye: position, center: position - sunlight.coneDirection, up: [0,1,0])
scene.uniforms.viewMatrix = float4x4(translation: [0, 0, 7]) * lookAt
scene.uniforms.shadowMatrix = scene.uniforms.projectionMatrix * scene.uniforms.viewMatrix
```

Shadow shader vertex

```
matrix_float4x4 mvp = uniforms.projectionMatrix * uniforms.viewMatrix * uniforms.modelMatrix;
float4 position = mvp * vertexIn.position;
float4 worldPosition = uniforms.modelMatrix * vertexIn.position;
float3 directionFromLightToFragment = normalize(light.position - worldPosition.xyz);
if (light.type == Spotlight) {
float3 tConeDirection = light.coneDirection;
float3 coneDirection = normalize(-tConeDirection);
float spotResult = dot(directionFromLightToFragment, coneDirection);
float coneAngle = cos(light.coneAngle);
if (spotResult < coneAngle) {
position = position.xyww;
}
}
```

Main Shader

```
float2 xy = in.shadowPosition.xy / in.shadowPosition.w;
xy = xy * 0.5 + 0.5;
xy.y = 1 - xy.y;
constexpr sampler s(coord::normalized, filter::linear, address::clamp_to_edge, compare_func:: less);
float shadow_sample = shadowTexture.sample(s, xy);
float current_sample = in.shadowPosition.z / in.shadowPosition.w;
if (current_sample > shadow_sample ) {
color *= 0.5;
}
```