使用Subroutine在shader中封装不同的函数,在CPU端选择调用那个函数
效果如下图所示
左侧:环境光
中间:环境光 + 漫反射
右侧:环境光 + 漫反射 + 高光
1、Subroutine 在shader中的内容
subroutine vec4 SurfaceColor();
subroutine uniform SurfaceColor U_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);
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。