码迷,mamicode.com
首页 > 其他好文 > 详细

shader漫反射模拟

时间:2015-02-21 16:37:33      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:opengl   glsl   directx   hlsl   图形   

给物体增加光照可以提升场景的立体感,可以用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;
}  


glsl fs代码:

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);//贴图颜色与光照值混合一下
}  

这边的向量都放在视图空间里计算,并且在fs中计算出光照值.


接下来是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;
}

hlsl ps代码:

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;
}

在hlsl光照在世界空间计算,并且是在vs中算出顶点颜色,然后插值计算出片元的光照颜色值,与glsl效果类似.


程序运行效果类似这样:

技术分享


shader漫反射模拟

标签:opengl   glsl   directx   hlsl   图形   

原文地址:http://blog.csdn.net/zxx43/article/details/43898551

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!