基于Qt的OpenGL可编程管线学习(4)-使用Subroutine绘制不同光照的模型
使用Subroutine在shader中封装不同的函数,在CPU端选择调用那个函数
成都创新互联公司-专业网站定制、快速模板网站建设、高性价比阿克塞哈萨克族自治网站开发、企业建站全套包干低至880元,成熟完善的模板库,直接使用。一站式阿克塞哈萨克族自治网站制作公司更省心,省钱,快速模板网站建设找我们,业务覆盖阿克塞哈萨克族自治地区。费用合理售后完善,十多年实体公司更值得信赖。
效果如下图所示
左侧:环境光
中间:环境光 + 漫反射
右侧:环境光 + 漫反射 + 高光
1、Subroutine 在shader中的内容
subroutine vec4 SurfaceColor(); subroutine uniform SurfaceColor U_SurfaceColor;
定义SurfaceColor()函数类型
环境光函数
// Ambient subroutine (SurfaceColor) vec4 Ambient() { // Ambient vec4 M_AmbientLightColor = vec4(0.2, 0.2, 0.2, 1.0); vec4 M_AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0); vec4 ambientColor = M_AmbientLightColor * M_AmbientMaterial; return ambientColor; }
环境光+漫反射函数
subroutine (SurfaceColor) vec4 Diffuse() { // Ambient vec4 M_AmbientLightColor = vec4(0.2, 0.2, 0.2, 1.0); vec4 M_AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0); vec4 ambientColor = M_AmbientLightColor * M_AmbientMaterial; // Diffuse vec3 M_LightPos = vec3(10.0, 10.0, 0.0); vec3 LightNormal = normalize(M_LightPos); // 指向光源的单位向量 vec3 NormalNormal = normalize(M_normal); // 法线的单位向量 // 点乘获取光照强度 vec4 M_DiffuseLightColor = vec4(1.0, 1.0, 1.0, 1.0); vec4 M_DiffuseMaterial = vec4(0.8, 0.8, 0.8, 1.0); vec4 diffuseColor = M_DiffuseLightColor * M_DiffuseMaterial * max(0.0, dot(NormalNormal, LightNormal)); return ambientColor + texture2D(U_MainTexture, M_coord) * diffuseColor; }
镜面反射函数
subroutine (SurfaceColor) vec4 Specular() { // Ambient vec4 M_AmbientLightColor = vec4(0.2, 0.2, 0.2, 1.0); vec4 M_AmbientMaterial = vec4(0.2, 0.2, 0.2, 1.0); vec4 ambientColor = M_AmbientLightColor * M_AmbientMaterial; // Diffuse vec3 M_LightPos = vec3(10.0, 10.0, 0.0); vec3 LightNormal = normalize(M_LightPos); // 指向光源的单位向量 vec3 NormalNormal = normalize(M_normal); // 法线的单位向量 // 点乘获取光照强度 vec4 M_DiffuseLightColor = vec4(1.0, 1.0, 1.0, 1.0); vec4 M_DiffuseMaterial = vec4(0.8, 0.8, 0.8, 1.0); vec4 diffuseColor = M_DiffuseLightColor * M_DiffuseMaterial * max(0.0, dot(NormalNormal, LightNormal)); // 镜面反射 vec4 specularLightColor = vec4(1.0, 1.0, 1.0, 1.0); vec4 specularMaterial = vec4(0.4, 0.4, 0.4, 1.0); vec3 reflerDir = normalize(reflect(-LightNormal, NormalNormal)); vec3 eyeDir = normalize(vec3(0.0) - M_WordPos.xyz); vec4 specularColor = specularLightColor * specularMaterial * pow(max(0.0, dot(reflerDir, eyeDir)), 180); return ambientColor + texture2D(U_MainTexture, M_coord) * diffuseColor + specularColor; }
main函数
void main() { gl_FragColor = U_SurfaceColor(); }
2、CPU端设置调用subrountine
获取subrountine的Location
m_SubRoutineLocation = OpenGLCore->glGetSubroutineUniformLocation(programId, \ GL_FRAGMENT_SHADER, "U_SurfaceColor"); // 获取 SubRoutine Index m_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);
网页标题:基于Qt的OpenGL可编程管线学习(4)-使用Subroutine绘制不同光照的模型
文章路径:http://pwwzsj.com/article/jgpjci.html