给物体增加光照可以提升场景的立体感,可以用shader实现光照模拟效果.
一般物体光照包括了环境光,漫反射和镜面光,通常光滑的物体可以看到镜面光效果,一般的物体受环境光与漫反射的影响更大一些,环境光可以用一个常量模拟,而漫反射光则是与物体表面法线和光向量的夹角大小有关,夹角大小可以用法向量与光照向量的点乘值表示(此处向量都是经过标准化计算的).
下面给出glsl vs代码:
uniform vec4 lightd;//光照向量
uniform mat4 viewMatrix;//视图矩阵
varying vec3 lightDir,normal;
void main() {
normal = normalize(gl_NormalMatrix * gl_Normal); //在视图空间的法线
lightDir = normalize(vec3(viewMatrix * lightd)); //在视图空间的光线
gl_TexCoord[0] = gl_MultiTexCoord0;//直接取传进来的纹理坐标
gl_Position = ftransform(); //顶点mvp变换
gl_FrontColor = gl_Color;
}
uniform sampler2D tex;//采样器
uniform vec4 amb,dif,matAmb,matDif;//光照与材质属性
varying vec3 lightDir,normal;//在视图空间的光向量与法向量
vec3 lighting() {
float dotLN = max(dot(lightDir,normalize(normal)),0.0); //计算法向量与光向量的夹角
vec3 intensity = (amb * matAmb + dif * matDif * dotLN).rgb; //计算光照值
return intensity;
}
void main() {
vec3 intensity = lighting();
gl_FragColor = texture2D(tex,gl_TexCoord[0].st) * vec4(intensity,1.0);//贴图颜色与光照值混合一下
}
接下来是hlsl vs代码:
float4x4 modelMatrix,viewMatrix,projMatrix,normalMatrix;//模型变换矩阵,视图变换矩阵,投影变换矩阵,法线变换矩阵
float4 amb,diff,ambMtl,diffMtl,lightDir;//光照与物体材质参数,光向量在世界空间
struct Input {
float4 position : POSITION;
float4 normal : NORMAL;
float2 texCoord0 : TEXCOORD0;
};
struct Output {
float4 position : POSITION;
float4 color : COLOR;
float2 texCoord0 : TEXCOORD0;
};
float4 calcLight(float3 normal) {
float4 light = float4(0.0,0.0,0.0,1.0);
float nDotL = max(dot(normalize(lightDir.xyz), normalize(normal)), 0.0);//计算法向量与光线的夹角
light = amb * ambMtl + diff * diffMtl * nDotL;//光照计算
return light;
}
Output main(Input input) {
float4x4 modelViewProjMatrix = mul(modelMatrix, mul(viewMatrix, projMatrix));//计算出mvp变换矩阵
float4 modelVert = input.position;//模型空间的顶点
float4 modelNormal = input.normal;//模型空间的法线
float2 texCoord0 = input.texCoord0;
float3 worldNormal = mul(modelNormal.xyz, (float3x3)normalMatrix);//世界空间的法线
float4 clipVert = mul(modelVert, modelViewProjMatrix);//裁剪空间的顶点,经过mvp变换
Output output = (Output)0;
output.position = clipVert;
output.color = calcLight(worldNormal);
output.texCoord0 = texCoord0;
return output;
}texture Texture0;//纹理0
texture Texture1;//纹理1
sampler tex0 = sampler_state {//采样器0状态
Texture = <Texture0>;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
sampler tex1 = sampler_state {//采样器1状态
Texture = <Texture1>;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
struct Input {
float4 color : COLOR;
float2 texCoord0 : TEXCOORD0;
};
struct Output {
float4 pixColor : COLOR;
};
Output main(Input input) {
float4 texColor = (0.5 * tex2D(tex0, input.texCoord0)) + (0.5 * tex2D(tex1, input.texCoord0));//多重纹理50%混合
float4 lightColor = input.color;
Output output = (Output)0;
output.pixColor = texColor * lightColor;//光照颜色与纹理颜色混合
return output;
}
程序运行效果类似这样:
原文:http://blog.csdn.net/zxx43/article/details/43898551