温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型

发布时间:2020-05-13 16:51:11 来源:网络 阅读:610 作者:Douzhq 栏目:编程语言

使用Subroutine在shader中封装不同的函数,在CPU端选择调用那个函数

效果如下图所示

基于Qt的OpenGL可编程管线学习(4)- 使用Subroutine绘制不同光照的模型

左侧:环境光

中间:环境光 + 漫反射

右侧:环境光 + 漫反射 + 高光


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);


向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI