That isn’t really a “light” shader - it’s the debug shader. It shows a red circle where a point light is.
And the point variable isn’t necessarily one pixel, you specify the size using a property with the [[point_size]]
attribute. That’s in VertexOut
and set to 20.0 in the vertex shader. You used points at the beginning of chapter 4 to try out transforms. You can look at the shader in the Chapter 4 Playground 3DTransforms to see how that works.
So without the discard_fragment()
bit, the debug shader would show a red square rather than a circle.
The fragment shader receives the fragment it’s going to render within that red square. That’s the [[point_coord]]
attribute, which is from 0 to 1. 0, 0 being the top left of the red square and 1,1 being the bottom right.
So a circle in that square would have a radius of 0.5. By checking whether the distance of the fragment is further than 0.5, you’re checking to see if it’s outside the circle (ie in the corner of the square). If it is, discard it, and you’re left with a red circle instead of a red square.
Rendering points can be quite useful aside from this debugging. They are 2D and very fast to render. Much later on, when rendering particles, you’ll use large points to render a texture on to. You can use them for billboard textures that always face the camera. For example, if you wanted to render a 2d tree in the background for speed, you could render a texture onto a point, and the tree would always face the camera.
Try changing point_size
in the vertex shader, vertex_light
, to something huge, like 150, make sure you’re debug rendering point lights in Renderer.swift:
debugLights(renderEncoder: renderEncoder, lightType: Pointlight)
and change the shader to this:
fragment float4 fragment_light(float2 point [[ point_coord]],
constant float3 &color [[ buffer(1) ]]) {
float d = distance(point, float2(0.5, 0.5));
// if (d > 0.5) {
// discard_fragment();
// }
if (point.x <= 0.2 && point.y <= 0.2) {
return float4(0, 1, 0, 1);
}
return float4(color ,1);
You’ll find that the top left of the resulting red square is rendered in green.