首页 > 代码库 > 基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型
基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型
使用Subroutine在shader中封装不同的函数,在CPU端选择调用那个函数
效果如下图所示
左侧:环境光
中间:环境光 + 漫反射
右侧:环境光 + 漫反射 + 高光
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);
本文出自 “不会飞的纸飞机” 博客,请务必保留此出处http://douzhq.blog.51cto.com/12552184/1931020
基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。