@@ -33,21 +33,7 @@ -(id)init
33
33
34
34
-(id )initWithLights : (NSArray *)lights
35
35
{
36
- NSArray *fragUniforms = @[
37
- [CCEffectUniform uniform: @" vec4" name: @" u_lightColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]],
38
- [CCEffectUniform uniform: @" vec4" name: @" u_globalAmbientColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]],
39
- ];
40
-
41
- NSArray *vertUniforms = @[
42
- [CCEffectUniform uniform: @" mat4" name: @" u_ndcToTangentSpace" value: [NSValue valueWithGLKMatrix4: GLKMatrix4Identity]],
43
- [CCEffectUniform uniform: @" vec4" name: @" u_lightVector" value: [NSValue valueWithGLKVector2: GLKVector2Make (0 .0f , 0 .0f )]]
44
- ];
45
-
46
- NSArray *varyings = @[
47
- [CCEffectVarying varying: @" vec4" name: @" v_tangentSpaceLightDir" ]
48
- ];
49
-
50
- if ((self = [super initWithFragmentUniforms: fragUniforms vertexUniforms: vertUniforms varyings: varyings]))
36
+ if ((self = [super init ]))
51
37
{
52
38
self.debugName = @" CCEffectLighting" ;
53
39
@@ -59,11 +45,29 @@ -(id)initWithLights:(NSArray *)lights
59
45
{
60
46
_lights = [[NSMutableArray alloc ] init ];
61
47
}
48
+
49
+
50
+ NSMutableArray *fragUniforms = [[NSMutableArray alloc ] initWithArray: @[[CCEffectUniform uniform: @" vec4" name: @" u_globalAmbientColor" value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]]]];
51
+ NSMutableArray *vertUniforms = [[NSMutableArray alloc ] initWithArray: @[[CCEffectUniform uniform: @" mat4" name: @" u_ndcToTangentSpace" value: [NSValue valueWithGLKMatrix4: GLKMatrix4Identity]]]];
52
+ NSMutableArray *varyings = [[NSMutableArray alloc ] init ];
53
+
54
+ for (NSUInteger lightIndex = 0 ; lightIndex < lights.count ; lightIndex++)
55
+ {
56
+ [vertUniforms addObject: [CCEffectUniform uniform: @" vec4" name: [NSString stringWithFormat: @" u_lightVector%lu " , (unsigned long )lightIndex] value: [NSValue valueWithGLKVector4: GLKVector4Make (0 .0f , 0 .0f , 0 .0f , 1 .0f )]]];
57
+ [fragUniforms addObject: [CCEffectUniform uniform: @" vec4" name: [NSString stringWithFormat: @" u_lightColor%lu " , (unsigned long )lightIndex] value: [NSValue valueWithGLKVector4: GLKVector4Make (1 .0f , 1 .0f , 1 .0f , 1 .0f )]]];
58
+
59
+ [varyings addObject: [CCEffectVarying varying: @" vec4" name: [NSString stringWithFormat: @" v_tangentSpaceLightDir%lu " , (unsigned long )lightIndex]]];
60
+ }
61
+
62
+ NSMutableArray *fragFunctions = [CCEffectLighting buildFragmentFunctionsWithLights: lights];
63
+ NSMutableArray *vertFunctions = [CCEffectLighting buildVertexFunctionsWithLights: lights];
64
+
65
+ [self buildEffectWithFragmentFunction: fragFunctions vertexFunctions: vertFunctions fragmentUniforms: fragUniforms vertexUniforms: vertUniforms varyings: varyings firstInStack: YES ];
62
66
}
63
67
return self;
64
68
}
65
69
66
- +(id )effectWithLight : (NSArray *)lights
70
+ +(id )effectWithLights : (NSArray *)lights
67
71
{
68
72
return [[self alloc ] initWithLights: lights];
69
73
}
@@ -84,47 +88,53 @@ -(void)removeAllLights
84
88
}
85
89
86
90
87
- -( void ) buildFragmentFunctions
91
+ +( NSMutableArray *) buildFragmentFunctionsWithLights : ( NSArray *) lights
88
92
{
89
- self.fragmentFunctions = [[NSMutableArray alloc ] init ];
90
-
91
93
CCEffectFunctionInput *input = [[CCEffectFunctionInput alloc ] initWithType: @" vec4" name: @" inputValue" initialSnippet: CCEffectDefaultInitialInputSnippet snippet: CCEffectDefaultInputSnippet];
92
94
93
- NSString * effectBody = CC_GLSL (
94
- // Index the normal map and expand the color value from [0..1] to [-1..1]
95
- vec4 normalMap = texture2D (cc_NormalMapTexture, cc_FragTexCoord2);
96
- vec4 tangentSpaceNormal = normalMap * 2.0 - 1.0 ;
97
-
98
- vec4 lightContribution = u_lightColor * dot (tangentSpaceNormal, v_tangentSpaceLightDir);
99
- if (normalMap.a > 0.0 )
100
- {
101
- return inputValue * (lightContribution + u_globalAmbientColor);
102
- }
103
- else
104
- {
105
- return vec4 (0 ,0 ,0 ,1 );
106
- }
107
- );
95
+ NSMutableString *effectBody = [[NSMutableString alloc ] init ];
96
+ [effectBody appendString: CC_GLSL (
97
+ // Index the normal map and expand the color value from [0..1] to [-1..1]
98
+ vec4 normalMap = texture2D (cc_NormalMapTexture, cc_FragTexCoord2);
99
+ vec4 tangentSpaceNormal = normalMap * 2.0 - 1.0 ;
100
+
101
+ if (normalMap.a == 0.0 )
102
+ {
103
+ return vec4 (0 ,0 ,0 ,0 );
104
+ }
105
+ vec4 resultColor = u_globalAmbientColor;
106
+ )];
107
+
108
+ for (NSUInteger lightIndex = 0 ; lightIndex < lights.count ; lightIndex++)
109
+ {
110
+ [effectBody appendFormat: @" resultColor += u_lightColor%lu * dot(tangentSpaceNormal, v_tangentSpaceLightDir%lu );\n " , (unsigned long )lightIndex, (unsigned long )lightIndex];
111
+ }
112
+ [effectBody appendString: @" return resultColor * inputValue;\n " ];
108
113
109
114
CCEffectFunction* fragmentFunction = [[CCEffectFunction alloc ] initWithName: @" lightingEffectFrag" body: effectBody inputs: @[input] returnType: @" vec4" ];
110
- [ self .fragmentFunctions addObject : fragmentFunction];
115
+ return [ NSMutableArray arrayWithObject : fragmentFunction];
111
116
}
112
117
113
- -( void ) buildVertexFunctions
118
+ +( NSMutableArray *) buildVertexFunctionsWithLights : ( NSArray *) lights
114
119
{
115
- self.vertexFunctions = [[NSMutableArray alloc ] init ];
116
-
117
- NSString * effectBody = CC_GLSL (
118
- // Compute the tangent space lighting direction vector for each
119
- // vertex. cc_Position was transformed on the CPU so we need to
120
- // back it out from NDC (normalized device coords) to tangent
121
- // space before using it to compute the light direction.
122
- v_tangentSpaceLightDir = normalize (u_lightVector - u_ndcToTangentSpace * cc_Position);
123
- return cc_Position;
124
- );
120
+ NSMutableString *effectBody = [[NSMutableString alloc ] init ];
121
+ for (NSUInteger lightIndex = 0 ; lightIndex < lights.count ; lightIndex++)
122
+ {
123
+ CCLightNode *light = lights[lightIndex];
124
+
125
+ if (light.type == CCLightNodeDirectional)
126
+ {
127
+ [effectBody appendFormat: @" v_tangentSpaceLightDir%lu = u_lightVector%lu ;" , (unsigned long )lightIndex, (unsigned long )lightIndex];
128
+ }
129
+ else
130
+ {
131
+ [effectBody appendFormat: @" v_tangentSpaceLightDir%lu = normalize(u_lightVector%lu - u_ndcToTangentSpace * cc_Position);" , (unsigned long )lightIndex, (unsigned long )lightIndex];
132
+ }
133
+ }
134
+ [effectBody appendString: @" return cc_Position;" ];
125
135
126
136
CCEffectFunction *vertexFunction = [[CCEffectFunction alloc ] initWithName: @" lightingEffectVtx" body: effectBody inputs: nil returnType: @" vec4" ];
127
- [ self .vertexFunctions addObject : vertexFunction];
137
+ return [ NSMutableArray arrayWithObject : vertexFunction];
128
138
}
129
139
130
140
-(void )buildRenderPasses
@@ -146,8 +156,10 @@ -(void)buildRenderPasses
146
156
pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_ndcToTangentSpace" ]] = [NSValue valueWithGLKMatrix4: pass.ndcToNodeLocal];
147
157
148
158
GLKVector4 globalAmbientColor = GLKVector4Make (0 .0f , 0 .0f , 0 .0f , 1 .0f );
149
- for (CCLightNode *light in weakSelf.lights )
159
+ for (NSUInteger lightIndex = 0 ; lightIndex < weakSelf.lights . count ; lightIndex++ )
150
160
{
161
+ CCLightNode *light = weakSelf.lights [lightIndex];
162
+
151
163
// Add this light's ambient contribution to the global ambient light color.
152
164
globalAmbientColor = GLKVector4Add (globalAmbientColor, GLKVector4MultiplyScalar (light.ambientColor .glkVector4 , light.ambientIntensity ));
153
165
@@ -157,10 +169,14 @@ -(void)buildRenderPasses
157
169
// Compute the light's position in the effect node's coordinate system.
158
170
GLKVector4 lightPosition = GLKMatrix4MultiplyVector4 (lightNodeToEffectNode, GLKVector4Make (light.anchorPointInPoints .x , light.anchorPointInPoints .y , 500 .0f , 1 .0f ));
159
171
172
+ // Compute the real light color based on color and intensity.
160
173
GLKVector4 lightColor = GLKVector4MultiplyScalar (light.color .glkVector4 , light.intensity );
161
174
162
- pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightColor" ]] = [NSValue valueWithGLKVector4: lightColor];
163
- pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_lightVector" ]] = [NSValue valueWithGLKVector4: lightPosition];
175
+ NSString *lightColorLabel = [NSString stringWithFormat: @" u_lightColor%lu " , (unsigned long )lightIndex];
176
+ NSString *lightVectorLabel = [NSString stringWithFormat: @" u_lightVector%lu " , (unsigned long )lightIndex];
177
+
178
+ pass.shaderUniforms [weakSelf.uniformTranslationTable[lightColorLabel]] = [NSValue valueWithGLKVector4: lightColor];
179
+ pass.shaderUniforms [weakSelf.uniformTranslationTable[lightVectorLabel]] = [NSValue valueWithGLKVector4: lightPosition];
164
180
}
165
181
166
182
pass.shaderUniforms [weakSelf.uniformTranslationTable[@" u_globalAmbientColor" ]] = [NSValue valueWithGLKVector4: globalAmbientColor];
0 commit comments