# 【GLSL教程】（七）逐像素的光照

•法线
•半向量
•光源方向

varying vec4 diffuse,ambient;
varying vec3 normal,lightDir,halfVector;

void main()
{
/* first transform the normal into eye space and
normalize the result */
normal = normalize(gl_NormalMatrix * gl_Normal);
/* now normalize the light's direction. Note that
according to the OpenGL specification, the light
is stored in eye space. Also since we're talking about
a directional light, the position field is actually direction */
lightDir = normalize(vec3(gl_LightSource[0].position));
/* Normalize the halfVector to pass it to the fragment shader */
halfVector = normalize(gl_LightSource[0].halfVector.xyz);
/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
ambient += gl_FrontMaterial.ambient * gl_LightModel.ambient;

gl_Position = ftransform();
}

varying vec4 diffuse,ambient;
varying vec3 normal,lightDir,halfVector;

void main()
{
vec3 n,halfV;
float NdotL,NdotHV;
/* The ambient term will always be present */
vec4 color = ambient;
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
/* compute the dot product between normal and ldir */
NdotL = max(dot(n,lightDir),0.0);
...

    ...
if (NdotL > 0.0)
{
color += diffuse * NdotL;
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += gl_FrontMaterial.specular *
gl_LightSource[0].specular *
pow(NdotHV, gl_FrontMaterial.shininess);
}

gl_FragColor = color;
}

•光源的position域的w分量：对方向光来说它是0，表面这个position实际是一个方向（direction）；对点光来说，这个分量是1。
•点光源的衰减由三个系数决定：一个常数项，一个线性项和一个二次项。

varying vec4 diffuse,ambientGlobal,ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;

void main()
{
vec4 ecPos;
vec3 aux;
normal = normalize(gl_NormalMatrix * gl_Normal);

/* these are the new lines of code to compute the light's direction */
ecPos = gl_ModelViewMatrix * gl_Vertex;
aux = vec3(gl_LightSource[0].position-ecPos);
lightDir = normalize(aux);
dist = length(aux);
halfVector = normalize(gl_LightSource[0].halfVector.xyz);

/* Compute the diffuse, ambient and globalAmbient terms */
diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
/* The ambient terms have been separated since one of them */
/* suffers attenuation */
ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
ambientGlobal = gl_FrontMaterial.ambient * gl_LightModel.ambient;
gl_Position = ftransform();
}

varying vec4 diffuse,ambientGlobal, ambient;
varying vec3 normal,lightDir,halfVector;
varying float dist;

void main()
{
vec3 n,halfV,viewV,ldir;
float NdotL,NdotHV;
vec4 color = ambientGlobal;
float att;
/* a fragment shader can't write a varying variable, hence we need
a new variable to store the normalized interpolated normal */
n = normalize(normal);
/* compute the dot product between normal and normalized lightdir */
NdotL = max(dot(n,normalize(lightDir)),0.0);
if (NdotL > 0.0)
{
att = 1.0 / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
gl_LightSource[0].quadraticAttenuation * dist * dist);
color += att * (diffuse * NdotL + ambient);
halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += att * gl_FrontMaterial.specular * gl_LightSource[0].specular *
pow(NdotHV,gl_FrontMaterial.shininess);
}
gl_FragColor = color;
}

•聚光包含一个方向向量spotDirection，表示圆锥体的轴。
•圆锥体包含一个角度，在GLSL中可以使用应用程序设置的角度值以及对应的余弦值spotCosCutoff。
•最后还有一个衰减速率spotExponent，它表示从圆锥的中心轴向外表面变化时光强度的衰减。

...

n = normalize(normal);

/* compute the dot product between normal and ldir */
NdotL = max(dot(n,normalize(lightDir)),0.0);

if (NdotL > 0.0)
{
spotEffect = dot(normalize(gl_LightSource[0].spotDirection),
normalize(-lightDir));
if (spotEffect > gl_LightSource[0].spotCosCutoff)
{
/* compute the illumination in here */
}
}

gl_FragColor = ...

spotEffect = pow(spotEffect, gl_LightSource[0].spotExponent);
att = spotEffect / (gl_LightSource[0].constantAttenuation +
gl_LightSource[0].linearAttenuation * dist +
gl_LightSource[0].quadraticAttenuation * dist * dist);

color += att * (diffuse * NdotL + ambient);

halfV = normalize(halfVector);
NdotHV = max(dot(n,halfV),0.0);
color += att * gl_FrontMaterial.specular *
gl_LightSource[0].specular *
pow(NdotHV,gl_FrontMaterial.shininess);

• 5
点赞
• 5
评论
• 2
收藏
• 一键三连
• 扫一扫，分享海报

03-02 6612
06-11 1069
11-17 1696
01-04 594
05-09 310
08-04 2万+
08-23 188
08-15 1012
02-17 2万+
01-06 495
01-24 279
08-06 144
07-22 921
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、C币套餐、付费专栏及课程。