我正在努力了解openGL中的编码是如何工作的。我在网上找到了这个代码,我想弄清楚它。
对于我的顶点着色器,我有:
顶点
uniform vec3 fvLightPosition;
varying vec2 Texcoord;
varying vec2 Texcoordcut;
varying vec3 ViewDirection;
varying vec3 LightDirection;
uniform mat4 extra;
attribute vec3 rm_Binormal;
attribute vec3 rm_Tangent;
uniform float fSinTime0_X;
uniform float fCosTime0_X;
void main( void )
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex * extra;
Texcoord = gl_MultiTexCoord0.xy;
Texcoordcut = gl_MultiTexCoord0.xy;
vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
vec3 rotationLight = vec3(fCosTime0_X,0, fSinTime0_X);
ViewDirection = - fvObjectPosition.xyz;
LightDirection = (-rotationLight ) * (gl_NormalMatrix);
}
对于我的Fragment着色器,我在图片上创建了一个白色来在其中创建一个洞。:
uniform vec4 fvAmbient;
uniform vec4 fvSpecular;
uniform vec4 fvDiffuse;
uniform float fSpecularPower;
uniform sampler2D baseMap;
uniform sampler2D bumpMap;
varying vec2 Texcoord;
varying vec2 Texcoordcut;
varying vec3 ViewDirection;
varying vec3 LightDirection;
void main( void )
{
vec3 fvLightDirection = normalize( LightDirection );
vec3 fvNormal = normalize( ( texture2D( bumpMap, Texcoord ).xyz * 2.0 ) - 1.0 );
float fNDotL = dot( fvNormal, fvLightDirection );
vec3 fvReflection = normalize( ( ( 2.0 * fvNormal ) * fNDotL ) - fvLightDirection );
vec3 fvViewDirection = normalize( ViewDirection );
float fRDotV = max( 0.0, dot( fvReflection, fvViewDirection ) );
vec4 fvBaseColor = texture2D( baseMap, Texcoord );
vec4 fvTotalAmbient = fvAmbient * fvBaseColor;
vec4 fvTotalDiffuse = fvDiffuse * fNDotL * fvBaseColor;
vec4 fvTotalSpecular = fvSpecular * ( pow( fRDotV, fSpecularPower ) );
if(fvBaseColor == vec4(1,1,1,1)){
discard;
}else{
gl_FragColor = ( fvTotalDiffuse + fvTotalSpecular );
}
}
有谁能很清楚地解释我一切都是干什么的?我理解它的基本概念。但不经常你为什么需要它,以及当你使用其他变量时会发生什么?所发生的是茶壶周围的光线在时间上被粉碎和去除。这是如何正确地与余弦和窦变量联系在一起的?如果我想让光从上面照到茶壶底部怎么办?
此外,
这些线条是什么意思?
vec4 fvObjectPosition=gl_ModelViewMatrix*gl_Vertex;
为什么变量前面有一个负数?
ViewDirection=-fvObjectPosition.xyz;
为什么我们使用负旋转光?
LightDirection=(-rotationLight(*(gl_NormalMatrix(;
为什么他们使用*2.0(-1.0来计算法线向量?Normal=normalize(gl_NormalMatrix*gl_Normal(不是不可能吗?
vec3fvNormal=归一化((texture2D(bumpMap,Texcord(.xyz*2.0(-1.0(;
太懒了,无法在没有发送到着色器的属性上下文的情况下完全分析代码。。。但是你的子问题很简单:
-
这些线条是什么意思
vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
这将
gl_Vertex
(多边形边点(从对象/模型坐标系转换为摄影机坐标系。换句话说,它应用了顶点的所有旋转和平移。z
轴是指向屏幕或从屏幕指向的相机视图轴,x,y
轴与屏幕相同。尚未应用任何投影/剪切/夹紧!!!所得点存储在fvObjectPosition
4D向量(x,y,z,w)
中。我强烈建议您阅读《理解4x4齐次变换矩阵》,其中的子链接也值得研究。 -
为什么变量前面有一个负数
ViewDirection = - fvObjectPosition.xyz;
很可能是因为你需要从表面到相机的方向,所以
direction_from_surface=camera_pos-surface_pos
和你的surface_pos
已经在相机坐标系中,那么同一坐标系中的相机位置是(0,0,0)
,所以结果是direction_from_surface=(0,0,0)-surface_pos=-surface_pos
,或者你得到了负的Z
轴视图方向(取决于矩阵的格式(。没有背景信息很难确定。 -
为什么我们要使用负旋转光
LightDirection = (-rotationLight ) * (gl_NormalMatrix);
很可能是因为与子弹头2 相同的原因
-
他们为什么使用
*2.0)-1.0
来计算法线向量着色器使用法线/凹凸贴图,这意味着您获得了一个法线向量编码为RGB的纹理。由于RGB纹理被箝位到范围
<0,1>
,而法线向量坐标在范围<-1,+1>
,因此您只需要重新缩放纹素So:RGB*2.0
在<0,2>
范围内RGB*2.0-1.0
在<-1,+1>
范围内
这将获得多边形坐标系中的法向量,因此需要将其转换为方程使用的坐标系。通常是全球世界空间或相机空间。如果法线/凹凸贴图已经规格化,则不需要规格化。普通纹理具有独特的颜色。。。
- 平面具有
normal=(0.0,0.0,+1.0)
,因此在RGB中为(0.5,0.5,1.0)
这是纹理中常见的蓝色/品红色(请参阅上面的链接(。
但可以使用
Normal = normalize( gl_NormalMatrix * gl_Normal);
但这将消除凹凸/法线贴图,取而代之的是平面。类似这样的东西:
- GL+GLSL法线着色完整示例(C++(
-
光
CCD_ 24看起来像光的方向。这个是围绕
y
轴旋转的。如果您想将灯光方向更改为其他方向,只需使其均匀,并将其直接传递给着色器,而不是fCosTime0_X,fSinTime0_X
这是如何正确地与余弦和窦变量联系在一起的?
可以通过glUniform函数将数据发送到着色器统一变量。例如:在顶点着色器中,有2个浮点值,因此每次调用glUniform1f两次,位置和值不同
或者,您可以将float变量粘贴到一个vec2变量上,如下所示:uniform vec2 fSinValues;
并填充glUniform2f(location, sinVal, cosVal);
如果我想让光从上面照到茶壶底部怎么办?
如果你想让你的光在不同的方向上旋转,只需将sin和cos值传递到不同的空间坐标就可以了:vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);