diff --git a/build/cocos2d_libs.xcodeproj/project.pbxproj b/build/cocos2d_libs.xcodeproj/project.pbxproj index 8622205d1b..7c92ea00ad 100644 --- a/build/cocos2d_libs.xcodeproj/project.pbxproj +++ b/build/cocos2d_libs.xcodeproj/project.pbxproj @@ -2800,6 +2800,9 @@ B3AF019F1842FBA400A98B85 /* b2MotorJoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = b2MotorJoint.h; sourceTree = ""; }; B60C5BD219AC68B10056FBDE /* CCBillBoard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCBillBoard.cpp; sourceTree = ""; }; B60C5BD319AC68B10056FBDE /* CCBillBoard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCBillBoard.h; sourceTree = ""; }; + B67C624319D4186F00F11FC6 /* ccShader_3D_ColorNormal.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_ColorNormal.frag; sourceTree = ""; }; + B67C624419D4186F00F11FC6 /* ccShader_3D_ColorNormalTex.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_ColorNormalTex.frag; sourceTree = ""; }; + B67C624519D4186F00F11FC6 /* ccShader_3D_PositionNormalTex.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = ccShader_3D_PositionNormalTex.vert; sourceTree = ""; }; B6C039DB19C95E03007207DC /* CCLight3D.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CCLight3D.cpp; sourceTree = ""; }; B6C039DC19C95E03007207DC /* CCLight3D.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CCLight3D.h; sourceTree = ""; }; ED9C6A9218599AD8000A5232 /* CCNodeGrid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; path = CCNodeGrid.cpp; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.cpp; }; @@ -4484,6 +4487,9 @@ 5034CA5D191D591900CE6051 /* shaders */ = { isa = PBXGroup; children = ( + B67C624319D4186F00F11FC6 /* ccShader_3D_ColorNormal.frag */, + B67C624419D4186F00F11FC6 /* ccShader_3D_ColorNormalTex.frag */, + B67C624519D4186F00F11FC6 /* ccShader_3D_PositionNormalTex.vert */, B29594AF1926D5D9003EEF37 /* ccShader_3D_Color.frag */, B29594B01926D5D9003EEF37 /* ccShader_3D_ColorTex.frag */, B29594B11926D5D9003EEF37 /* ccShader_3D_PositionTex.vert */, diff --git a/cocos/3d/CCSprite3D.cpp b/cocos/3d/CCSprite3D.cpp index 458e512f11..48c8cc0207 100644 --- a/cocos/3d/CCSprite3D.cpp +++ b/cocos/3d/CCSprite3D.cpp @@ -526,10 +526,12 @@ void Sprite3D::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) //check light and determine the shader used const auto& lights = Director::getInstance()->getRunningScene()->getLights(); bool usingLight = false; + Color4F ambient(0.f, 0.f, 0.f, 1.f); for (const auto light : lights) { - usingLight = ((unsigned short)light->getLightFlag() & _lightMask) > 0; - if (usingLight) - break; + if (((unsigned short)light->getLightFlag() & _lightMask) > 0) + { + usingLight = true; + } } if (usingLight != _shaderUsingLight) genGLProgramState(); diff --git a/cocos/renderer/CCMeshCommand.cpp b/cocos/renderer/CCMeshCommand.cpp index 187aaf751c..7828472968 100644 --- a/cocos/renderer/CCMeshCommand.cpp +++ b/cocos/renderer/CCMeshCommand.cpp @@ -252,7 +252,8 @@ void MeshCommand::batchDraw() } - setLightUniforms(); + if (Director::getInstance()->getRunningScene()->getLights().size() > 0) + setLightUniforms(); _glProgramState->applyGLProgram(_mv); _glProgramState->applyUniforms(); @@ -294,7 +295,8 @@ void MeshCommand::execute() } - setLightUniforms(); + if (Director::getInstance()->getRunningScene()->getLights().size() > 0) + setLightUniforms(); _glProgramState->apply(_mv); @@ -351,24 +353,22 @@ void MeshCommand::setLightUniforms() int maxDirLight = conf->getMaxSupportDirLightInShader(); int maxPointLight = conf->getMaxSupportPointLightInShader(); int maxSpotLight = conf->getMaxSupportSpotLightInShader(); - if (scene) + auto &lights = scene->getLights(); + if (_glProgramState->getVertexAttribsFlags() & GLProgram::VERTEX_ATTRIB_NORMAL) { - auto &lights = scene->getLights(); GLint enabledDirLightNum = 0; GLint enabledPointLightNum = 0; GLint enabledSpotLightNum = 0; Vec3 ambientColor; - for (unsigned int i = 0; i < lights.size(); ++i) + for (const auto& light : lights) { - BaseLight3D *light = lights[i]; - bool useLight = light->isEnabled(); - useLight = useLight && ((unsigned short)light->getLightFlag() & _lightMask); + bool useLight = light->isEnabled() && ((unsigned short)light->getLightFlag() & _lightMask); if (useLight) { float intensity = light->getIntensity(); switch (light->getLightType()) { - case LightType::DIRECTIONAL: + case LightType::DIRECTIONAL: { CCASSERT(enabledDirLightNum < maxDirLight, ""); DirectionLight3D *dirLight = static_cast(light); @@ -379,8 +379,8 @@ void MeshCommand::setLightUniforms() _glProgramState->setUniformVec3(s_dirLightUniformNames[enabledDirLightNum].dir, dir); ++enabledDirLightNum; } - break; - case LightType::POINT: + break; + case LightType::POINT: { CCASSERT(enabledPointLightNum < maxPointLight, ""); PointLight3D *pointLight = static_cast(light); @@ -391,8 +391,8 @@ void MeshCommand::setLightUniforms() _glProgramState->setUniformFloat(s_pointLightUniformNames[enabledPointLightNum].rangeInverse, 1.0f / pointLight->getRange()); ++enabledPointLightNum; } - break; - case LightType::SPOT: + break; + case LightType::SPOT: { CCASSERT(enabledSpotLightNum < maxSpotLight, ""); SpotLight3D *spotLight = static_cast(light); @@ -408,33 +408,33 @@ void MeshCommand::setLightUniforms() _glProgramState->setUniformFloat(s_spotLightUniformNames[enabledSpotLightNum].rangeInverse, 1.0f / spotLight->getRange()); ++enabledSpotLightNum; } - break; - case LightType::AMBIENT: + break; + case LightType::AMBIENT: { AmbientLight3D *ambLight = static_cast(light); const Color3B &col = ambLight->getDisplayedColor(); ambientColor += Vec3(col.r / 255.0f * intensity, col.g / 255.0f * intensity, col.b / 255.0f * intensity); } - break; - default: - break; + break; + default: + break; } } } - + for (unsigned short i = enabledDirLightNum; i < maxDirLight; ++i) { _glProgramState->setUniformVec3(s_dirLightUniformNames[i].color, Vec3::ZERO); _glProgramState->setUniformVec3(s_dirLightUniformNames[i].dir, Vec3::ZERO); } - + for (unsigned short i = enabledPointLightNum; i < maxPointLight; ++i) { _glProgramState->setUniformVec3(s_pointLightUniformNames[i].color, Vec3::ZERO); _glProgramState->setUniformVec3(s_pointLightUniformNames[i].position, Vec3::ZERO); _glProgramState->setUniformFloat(s_pointLightUniformNames[i].rangeInverse, 0.0f); } - + for (unsigned short i = enabledSpotLightNum; i < maxSpotLight; ++i) { _glProgramState->setUniformVec3(s_spotLightUniformNames[i].color, Vec3::ZERO); @@ -444,9 +444,34 @@ void MeshCommand::setLightUniforms() _glProgramState->setUniformFloat(s_spotLightUniformNames[i].outerAngleCos, 0.0f); _glProgramState->setUniformFloat(s_spotLightUniformNames[i].rangeInverse, 0.0f); } - + _glProgramState->setUniformVec3("u_AmbientLightSourceColor", ambientColor); } + else // normal does not exist + { + Vec3 ambient(0.0f, 0.0f, 0.0f); + bool hasAmbient; + for (const auto& light : lights) + { + if (light->getLightType() == LightType::AMBIENT) + { + bool useLight = light->isEnabled() && ((unsigned short)light->getLightFlag() & _lightMask); + if (useLight) + { + hasAmbient = true; + const Color3B &col = light->getDisplayedColor(); + ambient.x += col.r * light->getIntensity(); + ambient.y += col.g * light->getIntensity(); + ambient.z += col.b * light->getIntensity(); + } + } + } + if (hasAmbient) + { + ambient.x /= 255.f; ambient.y /= 255.f; ambient.z /= 255.f; + } + _glProgramState->setUniformVec4("u_color", Vec4(_displayColor.x * ambient.x, _displayColor.y * ambient.y, _displayColor.z * ambient.z, _displayColor.w)); + } } void MeshCommand::setLightUniformNames()