Skip to content

Commit f0f6858

Browse files
author
Thayer J Andrews
committed
CCEffectLighting - Start adding support for multiple lights
1 parent 8cf2eb2 commit f0f6858

File tree

2 files changed

+85
-30
lines changed

2 files changed

+85
-30
lines changed

cocos2d/CCEffectLighting.h

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,6 @@
1919
/// @name Accessing Effect Attributes
2020
/// -----------------------------------------------------------------------
2121

22-
/** The lights that will contribute to the lighting of the affected
23-
* node.
24-
*/
25-
@property (nonatomic, strong) CCLightNode *light;
26-
2722

2823
/// -----------------------------------------------------------------------
2924
/// @name Initializing a CCEffectLighting object
@@ -39,11 +34,11 @@
3934
/**
4035
* Initializes a CCEffectLighting object with the supplied parameters.
4136
*
42-
* @param environment The node that will light the affected node.
37+
* @param environment The array of lights that will light the affected node.
4338
*
4439
* @return The CCEffectLighting object.
4540
*/
46-
-(id)initWithLight:(CCLightNode *)light;
41+
-(id)initWithLights:(NSArray *)lights;
4742

4843

4944
/// -----------------------------------------------------------------------
@@ -53,10 +48,35 @@
5348
/**
5449
* Creates a CCEffectLighting object with the supplied parameters.
5550
*
56-
* @param environment The node that will light the affected node.
51+
* @param environment The array of lights that will light the affected node.
5752
*
5853
* @return The CCEffectLighting object.
5954
*/
60-
+(id)effectWithLight:(CCLightNode *)light;
55+
+(id)effectWithLights:(NSArray *)lights;
56+
57+
58+
/// -----------------------------------------------------------------------
59+
/// @name Adding and removing lights
60+
/// -----------------------------------------------------------------------
61+
62+
/**
63+
* Adds a light to the effect.
64+
*
65+
* @param light CCLightNode to add.
66+
*/
67+
-(void) addLight:(CCLightNode *)light;
68+
69+
/**
70+
* Removes a light from the effect.
71+
*
72+
* @param light The light node to remove.
73+
*/
74+
-(void) removeLight:(CCLightNode *)light;
75+
76+
/**
77+
* Removes all lights from the effect.
78+
*/
79+
-(void) removeAllLights;
80+
6181

6282
@end

cocos2d/CCEffectLighting.m

Lines changed: 56 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,19 @@
1919

2020
@interface CCEffectLighting ()
2121

22+
@property (nonatomic, strong) NSMutableArray *lights;
23+
2224
@end
2325

2426

2527
@implementation CCEffectLighting
2628

2729
-(id)init
2830
{
29-
return [self initWithLight:nil];
31+
return [self initWithLights:nil];
3032
}
3133

32-
-(id)initWithLight:(CCLightNode *)light
34+
-(id)initWithLights:(NSArray *)lights
3335
{
3436
NSArray *fragUniforms = @[
3537
[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
3840

3941
NSArray *vertUniforms = @[
4042
[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)]]
4244
];
4345

4446
NSArray *varyings = @[
@@ -49,16 +51,39 @@ -(id)initWithLight:(CCLightNode *)light
4951
{
5052
self.debugName = @"CCEffectLighting";
5153

52-
_light = light;
54+
if (lights)
55+
{
56+
_lights = [lights mutableCopy];
57+
}
58+
else
59+
{
60+
_lights = [[NSMutableArray alloc] init];
61+
}
5362
}
5463
return self;
5564
}
5665

57-
+(id)effectWithLight:(CCLightNode *)light
66+
+(id)effectWithLight:(NSArray *)lights
67+
{
68+
return [[self alloc] initWithLights:lights];
69+
}
70+
71+
-(void)addLight:(CCLightNode *)light
5872
{
59-
return [[self alloc] initWithLight:light];
73+
[_lights addObject:light];
6074
}
6175

76+
-(void)removeLight:(CCLightNode *)light
77+
{
78+
[_lights removeObject:light];
79+
}
80+
81+
-(void)removeAllLights
82+
{
83+
[_lights removeAllObjects];
84+
}
85+
86+
6287
-(void)buildFragmentFunctions
6388
{
6489
self.fragmentFunctions = [[NSMutableArray alloc] init];
@@ -94,7 +119,7 @@ -(void)buildVertexFunctions
94119
// vertex. cc_Position was transformed on the CPU so we need to
95120
// back it out from NDC (normalized device coords) to tangent
96121
// 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);
98123
return cc_Position;
99124
);
100125

@@ -115,21 +140,31 @@ -(void)buildRenderPasses
115140
pass.shaderUniforms[CCShaderUniformPreviousPassTexture] = previousPassTexture;
116141
pass.shaderUniforms[CCShaderUniformTexCoord1Center] = [NSValue valueWithGLKVector2:pass.texCoord1Center];
117142
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.
131146
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+
133168
} copy]];
134169

135170
self.renderPasses = @[pass0];

0 commit comments

Comments
 (0)