使用GLSL实现更多数量的局部光照
2008-07-02 11:16
399 查看
众所周知,OpenGL固定管线只提供了最多8盏灯光。如何使得自己的场景之中拥有更多的灯光效果呢?
这里提供一种使用GLSL shader实现更多数量的局部光照。
在GLSL里,首先建立光照参数数据结构:
struct myLightParams
const int maxLightCount = 32;
uniform myLightParams light[maxLightCount];
uniform bool bLocalViewer;
uniform bool bSeperateSpecualr;
主函数:
void main()
void DirectionalLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
void PointLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
void SpotLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
{
vec3 VP = vec3(light[i].position) - epos;
float d = length(VP);
VP = normalize(VP);
float att = 1.0/(light[i].constantAttenuation + light[i].linearAttenuation*d + light[i].quadraticAttenuation*d*d);
float dotSpot = dot(-VP, normalize(light[i].spotDirection));
float cosCutoff = cos(light[i].spotCutoff*3.1415926/180.0);
float spotAtt = 0;
if (dotSpot < cosCutoff)
spotAtt = 0;
else
spotAtt = pow(dotSpot, light[i].spotExponent);
att *= spotAtt;
vec3 h = normalize(VP+eye);
float dotVP = max(0, dot(normal, VP));
float dotHV = max(0, dot(normal, h));
amb += light[i].ambient * att;
diff += light[i].diffuse * dotVP * att;
spec += light[i].specular * pow(dotHV, gl_FrontMaterial.shininess) * att;
}
这样,对于场景之中的任意对象,它所能够接受计算的光源就可以突破8个的限制了。
上述光照计算是遵循OpenGL spec的,因此与固定管线的效果是一致的。
这里提供一种使用GLSL shader实现更多数量的局部光照。
在GLSL里,首先建立光照参数数据结构:
struct myLightParams
const int maxLightCount = 32;
uniform myLightParams light[maxLightCount];
uniform bool bLocalViewer;
uniform bool bSeperateSpecualr;
主函数:
void main()
void DirectionalLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
void PointLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
void SpotLight(int i, vec3 eye, vec3 epos, vec3 normal,
inout vec4 amb, inout vec4 diff, inout vec4 spec)
{
vec3 VP = vec3(light[i].position) - epos;
float d = length(VP);
VP = normalize(VP);
float att = 1.0/(light[i].constantAttenuation + light[i].linearAttenuation*d + light[i].quadraticAttenuation*d*d);
float dotSpot = dot(-VP, normalize(light[i].spotDirection));
float cosCutoff = cos(light[i].spotCutoff*3.1415926/180.0);
float spotAtt = 0;
if (dotSpot < cosCutoff)
spotAtt = 0;
else
spotAtt = pow(dotSpot, light[i].spotExponent);
att *= spotAtt;
vec3 h = normalize(VP+eye);
float dotVP = max(0, dot(normal, VP));
float dotHV = max(0, dot(normal, h));
amb += light[i].ambient * att;
diff += light[i].diffuse * dotVP * att;
spec += light[i].specular * pow(dotHV, gl_FrontMaterial.shininess) * att;
}
这样,对于场景之中的任意对象,它所能够接受计算的光源就可以突破8个的限制了。
上述光照计算是遵循OpenGL spec的,因此与固定管线的效果是一致的。
相关文章推荐
- 使用GLSL实现更多数量的局部光照 【转】
- 使用GLSL实现更多数量的局部光照
- 使用GLSL实现对光照的模拟(二)
- 使用GLSL实现对光照的模拟(一)
- 使用GLSL实现对光照的模拟(一)
- OpenGL 4.0 GLSL 用单光源 实现逐顶点 漫反射光照模型
- 使用XML实现页面的局部刷新
- pulltorefresh(一)使用介绍,实现下拉刷新上拉加载更多
- 使用updatepanel局部刷新实现注册时对用户名的检测示例
- 使用 AJAX,局部刷新 GridView 进行数据绑定的简单实现
- 使用JQUERY实现局部页面定时刷新
- GLSL-使用Uniform Block实现着色器的数据共享
- 使用ajax与jQuery实现局部修改信息
- .NET使用js制作百度搜索下拉提示效果(不是局部刷新)实现思路
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- 使用SwipeRefreshLayout和RecyclerView实现仿“简书”下拉刷新和上拉加载更多
- 使用turbolinks实现局部页面刷新
- 使用vue.js 在移动端简单实现的下拉加载更多 和一些常用的js/jq操作和vueFilter,v-if和v-show运用
- 【SSH网上商城项目实战28】使用Ajax技术局部更新商品数量和总价