From 53ad652463601cf8aa4bfc05d0ef65212b4b7ef0 Mon Sep 17 00:00:00 2001 From: songchengjiang Date: Wed, 27 Aug 2014 16:26:01 +0800 Subject: [PATCH 1/3] Light Shader optimization --- cocos/renderer/CCGLProgram.cpp | 36 ++++---- cocos/renderer/ccShader_3D_ColorNormal.frag | 89 +++++++++++-------- .../renderer/ccShader_3D_ColorNormalTex.frag | 87 ++++++++++-------- .../ccShader_3D_PositionNormalTex.vert | 64 ++++++++++--- 4 files changed, 174 insertions(+), 102 deletions(-) diff --git a/cocos/renderer/CCGLProgram.cpp b/cocos/renderer/CCGLProgram.cpp index 00a784124b..95f6083d9c 100644 --- a/cocos/renderer/CCGLProgram.cpp +++ b/cocos/renderer/CCGLProgram.cpp @@ -46,9 +46,9 @@ THE SOFTWARE. #include "CCPrecompiledShaders.h" #endif -#define CC_MAX_DIRECTIONAL_LIGHT_NUM 2 -#define CC_MAX_POINT_LIGHT_NUM 2 -#define CC_MAX_SPOT_LIGHT_NUM 2 +#define CC_MAX_DIRECTIONAL_LIGHT_NUM 1 +#define CC_MAX_POINT_LIGHT_NUM 1 +#define CC_MAX_SPOT_LIGHT_NUM 1 NS_CC_BEGIN @@ -545,9 +545,9 @@ void GLProgram::bindAttribLocation(const std::string &attributeName, GLuint inde void GLProgram::updateUniforms() { - _builtInUniforms[UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_DIRECTIONAL_LIGHT_NUM); - _builtInUniforms[UNIFORM_ENABLED_POINT_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_POINT_LIGHT_NUM); - _builtInUniforms[UNIFORM_ENABLED_SPOT_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_SPOT_LIGHT_NUM); + //_builtInUniforms[UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_DIRECTIONAL_LIGHT_NUM); + //_builtInUniforms[UNIFORM_ENABLED_POINT_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_POINT_LIGHT_NUM); + //_builtInUniforms[UNIFORM_ENABLED_SPOT_LIGHT_NUM] = glGetUniformLocation(_program, UNIFORM_NAME_ENABLED_SPOT_LIGHT_NUM); _builtInUniforms[UNIFORM_AMBIENT_COLOR] = glGetUniformLocation(_program, UNIFORM_NAME_AMBIENT_COLOR); _builtInUniforms[UNIFORM_P_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_P_MATRIX); _builtInUniforms[UNIFORM_MV_MATRIX] = glGetUniformLocation(_program, UNIFORM_NAME_MV_MATRIX); @@ -565,11 +565,15 @@ void GLProgram::updateUniforms() _builtInUniforms[UNIFORM_SAMPLER2] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER2); _builtInUniforms[UNIFORM_SAMPLER3] = glGetUniformLocation(_program, UNIFORM_NAME_SAMPLER3); - _flags.usesLights = ( - _builtInUniforms[UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM] != -1 || - _builtInUniforms[UNIFORM_ENABLED_POINT_LIGHT_NUM] != -1 || - _builtInUniforms[UNIFORM_ENABLED_SPOT_LIGHT_NUM] != -1 - ); + //_flags.usesLights = ( + // _builtInUniforms[UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM] != -1 || + // _builtInUniforms[UNIFORM_ENABLED_POINT_LIGHT_NUM] != -1 || + // _builtInUniforms[UNIFORM_ENABLED_SPOT_LIGHT_NUM] != -1 + // ); + + _flags.usesLights = CC_MAX_DIRECTIONAL_LIGHT_NUM || + CC_MAX_POINT_LIGHT_NUM || + CC_MAX_SPOT_LIGHT_NUM; _flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1; _flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1; _flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1; @@ -1017,7 +1021,7 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "color"); setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "position"); - setUniformLocationWith4f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14], light->getRange()); + setUniformLocationWith4f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14], 1.0f / light->getRange()); ++enabledPointLightNum; } else @@ -1034,7 +1038,7 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "direction"); setUniformLocationWith3f(glGetUniformLocation(_program, str), dir.x, dir.y, dir.z); sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "params"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), cosf(light->getInnerAngle()), cosf(light->getOuterAngle()), light->getRange()); + setUniformLocationWith3f(glGetUniformLocation(_program, str), cosf(light->getInnerAngle()), cosf(light->getOuterAngle()), 1.0f / light->getRange()); ++enabledSpotLightNum; } } @@ -1042,9 +1046,9 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) } - setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM], enabledDirLightNum); - setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_POINT_LIGHT_NUM], enabledPointLightNum); - setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_SPOT_LIGHT_NUM], enabledSpotLightNum); + //setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_DIRECTIONAL_LIGHT_NUM], enabledDirLightNum); + //setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_POINT_LIGHT_NUM], enabledPointLightNum); + //setUniformLocationWith1i(_builtInUniforms[GLProgram::UNIFORM_ENABLED_SPOT_LIGHT_NUM], enabledSpotLightNum); const auto& ambientColor = scene->getAmbientColor(); setUniformLocationWith4f(_builtInUniforms[GLProgram::UNIFORM_AMBIENT_COLOR], ambientColor.r, ambientColor.g, ambientColor.b, ambientColor.a); } diff --git a/cocos/renderer/ccShader_3D_ColorNormal.frag b/cocos/renderer/ccShader_3D_ColorNormal.frag index 397360bcfb..33e51251ec 100644 --- a/cocos/renderer/ccShader_3D_ColorNormal.frag +++ b/cocos/renderer/ccShader_3D_ColorNormal.frag @@ -2,50 +2,61 @@ const char* cc3D_ColorNormal_frag = STRINGIFY( \n#ifdef GL_ES\n -varying lowp vec4 DestinationColor; -varying mediump vec4 ePosition; -varying mediump vec3 eNormal; -\n#else\n -varying vec4 DestinationColor; -varying vec4 ePosition; -varying vec3 eNormal; + +varying mediump vec2 TextureCoordOut; +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying mediump vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; \n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying mediump vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying mediump vec3 v_normal; + +\n#else\n + +varying vec2 TextureCoordOut; +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; +\n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying vec3 v_normal; + +\n#endif\n + uniform vec4 u_color; \n#if CC_MAX_POINT_LIGHT_NUM\n -void PointLight(int n, vec4 ePosition, vec3 eNormal, inout vec4 intensity) +void PointLight(int n, vec3 normal, inout vec4 intensity) { - if (distance(CC_PointLightSource[n].position.xyz, ePosition.xyz) < CC_PointLightSource[n].position.w) - { - vec3 lightDir = CC_PointLightSource[n].position.xyz - ePosition.xyz; - lightDir = normalize(lightDir); - intensity.xyz += CC_PointLightSource[n].color * max(0.0, dot(lightDir, eNormal)); - } + vec3 dir = v_vertexToPointLightDirection[n]; + vec3 ldir = dir * CC_PointLightSource[n].position.w; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + intensity.xyz += CC_PointLightSource[n].color * max(0.0, dot(normalize(dir), normal)) * attenuation; intensity.w = 1.0; } \n#endif\n \n#if CC_MAX_DIRECTIONAL_LIGHT_NUM\n -void DirectionalLight(int n, vec3 eNormal, inout vec4 intensity) +void DirectionalLight(int n, vec3 normal, inout vec4 intensity) { - intensity.xyz += CC_DirLightSource[n].color * max(0.0, dot(-CC_DirLightSource[n].direction, eNormal)); + intensity.xyz += CC_DirLightSource[n].color * max(0.0, dot(-CC_DirLightSource[n].direction, normal)); intensity.w = 1.0; } \n#endif\n \n#if CC_MAX_SPOT_LIGHT_NUM\n -void SpotLight(int n, vec4 ePosition, vec3 eNormal, inout vec4 intensity) +void SpotLight(int n, vec3 normal, inout vec4 intensity) { - if (distance(CC_SpotLightSource[n].position, ePosition.xyz) < CC_SpotLightSource[n].params.z) - { - vec3 lightDir = CC_SpotLightSource[n].position - ePosition.xyz; - lightDir = normalize(lightDir); - float spotDot = dot(normalize(lightDir), -CC_SpotLightSource[n].direction); - float innerCos = CC_SpotLightSource[n].params.x; - float outerCos = CC_SpotLightSource[n].params.y; - float factor = smoothstep(outerCos, innerCos, spotDot); - intensity.xyz += CC_SpotLightSource[n].color * max(0.0, dot(lightDir, eNormal)) * factor; - } + vec3 dir = v_vertexToPointLightDirection[n]; + vec3 ldir = dir * CC_SpotLightSource[n].position.z; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + float spotDot = dot(normalize(dir), -CC_SpotLightSource[n].direction); + float innerCos = CC_SpotLightSource[n].params.x; + float outerCos = CC_SpotLightSource[n].params.y; + float factor = smoothstep(outerCos, innerCos, spotDot); + intensity.xyz += CC_SpotLightSource[n].color * max(0.0, dot(normalize(dir), normal)) * factor * attenuation; intensity.w = 1.0; } \n#endif\n @@ -54,12 +65,12 @@ void main(void) { vec4 intensity = vec4(0.0); \n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n - vec3 normal = normalize(eNormal); + vec3 normal = normalize(v_normal); \n#endif\n \n#if CC_MAX_DIRECTIONAL_LIGHT_NUM\n - - for (int i = 0; i < CC_EnabledDirLightNum; ++i) + + for (int i = 0; i < CC_MAX_DIRECTIONAL_LIGHT_NUM; ++i) { DirectionalLight(i, normal, intensity); } @@ -68,25 +79,27 @@ void main(void) \n#if CC_MAX_POINT_LIGHT_NUM\n - for (int i = 0; i < CC_EnabledPointLightNum; ++i) + for (int i = 0; i < CC_MAX_POINT_LIGHT_NUM; ++i) { - PointLight(i, ePosition, normal, intensity); + PointLight(i, normal, intensity); } \n#endif\n \n#if CC_MAX_SPOT_LIGHT_NUM\n - for (int i = 0; i < CC_EnabledSpotLightNum; ++i) + for (int i = 0; i < CC_MAX_SPOT_LIGHT_NUM; ++i) { - SpotLight(i, ePosition, normal, intensity); + SpotLight(i, normal, intensity); } \n#endif\n - if (intensity.w == 0.0) - gl_FragColor = u_color; - else - gl_FragColor = u_color * (CC_AmbientColor + intensity); +\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n + gl_FragColor = u_color * (CC_AmbientColor + intensity); +\n#else\n + gl_FragColor = u_color; +\n#endif\n + } ); diff --git a/cocos/renderer/ccShader_3D_ColorNormalTex.frag b/cocos/renderer/ccShader_3D_ColorNormalTex.frag index cdd9ebe393..c35b12120f 100644 --- a/cocos/renderer/ccShader_3D_ColorNormalTex.frag +++ b/cocos/renderer/ccShader_3D_ColorNormalTex.frag @@ -2,50 +2,61 @@ const char* cc3D_ColorNormalTex_frag = STRINGIFY( \n#ifdef GL_ES\n + varying mediump vec2 TextureCoordOut; -varying mediump vec4 ePosition; -varying mediump vec3 eNormal; -\n#else\n -varying vec2 TextureCoordOut; -varying vec4 ePosition; -varying vec3 eNormal; +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying mediump vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; \n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying mediump vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying mediump vec3 v_normal; + +\n#else\n + +varying vec2 TextureCoordOut; +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; +\n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying vec3 v_normal; + +\n#endif\n + uniform vec4 u_color; \n#if CC_MAX_POINT_LIGHT_NUM\n -void PointLight(int n, vec4 ePosition, vec3 eNormal, inout vec4 intensity) +void PointLight(int n, vec3 normal, inout vec4 intensity) { - if (distance(CC_PointLightSource[n].position.xyz, ePosition.xyz) < CC_PointLightSource[n].position.w) - { - vec3 lightDir = CC_PointLightSource[n].position.xyz - ePosition.xyz; - lightDir = normalize(lightDir); - intensity.xyz += CC_PointLightSource[n].color * max(0.0, dot(lightDir, eNormal)); - } + vec3 dir = v_vertexToPointLightDirection[n]; + vec3 ldir = dir * CC_PointLightSource[n].position.w; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + intensity.xyz += CC_PointLightSource[n].color * max(0.0, dot(normalize(dir), normal)) * attenuation; intensity.w = 1.0; } \n#endif\n \n#if CC_MAX_DIRECTIONAL_LIGHT_NUM\n -void DirectionalLight(int n, vec3 eNormal, inout vec4 intensity) +void DirectionalLight(int n, vec3 normal, inout vec4 intensity) { - intensity.xyz += CC_DirLightSource[n].color * max(0.0, dot(-CC_DirLightSource[n].direction, eNormal)); + intensity.xyz += CC_DirLightSource[n].color * max(0.0, dot(-CC_DirLightSource[n].direction, normal)); intensity.w = 1.0; } \n#endif\n \n#if CC_MAX_SPOT_LIGHT_NUM\n -void SpotLight(int n, vec4 ePosition, vec3 eNormal, inout vec4 intensity) +void SpotLight(int n, vec3 normal, inout vec4 intensity) { - if (distance(CC_SpotLightSource[n].position, ePosition.xyz) < CC_SpotLightSource[n].params.z) - { - vec3 lightDir = CC_SpotLightSource[n].position - ePosition.xyz; - lightDir = normalize(lightDir); - float spotDot = dot(normalize(lightDir), -CC_SpotLightSource[n].direction); - float innerCos = CC_SpotLightSource[n].params.x; - float outerCos = CC_SpotLightSource[n].params.y; - float factor = smoothstep(outerCos, innerCos, spotDot); - intensity.xyz += CC_SpotLightSource[n].color * max(0.0, dot(lightDir, eNormal)) * factor; - } + vec3 dir = v_vertexToPointLightDirection[n]; + vec3 ldir = dir * CC_SpotLightSource[n].position.z; + float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); + float spotDot = dot(normalize(dir), -CC_SpotLightSource[n].direction); + float innerCos = CC_SpotLightSource[n].params.x; + float outerCos = CC_SpotLightSource[n].params.y; + float factor = smoothstep(outerCos, innerCos, spotDot); + intensity.xyz += CC_SpotLightSource[n].color * max(0.0, dot(normalize(dir), normal)) * factor * attenuation; intensity.w = 1.0; } \n#endif\n @@ -54,12 +65,12 @@ void main(void) { vec4 intensity = vec4(0.0); \n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n - vec3 normal = normalize(eNormal); + vec3 normal = normalize(v_normal); \n#endif\n \n#if CC_MAX_DIRECTIONAL_LIGHT_NUM\n - - for (int i = 0; i < CC_EnabledDirLightNum; ++i) + + for (int i = 0; i < CC_MAX_DIRECTIONAL_LIGHT_NUM; ++i) { DirectionalLight(i, normal, intensity); } @@ -68,25 +79,27 @@ void main(void) \n#if CC_MAX_POINT_LIGHT_NUM\n - for (int i = 0; i < CC_EnabledPointLightNum; ++i) + for (int i = 0; i < CC_MAX_POINT_LIGHT_NUM; ++i) { - PointLight(i, ePosition, normal, intensity); + PointLight(i, normal, intensity); } \n#endif\n \n#if CC_MAX_SPOT_LIGHT_NUM\n - for (int i = 0; i < CC_EnabledSpotLightNum; ++i) + for (int i = 0; i < CC_MAX_SPOT_LIGHT_NUM; ++i) { - SpotLight(i, ePosition, normal, intensity); + SpotLight(i, normal, intensity); } \n#endif\n - if (intensity.w == 0.0) - gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color; - else - gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color * (CC_AmbientColor + intensity); +\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n + gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color * (CC_AmbientColor + intensity); +\n#else\n + gl_FragColor = texture2D(CC_Texture0, TextureCoordOut) * u_color; +\n#endif\n + } ); diff --git a/cocos/renderer/ccShader_3D_PositionNormalTex.vert b/cocos/renderer/ccShader_3D_PositionNormalTex.vert index 550b64e56e..4b1f489d22 100644 --- a/cocos/renderer/ccShader_3D_PositionNormalTex.vert +++ b/cocos/renderer/ccShader_3D_PositionNormalTex.vert @@ -5,15 +5,36 @@ attribute vec4 a_position; attribute vec2 a_texCoord; attribute vec3 a_normal; varying vec2 TextureCoordOut; -varying vec4 ePosition; -varying vec3 eNormal; + +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; +\n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying vec3 v_normal; void main(void) { -\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n - eNormal = CC_NormalMatrix * a_normal; + vec4 ePosition = CC_MVMatrix * a_position; +\n#if (CC_MAX_POINT_LIGHT_NUM > 0)\n + for (int i = 0; i < CC_MAX_POINT_LIGHT_NUM; ++i) + { + v_vertexToPointLightDirection[i] = CC_PointLightSource[i].position.xyz - ePosition.xyz; + } \n#endif\n - ePosition = CC_MVMatrix * a_position; + +\n#if (CC_MAX_SPOT_LIGHT_NUM > 0)\n + for (int i = 0; i < CC_MAX_SPOT_LIGHT_NUM; ++i) + { + v_vertexToSpotLightDirection[i] = CC_SpotLightSource[i].position.xyz - ePosition.xyz; + } +\n#endif\n + +\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n + v_normal = CC_NormalMatrix * a_normal; +\n#endif\n + TextureCoordOut = a_texCoord; TextureCoordOut.y = 1.0 - TextureCoordOut.y; gl_Position = CC_PMatrix * ePosition; @@ -36,8 +57,14 @@ uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; // Varyings varying vec2 TextureCoordOut; -varying vec4 ePosition; -varying vec3 eNormal; + +\n#if CC_MAX_POINT_LIGHT_NUM\n +varying vec3 v_vertexToPointLightDirection[CC_MAX_POINT_LIGHT_NUM]; +\n#endif\n +\n#if CC_MAX_SPOT_LIGHT_NUM\n +varying vec3 v_vertexToSpotLightDirection[CC_MAX_SPOT_LIGHT_NUM]; +\n#endif\n +varying vec3 v_normal; void getPositionAndNormal(out vec4 position, out vec3 normal) { @@ -86,7 +113,7 @@ void getPositionAndNormal(out vec4 position, out vec3 normal) position.w = p.w; \n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n - vec4 n = vec4(a_normal, 0.0); + vec3 n = vec4(a_normal, 0.0); normal.x = dot(n, matrixPalette1); normal.y = dot(n, matrixPalette2); normal.z = dot(n, matrixPalette3); @@ -99,10 +126,25 @@ void main() vec3 normal; getPositionAndNormal(position, normal); -\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n - eNormal = CC_NormalMatrix * normal; + vec4 ePosition = CC_MVMatrix * position; +\n#if (CC_MAX_POINT_LIGHT_NUM > 0)\n + for (int i = 0; i < CC_MAX_POINT_LIGHT_NUM; ++i) + { + v_vertexToPointLightDirection[i] = CC_PointLightSource[i].position.xyz- ePosition.xyz; + } \n#endif\n - ePosition = CC_MVMatrix * position; + +\n#if (CC_MAX_SPOT_LIGHT_NUM > 0)\n + for (int i = 0; i < CC_MAX_SPOT_LIGHT_NUM; ++i) + { + v_vertexToSpotLightDirection[i] = CC_SpotLightSource[i].position.xyz - ePosition.xyz; + } +\n#endif\n + +\n#if (CC_MAX_DIRECTIONAL_LIGHT_NUM || CC_MAX_POINT_LIGHT_NUM || CC_MAX_SPOT_LIGHT_NUM)\n + v_normal = CC_NormalMatrix * normal; +\n#endif\n + TextureCoordOut = a_texCoord; TextureCoordOut.y = 1.0 - TextureCoordOut.y; gl_Position = CC_PMatrix * ePosition; From 682bcf9755331c797f0710d3da0a7d59b0331892 Mon Sep 17 00:00:00 2001 From: songchengjiang Date: Wed, 27 Aug 2014 16:28:53 +0800 Subject: [PATCH 2/3] Tab Format --- cocos/renderer/CCGLProgram.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cocos/renderer/CCGLProgram.cpp b/cocos/renderer/CCGLProgram.cpp index 95f6083d9c..c0b2cc9988 100644 --- a/cocos/renderer/CCGLProgram.cpp +++ b/cocos/renderer/CCGLProgram.cpp @@ -571,9 +571,9 @@ void GLProgram::updateUniforms() // _builtInUniforms[UNIFORM_ENABLED_SPOT_LIGHT_NUM] != -1 // ); - _flags.usesLights = CC_MAX_DIRECTIONAL_LIGHT_NUM || - CC_MAX_POINT_LIGHT_NUM || - CC_MAX_SPOT_LIGHT_NUM; + _flags.usesLights = CC_MAX_DIRECTIONAL_LIGHT_NUM || + CC_MAX_POINT_LIGHT_NUM || + CC_MAX_SPOT_LIGHT_NUM; _flags.usesP = _builtInUniforms[UNIFORM_P_MATRIX] != -1; _flags.usesMV = _builtInUniforms[UNIFORM_MV_MATRIX] != -1; _flags.usesMVP = _builtInUniforms[UNIFORM_MVP_MATRIX] != -1; From 731d1165c333683daf709146742ac0618b23e4b8 Mon Sep 17 00:00:00 2001 From: songchengjiang Date: Wed, 27 Aug 2014 17:09:20 +0800 Subject: [PATCH 3/3] Spot Light Shader optimization --- cocos/renderer/CCGLProgram.cpp | 78 +++++++++---------- cocos/renderer/ccShader_3D_ColorNormal.frag | 4 +- .../renderer/ccShader_3D_ColorNormalTex.frag | 4 +- .../Classes/LightTest/LightTestDemo.cpp | 4 +- tests/cpp-tests/Classes/controller.cpp | 1 + .../proj.win32/cpp-tests.vcxproj.filters | 9 +++ 6 files changed, 54 insertions(+), 46 deletions(-) diff --git a/cocos/renderer/CCGLProgram.cpp b/cocos/renderer/CCGLProgram.cpp index c0b2cc9988..7a3547a2aa 100644 --- a/cocos/renderer/CCGLProgram.cpp +++ b/cocos/renderer/CCGLProgram.cpp @@ -998,51 +998,49 @@ void GLProgram::setUniformsForBuiltins(const Mat4 &matrixMV) for (unsigned int i = 0; i < lights.size(); ++i) { Light3D *light = lights[i]; - if (light->getEnabled()) + Color3B col = light->getDisplayedColor(); + if (!light->getEnabled()) { - if (light->getLightType() == Light3D::DIRECTIONAL) + col = Color3B::BLACK; + } + if (light->getLightType() == Light3D::DIRECTIONAL) + { + CCASSERT(enabledDirLightNum < CC_MAX_DIRECTIONAL_LIGHT_NUM, ""); + Vec3 dir = light->getWorldDirection(); + dir.normalize(); + sprintf(str, "CC_DirLightSource[%d].%s", enabledDirLightNum, "color"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); + sprintf(str, "CC_DirLightSource[%d].%s", enabledDirLightNum, "direction"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), dir.x, dir.y, dir.z); + ++enabledDirLightNum; + } + else + if (light->getLightType() == Light3D::POINT) { - CCASSERT(enabledDirLightNum < CC_MAX_DIRECTIONAL_LIGHT_NUM, ""); - const Color3B &col = light->getDisplayedColor(); - Vec3 dir = light->getWorldDirection(); - dir.normalize(); - sprintf(str, "CC_DirLightSource[%d].%s", enabledDirLightNum, "color"); + CCASSERT(enabledPointLightNum < CC_MAX_POINT_LIGHT_NUM, ""); + Mat4 mat= light->getNodeToWorldTransform(); + sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "color"); setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); - sprintf(str, "CC_DirLightSource[%d].%s", enabledDirLightNum, "direction"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), dir.x, dir.y, dir.z); - ++enabledDirLightNum; + sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "position"); + setUniformLocationWith4f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14], 1.0f / light->getRange()); + ++enabledPointLightNum; } else - if (light->getLightType() == Light3D::POINT) - { - CCASSERT(enabledPointLightNum < CC_MAX_POINT_LIGHT_NUM, ""); - const Color3B &col = light->getDisplayedColor(); - Mat4 mat= light->getNodeToWorldTransform(); - sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "color"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); - sprintf(str, "CC_PointLightSource[%d].%s", enabledPointLightNum, "position"); - setUniformLocationWith4f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14], 1.0f / light->getRange()); - ++enabledPointLightNum; - } - else - { - CCASSERT(enabledSpotLightNum < CC_MAX_SPOT_LIGHT_NUM, ""); - const Color3B &col = light->getDisplayedColor(); - Vec3 dir = light->getWorldDirection(); - dir.normalize(); - Mat4 mat= light->getNodeToWorldTransform(); - sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "color"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); - sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "position"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14]); - sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "direction"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), dir.x, dir.y, dir.z); - sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "params"); - setUniformLocationWith3f(glGetUniformLocation(_program, str), cosf(light->getInnerAngle()), cosf(light->getOuterAngle()), 1.0f / light->getRange()); - ++enabledSpotLightNum; - } - } - + { + CCASSERT(enabledSpotLightNum < CC_MAX_SPOT_LIGHT_NUM, ""); + Vec3 dir = light->getWorldDirection(); + dir.normalize(); + Mat4 mat= light->getNodeToWorldTransform(); + sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "color"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), col.r / 255.0f, col.g / 255.0f, col.b / 255.0f); + sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "position"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), mat.m[12], mat.m[13], mat.m[14]); + sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "direction"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), dir.x, dir.y, dir.z); + sprintf(str, "CC_SpotLightSource[%d].%s", enabledSpotLightNum, "params"); + setUniformLocationWith3f(glGetUniformLocation(_program, str), cosf(light->getInnerAngle()), cosf(light->getOuterAngle()), 1.0f / light->getRange()); + ++enabledSpotLightNum; + } } diff --git a/cocos/renderer/ccShader_3D_ColorNormal.frag b/cocos/renderer/ccShader_3D_ColorNormal.frag index 33e51251ec..efc14d8dd9 100644 --- a/cocos/renderer/ccShader_3D_ColorNormal.frag +++ b/cocos/renderer/ccShader_3D_ColorNormal.frag @@ -49,8 +49,8 @@ void DirectionalLight(int n, vec3 normal, inout vec4 intensity) \n#if CC_MAX_SPOT_LIGHT_NUM\n void SpotLight(int n, vec3 normal, inout vec4 intensity) { - vec3 dir = v_vertexToPointLightDirection[n]; - vec3 ldir = dir * CC_SpotLightSource[n].position.z; + vec3 dir = v_vertexToSpotLightDirection[n]; + vec3 ldir = dir * CC_SpotLightSource[n].params.z; float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); float spotDot = dot(normalize(dir), -CC_SpotLightSource[n].direction); float innerCos = CC_SpotLightSource[n].params.x; diff --git a/cocos/renderer/ccShader_3D_ColorNormalTex.frag b/cocos/renderer/ccShader_3D_ColorNormalTex.frag index c35b12120f..d36e7f4fbd 100644 --- a/cocos/renderer/ccShader_3D_ColorNormalTex.frag +++ b/cocos/renderer/ccShader_3D_ColorNormalTex.frag @@ -49,8 +49,8 @@ void DirectionalLight(int n, vec3 normal, inout vec4 intensity) \n#if CC_MAX_SPOT_LIGHT_NUM\n void SpotLight(int n, vec3 normal, inout vec4 intensity) { - vec3 dir = v_vertexToPointLightDirection[n]; - vec3 ldir = dir * CC_SpotLightSource[n].position.z; + vec3 dir = v_vertexToSpotLightDirection[n]; + vec3 ldir = dir * CC_SpotLightSource[n].params.z; float attenuation = clamp(1.0 - dot(ldir, ldir), 0.0, 1.0); float spotDot = dot(normalize(dir), -CC_SpotLightSource[n].direction); float innerCos = CC_SpotLightSource[n].params.x; diff --git a/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp b/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp index add7e4b8e5..d6c001fdb8 100644 --- a/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp +++ b/tests/cpp-tests/Classes/LightTest/LightTestDemo.cpp @@ -210,13 +210,13 @@ void LightTestDemo::addLights() addChild(_directionalLight); _directionalLight->setCameraMask(2); - _pointLight = Light3D::CreatePointLight(Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 1000.0f); + _pointLight = Light3D::CreatePointLight(Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 10000.0f); _pointLight->retain(); _pointLight->setEnabled(false); addChild(_pointLight); _pointLight->setCameraMask(2); - _spotLight = Light3D::CreateSpotLight(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 0.1, 0.3, 1000.0f); + _spotLight = Light3D::CreateSpotLight(Vec3(-1.0f, -1.0f, 0.0f), Vec3(0.0f, 0.0f, 0.0f), Color3B(200, 200, 200), 0.0, 0.5, 10000.0f); _spotLight->retain(); _spotLight->setEnabled(false); addChild(_spotLight); diff --git a/tests/cpp-tests/Classes/controller.cpp b/tests/cpp-tests/Classes/controller.cpp index 89585f73f2..830f78b943 100644 --- a/tests/cpp-tests/Classes/controller.cpp +++ b/tests/cpp-tests/Classes/controller.cpp @@ -78,6 +78,7 @@ Controller g_aTestNames[] = { { "Node: Spine", []() { return new SpineTestScene(); } }, { "Node: Sprite", [](){return new SpriteTestScene(); } }, { "Node: Sprite3D", [](){ return new Sprite3DTestScene(); }}, + { "Node: LightTest", [](){ return new LightTestScene(); }}, { "Node: TileMap", [](){return new TileMapTestScene(); } }, #if CC_TARGET_PLATFORM != CC_PLATFORM_WP8 { "Node: FastTileMap", [](){return new TileMapTestSceneNew(); } }, diff --git a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters index e815660d53..b985b58998 100644 --- a/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters +++ b/tests/cpp-tests/proj.win32/cpp-tests.vcxproj.filters @@ -331,6 +331,9 @@ {7f85be1c-98c5-4412-afc5-6f39ae1452a7} + + {9befe67d-c725-4807-885f-edee45f95951} + @@ -867,6 +870,9 @@ Classes\Sprite3DTest + + Classes\LightTest + @@ -1601,5 +1607,8 @@ Classes\Sprite3DTest + + Classes\LightTest + \ No newline at end of file