基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型
使用Subroutine在shader中封装不同的函数,在CPU端选择调用那个函数
效果如下图所示
左侧:环境光
中间:环境光 + 漫反射
右侧:环境光 + 漫反射 + 高光
1、Subroutine 在shader中的内容
subroutinevec4SurfaceColor();subroutineuniformSurfaceColorU_SurfaceColor;
定义SurfaceColor()函数类型
环境光函数
//Ambientsubroutine(SurfaceColor)vec4Ambient(){//Ambientvec4M_AmbientLightColor=vec4(0.2,0.2,0.2,1.0);vec4M_AmbientMaterial=vec4(0.2,0.2,0.2,1.0);vec4ambientColor=M_AmbientLightColor*M_AmbientMaterial;returnambientColor;}
环境光+漫反射函数
subroutine(SurfaceColor)vec4Diffuse(){//Ambientvec4M_AmbientLightColor=vec4(0.2,0.2,0.2,1.0);vec4M_AmbientMaterial=vec4(0.2,0.2,0.2,1.0);vec4ambientColor=M_AmbientLightColor*M_AmbientMaterial;//Diffusevec3M_LightPos=vec3(10.0,10.0,0.0);vec3LightNormal=normalize(M_LightPos);//指向光源的单位向量vec3NormalNormal=normalize(M_normal);//法线的单位向量//点乘获取光照强度vec4M_DiffuseLightColor=vec4(1.0,1.0,1.0,1.0);vec4M_DiffuseMaterial=vec4(0.8,0.8,0.8,1.0);vec4diffuseColor=M_DiffuseLightColor*M_DiffuseMaterial*max(0.0,dot(NormalNormal,LightNormal));returnambientColor+texture2D(U_MainTexture,M_coord)*diffuseColor;}
镜面反射函数
subroutine(SurfaceColor)vec4Specular(){//Ambientvec4M_AmbientLightColor=vec4(0.2,0.2,0.2,1.0);vec4M_AmbientMaterial=vec4(0.2,0.2,0.2,1.0);vec4ambientColor=M_AmbientLightColor*M_AmbientMaterial;//Diffusevec3M_LightPos=vec3(10.0,10.0,0.0);vec3LightNormal=normalize(M_LightPos);//指向光源的单位向量vec3NormalNormal=normalize(M_normal);//法线的单位向量//点乘获取光照强度vec4M_DiffuseLightColor=vec4(1.0,1.0,1.0,1.0);vec4M_DiffuseMaterial=vec4(0.8,0.8,0.8,1.0);vec4diffuseColor=M_DiffuseLightColor*M_DiffuseMaterial*max(0.0,dot(NormalNormal,LightNormal));//镜面反射vec4specularLightColor=vec4(1.0,1.0,1.0,1.0);vec4specularMaterial=vec4(0.4,0.4,0.4,1.0);vec3reflerDir=normalize(reflect(-LightNormal,NormalNormal));vec3eyeDir=normalize(vec3(0.0)-M_WordPos.xyz);vec4specularColor=specularLightColor*specularMaterial*pow(max(0.0,dot(reflerDir,eyeDir)),180);returnambientColor+texture2D(U_MainTexture,M_coord)*diffuseColor+specularColor;}
main函数
voidmain(){gl_FragColor=U_SurfaceColor();}
2、CPU端设置调用subrountine
获取subrountine的Location
m_SubRoutineLocation=OpenGLCore->glGetSubroutineUniformLocation(programId,\GL_FRAGMENT_SHADER,"U_SurfaceColor");//获取SubRoutineIndexm_AmbientIndex=OpenGLCore->glGetSubroutineIndex(programId,GL_FRAGMENT_SHADER,"Ambient");m_DiffuseIndex=OpenGLCore->glGetSubroutineIndex(programId,GL_FRAGMENT_SHADER,"Diffuse");m_SpecularIndex=OpenGLCore->glGetSubroutineIndex(programId,GL_FRAGMENT_SHADER,"Specular");
为U_SurfaceColor设置值
OpenGLCore->glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&m_AmbientIndex);OpenGLCore->glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&m_DiffuseIndex);OpenGLCore->glUniformSubroutinesuiv(GL_FRAGMENT_SHADER,1,&m_SpecularIndex);
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。