当前位置: 首页 > 科技观察

《捕鱼达人3》Cocos引擎3D详解:鱼体波光处理

时间:2023-03-12 02:18:10 科技观察

在上一节中,我们已经掌握了如何使用Cocos2d-x加载鱼模型和播放鱼动画。在本节中,我们将学习如何为鱼模型添加闪光,使其看起来像是在海水中游泳。通过贴图动画实现给模型增加波浪光的感觉。其原理是给模型添加一个贴图,循环移动贴图地址的UV坐标,使贴在模型表面的贴图会根据UV值发生变化,从而产生贴图移动的效果。现在让我们实际做这个效果。我们需要使用着色器文件UVAnimation.vsh和UVAnimation.fsh,它们位于Resources\3D目录中。UVAnimation.vsh是模型骨骼动画的计算Shader,UV动画的效果在UVAnimation.fsh中处理:uniformsampler2Du_texture1;TextureUVvaluevoidmain(void){//UV动画是通过移动UV值Wavelightimagecaustics.png,它是一张黑白图像,用于对模型进行增加颜色值操作,本例中,黑色区域的颜色值为0,添加鱼的原纹理颜色值不变,而白色区域的值大于0,添加到原纹理颜色后会有提亮的效果鱼的价值。我们把这张图片放在项目的Resources\3D目录下。我们在FishLayer中添加一个可变的UV值:Vec2_lightani;在FishLayer::init函数中,我们将上面写的vsh、fsh等组合成一个鱼模型可以使用的Shader,使用://获取文件管理器autofileUtiles=FileUtils::getInstance();//加载对应的Shader文件//加载UVAnimation.vsh并获取文件内容stringautovertexFilePath=fileUtiles->fullPathForFilename("UVAnimation.vsh");autovertSource=fileUtiles->getStringFromFile(vertexFilePath);//加载UVAnimation.fsh并获取文件内容字符串autofragmentFilePath=fileUtiles->fullPathForFilename("UVAnimation.fsh");autofragSource=fileUtiles->getStringFromFile(fragmentFilePath);//将vsh和fsh组装成一个完整的Shader文件。autoglprogram=GLProgram::createWithByteArrays(vertSource.c_str(),fragSource.c_str());//从Shader文件中创建这个Shaderautoglprogramstate=GLProgramState::getOrCreateWithGLProgram(glprogram);//设置使用的Shader_sprite->setGLProgramState(glprogramstate)bythesprite);//创建乌龟使用的纹理。autotextrue1=Director::getInstance()->getTextureCache()->addImage("tortoise.png");//设置纹理为Shader中的变量值u_texture1glprogramstate->setUniformTexture("u_texture1",texture1);//创建波浪图。autotextrue2=Director::getInstance()->getTextureCache()->addImage("caustics.png");//设置纹理为Shader中的变量值u_lightTextureglprogramstate->setUniformTexture("u_lightTexture",texttrue2);//注意,对于波浪光照贴图,我们希望它在执行UV动画时能产生四面连续的效果,必须将它的贴图UV寻址方式设置为GL_REPEAT。Texture2D::TexParams.RepeatParams;tRepeatParams.magFilter=GL_LINEAR_MIPMAP_LINEAR;tRepeatParams.minFilter=GL_LINEAR;tRepeatParams.wrapS=GL_REPEAT;tRepeatParams.wrapT=GL_REPEAT;tRepeatParams.wrapT=GL_REPEAT;textrue2->setTexParameter在这里/这里有波光色;设置为白色。Vec4tLightColor(1.0,1.0,1.0,1.0);glprogramstate->setUniformVec4("v_LightColor",tLightColor);//下面一段是为了让我们自定义的Shader与我们的模型顶点组织相匹配。模型的顶点数据一般包括位置、法线、颜色、纹理和骨骼绑定信息。Shader需要将对应的内部顶点属性通道与模型对应的顶点属性数据进行绑定,才能正确显示顶点。longoffset=0;autoattributeCount=_sprite->getMesh()->getMeshVertexAttribCount();for(autok=0;kgetMesh()->getMeshVertexAttribute(k);glprogramstate->setVertexAttribPointer(s_attributeNames[meshattribute.vertexAttribute],meshattribute.size,meshattribute.type,GL_FALSE,_sprite->getMesh()->getVertexSizeInBytes(),(GLvoid*)offset);offset+=meshattribute.attribSizeBytes;}//uv滚动初始值设置为0_lightani.x=_lightani.y=0;之后我们重新加载FishLayer的draw函数,添加UV值的变化处理和设置。voidFishLayer::draw(Renderer*renderer,constMat4&transform,uint32_tflags){if(_sprite){autoglprogramstate=_sprite->getGLProgramState();if(glprogramstate){_lightani.x+=0.01;if(_lightani.x>1.0){_lightani.x-=1.0;}_lightani.y+=0.01;if(_lightani.y>1.0){_lightani.y-=1.0;}glprogramstate->setUniformVec2("v_animLight",_lightani);}}Node::draw(renderer,transform,flags);}这样,我们就完成了对鱼的波浪光处理。