【问题标题】:OpenGL ES 2.0-3.0 gl_LightSource equivalent?OpenGL ES 2.0-3.0 gl_LightSource 等效?
【发布时间】:2026-01-19 17:15:01
【问题描述】:

我正在尝试将顶点着色器转换为在 iOS 7 上工作,但我无法弄清楚 gl_LightSource[0].position.xyz 的等价物应该是什么。

这是 OpenGL ES 1.0 顶点着色器

我已经将所有 gl_xxx 东西换成了统一的 mat4/vec4 等,我可以从我的代码中传入,但我不知道如何处理这一行

vec4 eyeLightPos = gl_LightSource[0].position;


这是要转换的顶点着色器代码

 varying vec3 N;
 varying vec3 L;
 varying vec3 E;
 attribute float meanK;
 attribute float meanKS;
 attribute float gaussian;
 attribute float gaussianS;
 varying float meanCurvature;
 attribute float keyAttrib;
 attribute float keyUni;
 varying float keyShader;
 attribute float cuSS;
 varying float cuSSF;
 attribute float guSS;
 varying float guSSF;
 void main() {
       gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
       vec4 eyePosition = gl_ModelViewMatrix * gl_Vertex;
       vec4 eyeLightPos = gl_LightSource[0].position;
       N = normalize(gl_NormalMatrix * gl_Normal); L = eyeLightPos.xyz - eyePosition.xyz;
       E = -eyePosition.xyz;
       if(keyAttrib == 0.0)
             meanCurvature = meanK;
       if(keyAttrib == 1.0)
             meanCurvature = meanKS;
       if(keyAttrib == 2.0)
             meanCurvature = gaussian;
       if(keyAttrib == 3.0)
             meanCurvature = gaussianS;
       keyShader = keyUni;
       cuSSF = cuSS;
       guSSF = guSS;
}

这是片段着色器代码

varying vec3 N;
varying vec3 L;
varying vec3 E;
varying float meanCurvature;
varying float keyShader;
varying float cuSSF;
varying float guSSF;
void main() {
vec3 Normal = normalize(N);
vec3 Light = normalize(L);
vec3 Eye = normalize(E);
vec3 Half = normalize(Eye + Light);
vec4 baseColor = vec4(0.5,0.5,0.5,0.0);
vec4 white = vec4(1.0,1.0,1.0,0.0);
vec4 red = vec4(1.0,0.0,0.0,0.0);
vec4 blue = vec4(0.0,0.0,1.0,0.0);
float f = 1.0;
//Locally backscattered light
float alpha = 0.43;
float mu = 1.0;
float delta = 0.35;
float muss = 0.25;
float deltass = 0.01;
float Gd;
if(meanCurvature >= 0)
 Gd = 1.0 + (alpha * exp(-1.0 * pow((meanCurvature - mu),2.0) / delta));
else
 Gd = 1.0;
//Ambient occlusion
float landa = 0.6;
float gamma = 1.0;
float Aa = 1.0 - pow((landa * meanCurvature), (2.0 * gamma));
float lDotv = dot(Light, Eye); float epsilon = 20.0;
float lv;
if(lDotv >= 0.0)
 lv = 0.0;
//Subsurface scatter
else
 float nv = exp(-1.0 * pow(dot(Normal, Eye) - muss, 2.0) / deltass);
lv = pow((-1.0 * lDotv),epsilon); float GSS = -1.0 * meanCurvature * lv * nv;
float Kd = max(dot(Normal, Light), 0.0); float Ks = pow(max(dot(Half, Normal), 0.0),
            gl_FrontMaterial.shininess);
vec4 diffuse = Kd * gl_FrontLightProduct[0].diffuse;
if(dot(Normal, Light) < 0.0) f = 0.0;
vec4 specular = f * Ks * gl_FrontLightProduct[0].specular;
vec4 ambient = gl_FrontLightProduct[0].ambient;
vec4 Css = vec4(1.0,1.0,1.0,1.0);
if(keyShader == 1.0)
      gl_FragColor = (ambient) + (Gd * dot(Normal, Light) * diffuse) - (GSS * Css);
else if(keyShader == 2.0)
      gl_FragColor = Aa * ambient;
else if(keyShader == 3.0)
      gl_FragColor = (Gd * dot(Normal, Light) * diffuse) - (GSS * Css);
else if(keyShader == 4.0)
      gl_FragColor = ambient;
else if(keyShader == 5.0)
gl_FragColor = (Aa * ambient) + (dot(Normal, Light) * diffuse)
            - (GSS * Css);
else if(keyShader == 6.0)
gl_FragColor = Gd * dot(Normal, Light) * diffuse; else if(keyShader == 7.0)
      gl_FragColor = (Aa * ambient) - (GSS * Css);
else if(keyShader == 8.0)
      gl_FragColor = diffuse;
else if(keyShader == 9.0)
gl_FragColor = (Aa * ambient) + (Gd * dot(Normal, Light) * diffuse) - (Css);
else if(keyShader == 10.0)
      gl_FragColor = GSS * baseColor;
else if(keyShader == 0.0)
gl_FragColor = (Aa * ambient) + (Gd * dot(Normal, Light) *
            diffuse) - (GSS * Css);
else if(keyShader == 11.0) {
      if(meanCurvature == 0.0)
            gl_FragColor = baseColor;
      else if(meanCurvature < 0.0)
            gl_FragColor = baseColor + ((-1.0 * meanCurvature) *
      else        blue);
            gl_FragColor = baseColor + (meanCurvature * red);
}
else if(keyShader == 12.0)
      gl_FragColor = ambient + diffuse + specular;
else if(keyShader == 13.0) {
      if(cuSSF == 0)
            gl_FragColor = baseColor;
      else if(cuSSF < 0.0)
      else  gl_FragColor = baseColor + ((-1.0 * cuSSF) * blue);
}           gl_FragColor = baseColor + (cuSSF * red);
else if(keyShader == 14.0) {
      if(guSSF == 0)
            gl_FragColor = baseColor;
      else if(guSSF < 0.0)
      else  gl_FragColor = baseColor + ((-1.0 * guSSF ) * blue);
}           gl_FragColor = baseColor + (guSSF  * red);
else if(keyShader == 15.0)
      gl_FragColor = Gd * diffuse;
else if(keyShader == 16.0)
gl_FragColor = Gd * dot(Normal, Light) * white;
else if(keyShader == 17.0)
gl_FragColor = dot(Normal, Light) * diffuse;
else if(keyShader == 18.0)
      gl_FragColor = Gd * baseColor;
else if(keyShader == 19.0)
      gl_FragColor = Aa * baseColor;
}

【问题讨论】:

    标签: ios7 opengl-es-2.0 opengl-es-3.0


    【解决方案1】:

    OpenGL ES 2 不像 OpenGL ES 1.0 那样使用固定功能管道。您必须将光源数据作为制服或属性传入。

    查看this page 的示例。

    您还必须自己实现法线和任何其他功能。

    有关您可以在 OpenGL ES 2.0 中访问的所有内置函数的列表,请查看this reference card。在第 4 页的顶部,您会找到一个列表和说明。

    【讨论】:

    • 不确定我是否可以在评论中提出其他问题,但 gl_NormalMatrix 和 gl_Normal 的类型是什么?我假设 gl_NormalMatrix 是 mat4 而 gl_Normal 是 vec4
    • 它是正常的,因此它的单位长度为 1,因此它是一个 vec3 和 mat3 ......现在我需要转换片段着色器......谢谢 jnfjnjtj
    • 对不起,我没有早点看到这个。查看我的更新答案以获取更多信息。