19
19
20
20
@interface CCEffectLighting ()
21
21
22
+ @property (nonatomic , strong ) NSMutableArray *lights;
23
+
22
24
@end
23
25
24
26
25
27
@implementation CCEffectLighting
26
28
27
29
-(id )init
28
30
{
29
- return [self initWithLight :nil ];
31
+ return [self initWithLights :nil ];
30
32
}
31
33
32
- -(id )initWithLight : (CCLightNode *)light
34
+ -(id )initWithLights : ( NSArray *)lights
33
35
{
34
36
NSArray *fragUniforms = @[
35
37
[CCEffectUniform uniform: @" vec4" name: @" u_lightColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]],
@@ -38,7 +40,7 @@ -(id)initWithLight:(CCLightNode *)light
38
40
39
41
NSArray *vertUniforms = @[
40
42
[CCEffectUniform uniform: @" mat4" name: @" u_ndcToTangentSpace" value: [NSValue valueWithGLKMatrix4: GLKMatrix4Identity]],
41
- [CCEffectUniform uniform: @" vec4" name: @" u_lightPosition " value: [NSValue valueWithGLKVector2: GLKVector2Make (0 .0f , 0 .0f )]]
43
+ [CCEffectUniform uniform: @" vec4" name: @" u_lightVector " value: [NSValue valueWithGLKVector2: GLKVector2Make (0 .0f , 0 .0f )]]
42
44
];
43
45
44
46
NSArray *varyings = @[
@@ -49,16 +51,39 @@ -(id)initWithLight:(CCLightNode *)light
49
51
{
50
52
self.debugName = @" CCEffectLighting" ;
51
53
52
- _light = light;
54
+ if (lights)
55
+ {
56
+ _lights = [lights mutableCopy ];
57
+ }
58
+ else
59
+ {
60
+ _lights = [[NSMutableArray alloc ] init ];
61
+ }
53
62
}
54
63
return self;
55
64
}
56
65
57
- +(id )effectWithLight : (CCLightNode *)light
66
+ +(id )effectWithLight : (NSArray *)lights
67
+ {
68
+ return [[self alloc ] initWithLights: lights];
69
+ }
70
+
71
+ -(void )addLight : (CCLightNode *)light
58
72
{
59
- return [[ self alloc ] initWithLight : light];
73
+ [_lights addObject : light];
60
74
}
61
75
76
+ -(void )removeLight : (CCLightNode *)light
77
+ {
78
+ [_lights removeObject: light];
79
+ }
80
+
81
+ -(void )removeAllLights
82
+ {
83
+ [_lights removeAllObjects ];
84
+ }
85
+
86
+
62
87
-(void )buildFragmentFunctions
63
88
{
64
89
self.fragmentFunctions = [[NSMutableArray alloc ] init ];
@@ -94,7 +119,7 @@ -(void)buildVertexFunctions
94
119
// vertex. cc_Position was transformed on the CPU so we need to
95
120
// back it out from NDC (normalized device coords) to tangent
96
121
// space before using it to compute the light direction.
97
- v_tangentSpaceLightDir = normalize (u_lightPosition - u_ndcToTangentSpace * cc_Position);
122
+ v_tangentSpaceLightDir = normalize (u_lightVector - u_ndcToTangentSpace * cc_Position);
98
123
return cc_Position;
99
124
);
100
125
@@ -115,21 +140,31 @@ -(void)buildRenderPasses
115
140
pass.shaderUniforms [CCShaderUniformPreviousPassTexture] = previousPassTexture;
116
141
pass.shaderUniforms [CCShaderUniformTexCoord1Center] = [NSValue valueWithGLKVector2: pass.texCoord1Center];
117
142
pass.shaderUniforms [CCShaderUniformTexCoord1Extents] = [NSValue valueWithGLKVector2: pass.texCoord1Extents];
118
-
119
- // Get the transform from the light's coordinate space to the effect's coordinate space.
120
- GLKMatrix4 lightNodeToEffectNode = weakSelf.light ? CCEffectUtilsTransformFromNodeToNode (weakSelf.light , pass.node , nil ) : GLKMatrix4Identity;
121
-
122
- // Compute the light's position in the effect node's coordinate system.
123
- GLKVector4 lightPosition = GLKMatrix4MultiplyVector4 (lightNodeToEffectNode, GLKVector4Make (weakSelf.light .anchorPointInPoints .x , weakSelf.light .anchorPointInPoints .y , 500 .0f , 1 .0f ));
124
-
125
- GLKVector4 lightColor = GLKVector4MultiplyScalar (weakSelf.light .color .glkVector4 , weakSelf.light .intensity );
126
- GLKVector4 ambientColor = GLKVector4MultiplyScalar (weakSelf.light .ambientColor .glkVector4 , weakSelf.light .ambientIntensity );
127
-
128
- pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightColor" ]] = [NSValue valueWithGLKVector4: lightColor];
129
- pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightPosition" ]] = [NSValue valueWithGLKVector4: lightPosition];
130
- pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_globalAmbientColor" ]] = [NSValue valueWithGLKVector4: ambientColor];
143
+
144
+ // Matrix for converting NDC (normalized device coordinates (aka normalized render target coordinates)
145
+ // to node local coordinates.
131
146
pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_ndcToTangentSpace" ]] = [NSValue valueWithGLKMatrix4: pass.ndcToNodeLocal];
132
-
147
+
148
+ GLKVector4 globalAmbientColor = GLKVector4Make (0 .0f , 0 .0f , 0 .0f , 1 .0f );
149
+ for (CCLightNode *light in weakSelf.lights )
150
+ {
151
+ // Add this light's ambient contribution to the global ambient light color.
152
+ globalAmbientColor = GLKVector4Add (globalAmbientColor, GLKVector4MultiplyScalar (light.ambientColor .glkVector4 , light.ambientIntensity ));
153
+
154
+ // Get the transform from the light's coordinate space to the effect's coordinate space.
155
+ GLKMatrix4 lightNodeToEffectNode = CCEffectUtilsTransformFromNodeToNode (light, pass.node , nil );
156
+
157
+ // Compute the light's position in the effect node's coordinate system.
158
+ GLKVector4 lightPosition = GLKMatrix4MultiplyVector4 (lightNodeToEffectNode, GLKVector4Make (light.anchorPointInPoints .x , light.anchorPointInPoints .y , 500 .0f , 1 .0f ));
159
+
160
+ GLKVector4 lightColor = GLKVector4MultiplyScalar (light.color .glkVector4 , light.intensity );
161
+
162
+ pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightColor" ]] = [NSValue valueWithGLKVector4: lightColor];
163
+ pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightVector" ]] = [NSValue valueWithGLKVector4: lightPosition];
164
+ }
165
+
166
+ pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_globalAmbientColor" ]] = [NSValue valueWithGLKVector4: globalAmbientColor];
167
+
133
168
} copy]];
134
169
135
170
self.renderPasses = @[pass0];
0 commit comments