如何计算glsl中两条法线之间的角度?
如何计算glsl中两条法线之间的角度? 我正在尝试将菲涅耳效果添加到对象的外边缘(将该效果与 phong 阴影相结合),并且我认为角度是我唯一缺少的东西。
片段着色器:
varying vec3 N;
varying vec3 v;
void main(void) {
v = vec3(gl_ModelViewMatrix * gl_Vertex);
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
顶点着色器:
varying vec3 N;
varying vec3 v;
void main(void) {
vec3 L = normalize(gl_LightSource[0].position.xyz - v);
vec3 E = normalize(-v);
vec3 R = normalize(-reflect(L,N));
vec4 Iamb = gl_FrontLightProduct[0].ambient
vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0), gl_FrontMaterial.shininess);
vec4 Itot = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;
vec3 A = //calculate the angle between the lighting direction and the normal//
float F = 0.33 + 0.67*(1-cos(A))*(1-cos(A))*(1-cos(A))*(1-cos(A))*(1-cos(A));
vec4 white = {1.0, 1.0, 1.0, 1.0};
gl_FragColor = F*white + (1.0-F)*Itot;
}
变化的 vec3
How do you calculate the angle between two normals in glsl? I am trying to add the fresnel effect to the outer edges of an object (combining that effect with phong shading), and I think that the angle is the only thing I am missing.
Fragment Shader:
varying vec3 N;
varying vec3 v;
void main(void) {
v = vec3(gl_ModelViewMatrix * gl_Vertex);
N = normalize(gl_NormalMatrix * gl_Normal);
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
Vertex Shader:
varying vec3 N;
varying vec3 v;
void main(void) {
vec3 L = normalize(gl_LightSource[0].position.xyz - v);
vec3 E = normalize(-v);
vec3 R = normalize(-reflect(L,N));
vec4 Iamb = gl_FrontLightProduct[0].ambient
vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0);
vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0), gl_FrontMaterial.shininess);
vec4 Itot = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec;
vec3 A = //calculate the angle between the lighting direction and the normal//
float F = 0.33 + 0.67*(1-cos(A))*(1-cos(A))*(1-cos(A))*(1-cos(A))*(1-cos(A));
vec4 white = {1.0, 1.0, 1.0, 1.0};
gl_FragColor = F*white + (1.0-F)*Itot;
}
varying vec3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
两个向量之间的点积将返回角度的余弦(在 GLSL 中为 dot(a,b))。 对其取反余弦将返回以弧度为单位的角度(在 GLSL 中为 acos(x))。
点积非常便宜,反余弦则相当昂贵。
然而,菲涅尔效应实际上并不需要角度。 只需在向量之间有点结果就足够了。 菲涅尔效应有很多近似方法,最便宜的一种是直接使用点。 或对其进行平方 (x*x),或求其他幂。
在上面的着色器中,看起来您只想将点提高到 5 次方。 就像是:
dot product between two vectors will return the cosine of the angle (in GLSL it's dot(a,b)). Taking arc-cosine of that will return angle in radians (in GLSL it's acos(x)).
Dot product is very cheap, arc-cosine is quite expensive.
However, Fresnel effect does not really need the angle. Just having dot result between the vectors is enough. There are many approximations for the Fresnel effect, one of the cheapest is just using the dot directly. Or squaring it (x*x), or raising to some other power.
In your shader above, it looks like you just want to raise dot to 5th power. Something like:
从两个向量的点积,你可以得到它们之间角度的余弦
使用这个,你在计算F时不需要计算余弦。由于你的向量是单位向量,例如长度为1,你甚至可以避免该部门。
From the dot product of two vectors you can get the cosine of the angle between them
Using this, you don't need to calculate the cosine when calculating F. Since your vectors are unit vectors, e.g., have length one, you can even avoid the division.