-1

我试图了解 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 = (-rotationLight) * (gl_NormalMatrix);

  • 为什么他们使用 *2.0 ) - 1.0 来计算法线向量?Normal = normalize(gl_NormalMatrix * gl_Normal);是不可能的吗??

    vec3 fvNormal = normalize((texture2D(bumpMap, Texcoord).xyz * 2.0) - 1.0);

4

2 回答 2

2

懒得在没有你发送给着色器的适当上下文的情况下全面分析代码......但你的子问题很简单:

  1. 这些线是什么意思? vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

    这会将gl_Vertex(多边形边缘点)从对象/模型坐标系转换为相机坐标系。换句话说,它应用了顶点的所有旋转和平移。z轴是指向或指向屏幕的相机视图轴,轴与屏幕相同x,y。尚未应用任何投影/剪报/夹具!结果点存储在fvObjectPosition4D 向量中,(x,y,z,w)我强烈建议您阅读Understanding 4x4 homogenous transform matrixs和那里的子链接也值得研究。

  2. 为什么在变量之前有一个减号? 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轴视图方向(取决于矩阵的格式)。没有背景信息很难确定。

  3. 为什么我们使用负旋转灯? LightDirection = (-rotationLight ) * (gl_NormalMatrix);

    很可能出于与第 2 条相同的原因

  4. 为什么它们*2.0)-1.0用于计算法线向量?

    着色器使用法线/凹凸贴图,这意味着您获得了一个法线向量编码为 RGB 的纹理。由于 RGB 纹理被限制在范围内<0,1>并且法线向量坐标在范围内,<-1,+1>因此您只需要重新调整纹理像素所以:

    • 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);

    但这将消除凹凸/法线贴图,而您只会得到平坦的表面。像这样的东西:

  5. vec3(fCosTime0_X,0, fSinTime0_X)看起来像光的方向。这个是绕y轴旋转的。如果您想将光线方向更改为其他方向,只需将其设为统一并将其直接传递给着色器而不是fCosTime0_X,fSinTime0_X

于 2015-08-17T09:34:56.213 回答
0

这如何与 cosinus 和 sinus 变量正确关联?

您可以通过 glUniform 函数将数据发送到着色器统一变量。例如:在您的顶点着色器中,您有 2 个浮点值,因此您将每次使用不同的位置和不同的值调用 glUniform1f 两次。
或者您可以像这样将浮点变量粘贴到一个 vec2 变量上:
uniform vec2 fSinValues;并用glUniform2f(location, sinVal, cosVal);

如果我想让光线从上方射到茶壶底部怎么办?

如果你想让你的光在不同的方向旋转,只需在这里将 sin 和 cos 值传递给不同的空间坐标:vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);

于 2015-08-13T16:59:58.550 回答