我试图了解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);
}
对于我的片段着色器,我在图片上创建了一个白色,以在其中创建一个洞。 :
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 );
}
}
有人可以解释我的一切是什么吗?我理解它的基本思想。但是,为什么你需要它,以及当你使用其他变量时会发生什么?会发生什么事情是茶壶周围的光线正在进行和移除。这与cosinus和sinus变量的正确关系如何?如果我希望光从上方进入茶壶的底部怎么办?
此外,
这条线是什么意思?
vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
为什么这里变量之前是减号?
ViewDirection = - fvObjectPosition.xyz;
为什么我们使用负旋转光?
LightDirection =( - revationLight)*(gl_NormalMatrix);
为什么他们使用* 2.0) - 1.0来计算normalvector?用 Normal = normalize(gl_NormalMatrix * gl_Normal); ?
是不可能的vec3 fvNormal = normalize((texture2D(bumpMap,Texcoord).xyz * 2.0) - 1.0);
答案 0 :(得分:2)
懒得完全分析代码而没有你要发送到着色器的提示器上下文...但你的子问题很容易:
这些内容是什么意思? vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;
这会将gl_Vertex
(多边形边缘点)从对象/模型坐标系转换为摄像机坐标系。换句话说,它应用了顶点的所有旋转和平移。 z
轴是指向或来自屏幕的摄像机视图轴,x,y
轴与屏幕相同。没有投影/剪报/夹子!结果点存储在fvObjectPosition
4D向量(x,y,z,w)
中我强烈建议您阅读Understanding 4x4 homogenous transform matrices,其中的子链接也值得研究。
为什么变量前面有一个减号? 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
或您的轴视图方向为负[{1}}(取决于矩阵的格式)。没有背景信息很难确定。
为什么我们使用负旋转光? Z
最有可能与bullet 2相同的原因
为什么他们使用LightDirection = (-rotationLight ) * (gl_NormalMatrix);
来计算normalvector?
着色器使用normal/bump mapping,这意味着您获得的纹理具有编码为RGB的法线向量。由于RGB纹理被限制在*2.0)-1.0
范围内,法线向量坐标在<0,1>
范围内,因此您只需要重新缩放纹素即可:
<-1,+1>
位于RGB*2.0
<0,2>
位于RGB*2.0-1.0
这将获得多边形坐标系中的法线向量,因此您需要将其转换为方程式的坐标系。通常是全球世界空间或相机空间。如果您的法线/凹凸贴图已经标准化,则无需标准化。普通纹理与颜色不同......
<-1,+1>
所以RGB格式为normal=(0.0,0.0,+1.0)
这是纹理中经常出现的常见蓝色/洋红色(参见上面的链接)。
但是,您可以使用(0.5,0.5,1.0)
但是这将消除凹凸/法线贴图,而你只需要平面。像这样:
<强>灯强>
Normal = normalize( gl_NormalMatrix * gl_Normal);
看起来像光线方向。这个围绕vec3(fCosTime0_X,0, fSinTime0_X)
轴旋转。如果您想将光线方向更改为其他内容,只需将其设为制服并将其直接传递到着色器而不是y
答案 1 :(得分:0)
这与cosinus和sinus变量的正确关系如何?
您可以通过glUniform函数将数据发送到着色器统一变量。例如:在顶点着色器中,您有2个浮点值,因此每次使用不同的位置和不同的值调用glUniform1f两次。
或者您可以将浮点变量粘贴到一个vec2变量,如下所示:
uniform vec2 fSinValues;
并填写glUniform2f(location, sinVal, cosVal);
如果我想让光从上面来到茶壶的底部怎么办?
如果您希望光线在不同方向旋转,只需将sin和cos值传递到此处的不同空间坐标:vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);