Explanation of working principle of openGL [closed]

十年热恋 提交于 2019-12-25 18:39:47

问题


I'm trying to understand how coding in openGL works. I found this code on the internet and I want to understand it clearly.

For my vertex shader I have:

Vertex

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

And for my Fragment shader, I created a white color on the picture to create a hole in it. :

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



}

Somebody who can explain me very whell what everything does? I understand the basic idea of it. But not often why you need it, and what happend when you use other variables? What happens is that light around the teapot is comming and removing in the time. How is this correctly linked with the cosinus and sinus variables? What if I want the the light comes from above and goes to the bottom of the teapot?

Also,

  • What do this lines mean?

    vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

  • And why is here a minus before the variable?

    ViewDirection = - fvObjectPosition.xyz;

  • Why do we use a negative rotationLight?

    LightDirection = (-rotationLight ) * (gl_NormalMatrix);

  • Why do they use *2.0 ) - 1.0 for calculating the normalvector? Isn't that not possible with Normal = normalize( gl_NormalMatrix * gl_Normal);?

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


回答1:


Too lazy to fully analyze the code without the propper context of what you are sending to the shaders ... but your subquestions are easy enough:

  1. What do this lines mean? vec4 fvObjectPosition = gl_ModelViewMatrix * gl_Vertex;

    This converts gl_Vertex (polygon edge points) from object/model coordinate system to camera coordinate system. In other words it apply all the rotations and translations of your vertexes. The z axis is camera view axis pointing to or from Screen and x,y axises are the same as screens. No projections/clippings/clampings are applied yet !!! The resulting point is stored in fvObjectPosition 4D vector (x,y,z,w) I strongly recommend you to read Understanding 4x4 homogenous transform matrices and the sub-links there are also worth looking into.

  2. And why is here a minus before the variable? ViewDirection = - fvObjectPosition.xyz;

    Most likely because you need the direction from surface to camera so direction_from_surface=camera_pos-surface_pos as your surface_pos is already in camera coordinate system then camera position in the same coordinates are (0,0,0) so the result is direction_from_surface=(0,0,0)-surface_pos=-surface_pos or you got negative Z axis view direction (depends on the format of your matrices). It is Hard to determine without background info.

  3. Why do we use a negative rotationLight? LightDirection = (-rotationLight ) * (gl_NormalMatrix);

    most likely for the same reasons as bullet 2

  4. Why do they use *2.0)-1.0 for calculating the normalvector?

    The shader use normal/bump mapping which means you got an texture with normal vectors encoded as RGB. As RGB textures are clamped to range <0,1> and normal vector coordinates are in range <-1,+1> then you just need to rescale the texel So:

    • RGB*2.0 is in range <0,2>
    • RGB*2.0-1.0 is in range <-1,+1>

    This obtains your normal vector in polygon coordinate system so you need to convert it to the coordinate system your equations work with. Usually global world space or camera space. The normalize is not necessary if your normal/bump map is normalized already. Normal textures are distinctive with colors ...

    • flat surface has normal=(0.0,0.0,+1.0) so in RGB it would be (0.5,0.5,1.0)

    That is the common bluish/magenta color often seen in textures (see the link above).

    But Yes you can use Normal = normalize( gl_NormalMatrix * gl_Normal);

    But that will eliminate the bump/normal map and you would got just flat surfaces instead. Something like this:

    • GL+GLSL normal shading complete example (C++)
  5. Light

    vec3(fCosTime0_X,0, fSinTime0_X) looks like the light direction. This one is rotating around y axis. If you want to change light direction to something else just make it an uniform and pass it directly to shader instead of fCosTime0_X,fSinTime0_X




回答2:


How is this correctly linked with the cosinus and sinus variables?

You can send data to a shader uniform variable via glUniform function. For example: in your vertex shader, you have 2 float values, so you will call glUniform1f twice each time with different location and different value.
Or you can stick the float variables to one vec2 variable like so:
uniform vec2 fSinValues; and fill them with glUniform2f(location, sinVal, cosVal);

What if I want the the light comes from above and goes to the bottom of the teapot?

If you want your light rotate in different direction, just pass the sin and cos values to different space coordinate right here: vec3 rotationLight = vec3(fCosTime0_X,fSinTime0_X, 0);



来源:https://stackoverflow.com/questions/31992390/explanation-of-working-principle-of-opengl

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!