@@ -35,8 +35,9 @@ @interface CCEffectLighting ()
35
35
36
36
@property (nonatomic , strong ) NSMutableArray *lights;
37
37
@property (nonatomic , assign ) CCLightKey lightKey;
38
- @property (nonatomic , readonly ) BOOL hasSpecular;
39
- @property (nonatomic , assign ) BOOL previousHasSpecular;
38
+ @property (nonatomic , readonly ) BOOL needsSpecular;
39
+ @property (nonatomic , assign ) BOOL shaderHasSpecular;
40
+ @property (nonatomic , assign ) BOOL shaderHasNormalMap;
40
41
41
42
@end
42
43
@@ -66,8 +67,9 @@ -(id)initWithLights:(NSArray *)lights
66
67
_specularColor = [CCColor whiteColor ];
67
68
_shininess = 5 .0f ;
68
69
69
- _lightKey = CCLightKeyMake (nil );
70
- _previousHasSpecular = NO ;
70
+ _lightKey = CCLightKeyMake (lights);
71
+ _shaderHasSpecular = NO ;
72
+ _shaderHasNormalMap = NO ;
71
73
}
72
74
return self;
73
75
}
@@ -96,21 +98,12 @@ -(void)removeAllLights
96
98
}
97
99
98
100
99
- +(NSMutableArray *)buildFragmentFunctionsWithLights : (NSArray *)lights andSpecular : (BOOL )hasSpecular
101
+ +(NSMutableArray *)buildFragmentFunctionsWithLights : (NSArray *)lights normalMap : (BOOL )needsNormalMap specular : ( BOOL ) needsSpecular
100
102
{
101
103
CCEffectFunctionInput *input = [[CCEffectFunctionInput alloc ] initWithType: @" vec4" name: @" inputValue" initialSnippet: CCEffectDefaultInitialInputSnippet snippet: CCEffectDefaultInputSnippet];
102
104
103
105
NSMutableString *effectBody = [[NSMutableString alloc ] init ];
104
106
[effectBody appendString: CC_GLSL (
105
- // Index the normal map and expand the color value from [0..1] to [-1..1]
106
- vec4 normalMap = texture2D (cc_NormalMapTexture, cc_FragTexCoord2);
107
- vec3 tangentSpaceNormal = normalize (normalMap.xyz * 2.0 - 1.0 );
108
-
109
- if ((inputValue.a * normalMap.a) == 0.0 )
110
- {
111
- return vec4 (0 ,0 ,0 ,0 );
112
- }
113
-
114
107
vec4 lightColor;
115
108
vec4 diffuseLightColor = u_globalAmbientColor;
116
109
vec4 specularLightColor = vec4 (0 ,0 ,0 ,0 );
@@ -122,8 +115,30 @@ +(NSMutableArray *)buildFragmentFunctionsWithLights:(NSArray*)lights andSpecular
122
115
float falloffTerm;
123
116
float diffuseTerm;
124
117
float specularTerm;
118
+ float composedAlpha = inputValue.a;
125
119
)];
126
120
121
+ if (needsNormalMap)
122
+ {
123
+ [effectBody appendString: CC_GLSL (
124
+ // Index the normal map and expand the color value from [0..1] to [-1..1]
125
+ vec4 normalMap = texture2D (cc_NormalMapTexture, cc_FragTexCoord2);
126
+ vec3 tangentSpaceNormal = normalize (normalMap.xyz * 2.0 - 1.0 );
127
+ composedAlpha *= normalMap.a;
128
+ )];
129
+ }
130
+ else
131
+ {
132
+ [effectBody appendString: @" vec3 tangentSpaceNormal = vec3(0,0,1);\n " ];
133
+ }
134
+
135
+ [effectBody appendString: CC_GLSL (
136
+ if (composedAlpha == 0.0 )
137
+ {
138
+ return vec4 (0 ,0 ,0 ,0 );
139
+ }
140
+ )];
141
+
127
142
for (NSUInteger lightIndex = 0 ; lightIndex < lights.count ; lightIndex++)
128
143
{
129
144
CCLightNode *light = lights[lightIndex];
@@ -142,15 +157,15 @@ +(NSMutableArray *)buildFragmentFunctionsWithLights:(NSArray*)lights andSpecular
142
157
[effectBody appendString: @" diffuseTerm = max(0.0, dot(tangentSpaceNormal, tangentSpaceLightDir));\n " ];
143
158
[effectBody appendString: @" diffuseLightColor += lightColor * diffuseTerm;\n " ];
144
159
145
- if (hasSpecular )
160
+ if (needsSpecular )
146
161
{
147
162
[effectBody appendString: @" halfAngleDir = (2.0 * dot(tangentSpaceLightDir, tangentSpaceNormal) * tangentSpaceNormal - tangentSpaceLightDir);\n " ];
148
163
[effectBody appendString: @" specularTerm = max(0.0, dot(halfAngleDir, vec3(0,0,1))) * step(0.0, diffuseTerm);\n " ];
149
164
[effectBody appendString: @" specularLightColor += lightColor * pow(specularTerm, u_specularExponent);\n " ];
150
165
}
151
166
}
152
167
[effectBody appendString: @" vec4 resultColor = diffuseLightColor * inputValue;\n " ];
153
- if (hasSpecular )
168
+ if (needsSpecular )
154
169
{
155
170
[effectBody appendString: @" resultColor += specularLightColor * u_specularColor;\n " ];
156
171
}
@@ -249,12 +264,17 @@ - (CCEffectPrepareStatus)prepareForRenderingWithSprite:(CCSprite *)sprite
249
264
{
250
265
CCEffectPrepareStatus result = CCEffectPrepareNothingToDo;
251
266
267
+ BOOL needsNormalMap = (sprite.normalMapSpriteFrame != nil );
268
+
252
269
CCLightKey newLightKey = CCLightKeyMake (_lights);
253
- if (!CCLightKeyCompare (newLightKey, _lightKey) ||
254
- (_previousHasSpecular != self.hasSpecular ))
270
+ if (!self.shader ||
271
+ !CCLightKeyCompare (newLightKey, _lightKey) ||
272
+ (_shaderHasSpecular != self.needsSpecular ) ||
273
+ (_shaderHasNormalMap != needsNormalMap))
255
274
{
256
275
_lightKey = newLightKey;
257
- _previousHasSpecular = self.hasSpecular ;
276
+ _shaderHasSpecular = self.needsSpecular ;
277
+ _shaderHasNormalMap = needsNormalMap;
258
278
259
279
NSMutableArray *fragUniforms = [[NSMutableArray alloc ] initWithArray: @[[CCEffectUniform uniform: @" vec4" name: @" u_globalAmbientColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]]]];
260
280
NSMutableArray *vertUniforms = [[NSMutableArray alloc ] initWithArray: @[[CCEffectUniform uniform: @" mat4" name: @" u_ndcToTangentSpace" value: [NSValue valueWithGLKMatrix4: GLKMatrix4Identity]]]];
@@ -275,13 +295,13 @@ - (CCEffectPrepareStatus)prepareForRenderingWithSprite:(CCSprite *)sprite
275
295
[varyings addObject: [CCEffectVarying varying: @" vec4" name: [NSString stringWithFormat: @" v_tangentSpaceLightDir%lu " , (unsigned long )lightIndex]]];
276
296
}
277
297
278
- if (self.hasSpecular )
298
+ if (self.needsSpecular )
279
299
{
280
300
[fragUniforms addObject: [CCEffectUniform uniform: @" float" name: @" u_specularExponent" value: [NSNumber numberWithFloat: 5 .0f ]]];
281
301
[fragUniforms addObject: [CCEffectUniform uniform: @" vec4" name: @" u_specularColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]]];
282
302
}
283
303
284
- NSMutableArray *fragFunctions = [CCEffectLighting buildFragmentFunctionsWithLights: _lights andSpecular: self .hasSpecular ];
304
+ NSMutableArray *fragFunctions = [CCEffectLighting buildFragmentFunctionsWithLights: _lights normalMap: needsNormalMap specular: self .needsSpecular ];
285
305
NSMutableArray *vertFunctions = [CCEffectLighting buildVertexFunctionsWithLights: _lights];
286
306
287
307
[self buildEffectWithFragmentFunction: fragFunctions vertexFunctions: vertFunctions fragmentUniforms: fragUniforms vertexUniforms: vertUniforms varyings: varyings firstInStack: YES ];
@@ -291,7 +311,7 @@ - (CCEffectPrepareStatus)prepareForRenderingWithSprite:(CCSprite *)sprite
291
311
return result;
292
312
}
293
313
294
- - (BOOL )hasSpecular
314
+ - (BOOL )needsSpecular
295
315
{
296
316
return (!ccc4FEqual (_specularColor.ccColor4f , ccc4f (0 .0f , 0 .0f , 0 .0f , 0 .0f )) && (_shininess > 0 .0f ));
297
317
}
0 commit comments