当前位置: 代码迷 >> VC/MFC >> 关于glsl逐像素光照的有关问题
  详细解决方案

关于glsl逐像素光照的有关问题

热度:138   发布时间:2016-05-02 03:49:09.0
关于glsl逐像素光照的问题
为了实现法线贴图弄的着色器,画模型的时候用的立即模式,法线用glNormal3fv指定了(模型格式里有法线数据),切线用glVertexAttrib3fv指定了(拿的相邻顶点的坐标相减算出来的)。切线和法线都是世界坐标系下的向量。传入的一致变量(lightpos,eyepos)的坐标都是世界坐标系下的。(其实我是想弄方向光,但是不会计算lightdir,只能拿当前模型世界坐标加上一个很远的距离算出lightpos再在shader里面算lightdir)

得到的光照结果非常的奇怪,不知道为什么,法线贴图是抄来的应该没问题

顶点着色器

uniform vec3 lightpos;
uniform vec3 eyepos;
varying vec3 lightvec;
varying vec3 halfvec;
attribute vec3 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 * vec4(eyepos, 1.0));

vec3 lightdir = normalize(vlightpos.xyz - pos.xyz);
vec3 eyedir = normalize(veyepos.xyz - pos.xyz);

vec3 n = normalize(gl_NormalMatrix * gl_Normal);
vec3 t = normalize(gl_NormalMatrix * tangent);
vec3 b = cross(n, t);
//t = cross(n, b);

vec3 halfdir = normalize(lightdir + eyedir);

lightvec.x = dot(t, lightdir);
lightvec.y = dot(b, lightdir);
lightvec.z = dot(n, lightdir);
lightvec = normalize(lightvec);

vec3 eyevec;
eyevec.x = dot(t, eyedir);
eyevec.y = dot(b, eyedir);
eyevec.z = dot(n, eyedir);
eyevec = normalize(eyevec);

halfvec = normalize(lightvec + eyevec);

gl_FrontColor = gl_Color;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_Position = ftransform();
}

片段着色器

//fragment shader
uniform sampler2D basetex;
uniform sampler2D normtex;
uniform vec4 ambient, diffuse, specular;
uniform float shiness;
varying vec3 lightvec;
varying vec3 halfvec;

void main(void)
{
vec3 vlightvec = normalize(lightvec);
vec3 vhalfvec =  normalize(halfvec);
vec4 baseCol = texture2D(basetex, gl_TexCoord[0].xy); 
vec3 tbnnorm = texture2D(normtex, gl_TexCoord[0].xy).xyz;
   
tbnnorm = normalize(tbnnorm * 2.0 - vec3(1.0));

float diffusefract = max(0.0, dot(vlightvec, tbnnorm));
float specularfract = max(0.0, dot(vhalfvec, tbnnorm));
if(specularfract > 0.0)
  {
specularfract = pow(specularfract, shiness);
}
   
gl_FragColor = gl_Color * vec4(ambient.xyz * baseCol.xyz + 
diffuse.xyz * diffusefract * baseCol.xyz +
specular.xyz * specularfract, 1.0);
}


固定diffusefract 和specularfract :


用了法线贴图之后:

------解决思路----------------------
不懂帮顶,这个看起来挺高端的,不过下面那个图看起来挺好的啊