我正在编写一个GLSL程序,作为在封闭源3D应用程序Maya中运行的插件的一部分。我的插件将自定义几何体渲染到应用程序渲染其默认多边形几何体的同一图像缓冲区中。该应用程序使用OpenGL固定管道进行照明和着色,但我使用GLSL渲染自定义几何体和材质。
我的问题是,我想模仿着色器中固定管道灯的行为。应用程序定义gl_LightSource
制服中的灯光,我希望它们在分配给我们在分配给应用程序的默认多边形几何体时具有的自定义几何体时具有相同的方向,强度等。
gl_LightSource
字段已清楚记录,但我找不到固定管道如何解释这些字段的明确文档。有许多关于如何在GLSL中编码点/方向/聚光灯的例子,但它们似乎并不完全模仿固定的管道。例如,如果应用程序定义了它们的混合,您如何确定光是点光源,定向光还是聚光灯?可以处理混合光类型而不会在我的着色器中引入过多的分支吗?
简而言之,是否有任何权威文档或固定功能管道如何评估gl_LightSource
的示例?
答案 0 :(得分:2)
我的问题是,我想模仿片段着色器中固定管道灯的行为。
那么这是你的第一个问题,因为“固定管道灯”是在顶点处理器中实现的,而不是按片段实现。
简而言之,是否有任何权威文档或固定函数管道如何评估gl_LightSource的示例?
是。它被称为“OpenGL图形系统:规范”。它适用于download on the OpenGL Registry;你想要兼容性配置文件。 4.2兼容性规范的2.13节涵盖了用于照明的所有数学。只需将其翻译成GLSL代码即可。
请注意,您无法完全模仿固定功能管道。也就是说,没有办法保证基于着色器和固定功能的照明之间的不变性。你会得到一些接近但不是二进制相同的值。
可以处理混合光照类型而不会在我的着色器中引入过多的分支吗?
你如何定义“过度”?你将需要分支,因为OpenGL的光照方程涉及条件逻辑。
这通常是人们不只是在着色器中重新实现GL照明的部分原因。如果你只是编写GLSL而不是使用数据驱动的方法,那么你可以更有效率。
答案 1 :(得分:1)
顶点着色器的完整源代码在OpenGL ES 2.0 Programming Guide中实现了固定功能管道。 (请注意,固定功能管道只是每个顶点照明,因此,照明计算不需要片段着色器。)
我相信OpenGL驱动程序在处于固定功能模式时会在内部使用此顶点着色器。请查看本书第8章“顶点着色器”。
它定义了具有以下属性的灯光结构;
并且,每个灯光都在函数 lighting_equation()中处理。
答案 2 :(得分:0)
以下是我根据OpenGL规范文档提出的内容:
#version 410 compatibility
vec3 incedentLight (in gl_LightSourceParameters light, in vec3 position)
{
if (light.position.w == 0) {
return normalize (-light.position.xyz);
} else {
vec3 offset = position - light.position.xyz;
float distance = length (offset);
vec3 direction = normalize (offset);
float intensity;
if (light.spotCutoff <= 90.) {
float spotCos = dot (direction, normalize (light.spotDirection));
intensity = pow (spotCos, light.spotExponent) *
step (light.spotCosCutoff, spotCos);
} else {
intensity = 1.;
}
intensity /= light.constantAttenuation +
light.linearAttenuation * distance +
light.quadraticAttenuation * distance * distance;
return intensity * direction;
}
}
根据我对GLSL的理解,分支应该合理有效,因为它只取决于统一变量。