第5步GLSL#

step_05.glsl#
1#define N 500
2
3// x, y position of the light
4uniform vec2 lightPosition;
5// Size of light in pixels
6uniform float lightSize;
7
8float terrain(vec2 samplePoint)
9{
10 float samplePointAlpha = texture(iChannel0, samplePoint).a;
11 float sampleStepped = step(0.1, samplePointAlpha);
12 float returnValue = 1.0 - sampleStepped;
13
14 return returnValue;
15}
16
17void mainImage( out vec4 fragColor, in vec2 fragCoord )
18{
19 // Distance in pixels to the light
20 float distanceToLight = length(lightPosition - fragCoord);
21
22 // Normalize the fragment coordinate from (0.0, 0.0) to (1.0, 1.0)
23 vec2 normalizedFragCoord = fragCoord/iResolution.xy;
24 vec2 normalizedLightCoord = lightPosition.xy/iResolution.xy;
25
26 // Start our mixing variable at 1.0
27 float lightAmount = 1.0;
28 for(float i = 0.0; i < N; i++)
29 {
30 // A 0.0 - 1.0 ratio between where our current pixel is, and where the light is
31 float t = i / N;
32 // Grab a coordinate between where we are and the light
33 vec2 samplePoint = mix(normalizedFragCoord, normalizedLightCoord, t);
34 // Is there something there? If so, we'll assume we are in shadow
35 float shadowAmount = terrain(samplePoint);
36 // Multiply the light amount.
37 // (Multiply in case we want to upgrade to soft shadows)
38 lightAmount *= shadowAmount;
39 }
40
41 // Find out how much light we have based on the distance to our light
42 lightAmount *= 1.0 - smoothstep(0.0, lightSize, distanceToLight);
43
44 // We'll alternate our display between black and whatever is in channel 1
45 vec4 blackColor = vec4(0.0, 0.0, 0.0, 1.0);
46
47 // Our fragment color will be somewhere between black and channel 1
48 // dependent on the value of b.
49 fragColor = mix(blackColor, texture(iChannel1, normalizedFragCoord), lightAmount);
50}