我在iOS上尝试了一些照明技术,通过利用iOS的OpenGL ES扩展深度查找纹理和相对简单的Blinn-Phong着色器,我已经能够产生一些我很满意的效果:
以上显示20只Suzanne猴子在全屏视网膜上进行多次采样和以下着色器。我正在进行多次采样,因为它每帧只增加1ms。我目前的平均渲染时间是30毫秒(iPad 3),这对于60fps而言太慢了。
顶点着色器:
//Position
uniform mat4 mvpMatrix;
attribute vec4 position;
uniform mat4 depthMVPMatrix;
uniform mat4 vpMatrix;
//Shadow out
varying vec3 ShadowCoord;
//Lighting
attribute vec3 normal;
varying vec3 normalOut;
uniform mat3 normalMatrix;
varying vec3 vertPos;
uniform vec4 lightColor;
uniform vec3 lightPosition;
void main() {
gl_Position = mvpMatrix * position;
//Used for handling shadows
ShadowCoord = (depthMVPMatrix * position).xyz;
ShadowCoord.z -= 0.01;
//Lighting calculations
normalOut = normalize(normalMatrix * normal);
vec4 vertPos4 = vpMatrix * position;
vertPos = vertPos4.xyz / vertPos4.w;
}
片段着色器:
#extension GL_EXT_shadow_samplers : enable
precision lowp float;
uniform sampler2DShadow shadowTexture;
varying vec3 normalOut;
uniform vec3 lightPosition;
varying vec3 vertPos;
varying vec3 ShadowCoord;
uniform vec4 fillColor;
uniform vec3 specColor;
void main() {
vec3 normal = normalize(normalOut);
vec3 lightDir = normalize(lightPosition - vertPos);
float lambertian = max(dot(lightDir,normal), 0.0);
vec3 reflectDir = reflect(-lightDir, normal);
vec3 viewDir = normalize(-vertPos);
float specAngle = max(dot(reflectDir, viewDir), 0.0);"
float specular = pow(specAngle, 16.0);
gl_FragColor = vec4((lambertian * fillColor.xyz + specular * specColor) * shadow2DEXT(shadowTexture, ShadowCoord), fillColor.w);
}
我read that it is possible to use textures as lookup tables减少片段着色器中的计算,但链接的示例似乎是在做完全的Phong照明,而不是Blinn-Phong(我没有做任何表面切线)。此外,在运行样品时,照明看起来相当平滑(我的背景,纯色+ Phong阴影,由于压缩看起来略微带状 - 它在设备上看起来更加平滑)。在我的情况下是否可以使用查找纹理,或者我将不得不向下移动到30fps(我可以实现),关闭多次采样并限制Phong着色到猴子,而不是全屏?在现实世界(即游戏)场景中,我是否需要在整个屏幕上进行Phong着色?