您好,登錄后才能下訂單哦!
使用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);
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。