openGL工作原理说明



我正在努力了解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(;

太懒了,无法在没有发送到着色器的属性上下文的情况下完全分析代码。。。但是你的子问题很简单:

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

    这将gl_Vertex(多边形边点(从对象/模型坐标系转换为摄影机坐标系。换句话说,它应用了顶点的所有旋转和平移。z轴是指向屏幕或从屏幕指向的相机视图轴,x,y轴与屏幕相同。尚未应用任何投影/剪切/夹紧!!!所得点存储在fvObjectPosition 4D向量(x,y,z,w)中。我强烈建议您阅读《理解4x4齐次变换矩阵》,其中的子链接也值得研究。

  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>,因此您只需要重新缩放纹素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++(
  5. 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);

相关内容

  • 没有找到相关文章

最新更新