# 永远也不完美的程序

• 随笔 - 39
• 文章 - 61
• 评论 - 173
• 引用 - 0

• 积分 - 270167
• 排名 - 94

### 最新评论

1. 怎样获得顶点的TBN

uniform vec3 lightpos; //传入光源的模型坐标吧
uniform vec4 eyepos;

varying vec3 lightdir;
varying vec3 halfvec;
varying vec3 norm;
varying vec3 eyedir;

attribute vec3 rm_Tangent;

void main(void)
{
vec4 pos = gl_ModelViewMatrix * gl_Vertex;
pos = pos / pos.w;

//把光源和眼睛从模型空间转换到视图空间
vec4 vlightPos = (gl_ModelViewMatrix * vec4(lightpos, 1.0));
vec4 veyePos   = (gl_ModelViewMatrix * eyepos);

lightdir = normalize(vlightPos.xyz - pos.xyz);
vec3 eyedir = normalize(veyePos.xyz - pos.xyz);

//模型空间下的TBN
norm = normalize(gl_NormalMatrix * gl_Normal);

vec3 vtangent  = normalize(gl_NormalMatrix * rm_Tangent);

vec3 vbinormal = cross(norm,vtangent);

//将光源向量和视线向量转换到TBN切线空间
lightdir.x = dot(vtangent,  lightdir);
lightdir.y = dot(vbinormal, lightdir);
lightdir.z = dot(norm     , lightdir);
lightdir = normalize(lightdir);

eyedir.x = dot(vtangent,  eyedir);
eyedir.y = dot(vbinormal, eyedir);
eyedir.z = dot(norm     , eyedir);
eyedir = normalize(eyedir);

halfvec = normalize(lightdir + eyedir);

gl_FrontColor = gl_Color;

gl_TexCoord[0] = gl_MultiTexCoord0;

gl_Position = ftransform();
}
// vertex shaderuniform vec3 lightpos; //传入光源的模型坐标吧uniform vec4 eyepos;varying vec3 lightdir;varying vec3 halfvec;varying vec3 norm;varying vec3 eyedir;attribute vec3 rm_Tangent;void main(void){   vec4 pos = gl_ModelViewMatrix * gl_Vertex;   pos = pos / pos.w;   //把光源和眼睛从模型空间转换到视图空间   vec4 vlightPos = (gl_ModelViewMatrix * vec4(lightpos, 1.0));   vec4 veyePos   = (gl_ModelViewMatrix * eyepos);      lightdir = normalize(vlightPos.xyz - pos.xyz);   vec3 eyedir = normalize(veyePos.xyz - pos.xyz);     //模型空间下的TBN   norm = normalize(gl_NormalMatrix * gl_Normal);   vec3 vtangent  = normalize(gl_NormalMatrix * rm_Tangent);   vec3 vbinormal = cross(norm,vtangent);      //将光源向量和视线向量转换到TBN切线空间   lightdir.x = dot(vtangent,  lightdir);   lightdir.y = dot(vbinormal, lightdir);    lightdir.z = dot(norm     , lightdir);   lightdir = normalize(lightdir);      eyedir.x = dot(vtangent,  eyedir);   eyedir.y = dot(vbinormal, eyedir);   eyedir.z = dot(norm     , eyedir);   eyedir = normalize(eyedir);      halfvec = normalize(lightdir + eyedir);   gl_FrontColor = gl_Color;      gl_TexCoord[0] = gl_MultiTexCoord0;      gl_Position = ftransform();}

uniform float shiness;
uniform vec4 ambient, diffuse, specular;

uniform sampler2D bumptex;
uniform sampler2D basetex;

float amb = 0.2;
float diff = 0.2;
float spec = 0.6;

varying vec3 lightdir;
varying vec3 halfvec;
varying vec3 norm;
varying vec3 eyedir;

void main(void)
{
vec3 vlightdir = normalize(lightdir);
vec3 veyedir = normalize(eyedir);

vec3 vnorm =   normalize(norm);
vec3 vhalfvec =  normalize(halfvec);

vec4 baseCol = texture2D(basetex, gl_TexCoord[0].xy);

//Normal Map里的像素normal定义于该像素的切线空间
vec3 tbnnorm = texture2D(bumptex, gl_TexCoord[0].xy).xyz;

tbnnorm = normalize((tbnnorm  - vec3(0.5))* 2.0);

float diffusefract =  max( dot(lightdir,tbnnorm) , 0.0);
float specularfract = max( dot(vhalfvec,tbnnorm) , 0.0);

if(specularfract > 0.0){
specularfract = pow(specularfract, shiness);
}

gl_FragColor = vec4(amb * ambient.xyz * baseCol.xyz
+ diff * diffuse.xyz * diffusefract * baseCol.xyz
+ spec * specular.xyz * specularfract ,1.0);
}
//fragment shaderuniform float shiness;uniform vec4 ambient, diffuse, specular;uniform sampler2D bumptex;uniform sampler2D basetex;float amb = 0.2;float diff = 0.2;float spec = 0.6;varying vec3 lightdir;varying vec3 halfvec;varying vec3 norm;varying vec3 eyedir;void main(void){   vec3 vlightdir = normalize(lightdir);   vec3 veyedir = normalize(eyedir);   vec3 vnorm =   normalize(norm);   vec3 vhalfvec =  normalize(halfvec);        vec4 baseCol = texture2D(basetex, gl_TexCoord[0].xy);       //Normal Map里的像素normal定义于该像素的切线空间   vec3 tbnnorm = texture2D(bumptex, gl_TexCoord[0].xy).xyz;      tbnnorm = normalize((tbnnorm  - vec3(0.5))* 2.0);       float diffusefract =  max( dot(lightdir,tbnnorm) , 0.0);    float specularfract = max( dot(vhalfvec,tbnnorm) , 0.0);      if(specularfract > 0.0){   specularfract = pow(specularfract, shiness);   }      gl_FragColor = vec4(amb * ambient.xyz * baseCol.xyz                 + diff * diffuse.xyz * diffusefract * baseCol.xyz                 + spec * specular.xyz * specularfract ,1.0);}

(上为底纹理和法线纹理，下为它们与某破壁模型合作的效果，纹理from planetpixelemporium.com)

(我想是游戏最常用的用途：砖墙。我想是最常用的NormalMap,from NEHE)

(自己把墙壁BaseMap放入Photoshop的normalMapFilter里弄的NormalMap，呃.....)

posted on 2010-11-29 17:58 狂烂球 阅读(2305) 评论(0)  编辑 收藏 引用 所属分类: 图形编程

 只有注册用户登录后才能发表评论。 【推荐】100%开源！大型工业跨平台软件C++源码提供，建模，组态！ 相关文章: