zoukankan      html  css  js  c++  java
  • glsl 法向量规格化的问题

    GLSL Tutorial


    Normalization Issues


    Vertex Shader

    The dot product is commonly used to compute the cosine of the angle between two vectors. As we know this will only hold if both vectors are normalized. This is why we use the normalization operation in many shaders. In here we will see when we can skip this step, and we must use it.

    When a normal vector arrives at a vertex shader is common to normalize it

    两个向量点乘一般用来求两个向量的余弦值,而且这两个向量的模必需为单位值,也就是说,我们必需单位化这两个向量
    	normal = normalize(gl_NormalMatrix * gl_Normal);
    

    The multiplication by the gl_NormaMatrix transforms the incoming normal to eye-space. The normalization guarantees a unit length vector as required to compute the cosine with a dot product.

    So can we avoid the normalization? We'll in some cases we can. If the gl_NormaMatrix is orthogonal then we know that the length of the incoming vector is preserved, i.e. the length of normal is equal to the length of gl_Normal. Therefore, if the normals from the OpenGL application are normalized, which is common, we can avoid the normalization in the shader.
    那么我们有没有可能在顶点着色器中不使用单位化?答案是在一些情况是下是可能的,如果转换矩阵是正交的

    In practice this means that if we use gluLookAt to set the camera, and then perform only rotations and translations on our models, we can skip the normalization of the normal vector in the shader. It also means that a directional light will have its direction already normalized.
    这意味着,在实际代码中,只有旋转和平移转换矩阵,并用定向光的方向必需是单位化的

    Fragment Shader

    In the fragment shader we often find ourselves normalizing a vector which was just normalized in the vertex shader. Do we really need to do this? Well, the answer is yes, in most cases we do.
    在片元着色器中,我们发现我们规范过的向量已经在顶点着色器中规范过了,我们确实需要这样做吗?是的,在大部分情况我们面要这么做.

    Consider a triangle with three different per vertex normal vectors. The fragment shader receives an interpolated normal, based on the distance from the fragment to the three vertices. The problem is that the interpolated vector, although it has the right direction, it doesn't have unit length.

    考虑一个三个顶点的法向量都不一样的三角形,
    The following diagram shows why this is the case. The black lines represent the faces (in 2D), the normals at the vertices are represented in blue. The green vector represents an interpolated normal at the fragment (represented with a dot). All interpolated normals will lie the dotted line. As can be seen in the figure, the green vector is smaller than the blue vectors (which are unit length, at least that was my intention :) ).

    Note that if the vertex normals were not normalized, not only the length would be different from one, but also the direction would be worng in the general case. Hence, even if a vector isn't used on a vertex shader, if we need to have it normalized in the fragment shader, we must also normalize it on the vertex shader.

    There is however a case when normalization can be skipped in the fragment shader, as long as the vectors per vertex are normalized. This is when the vectors per vertex all share the same direction, i.e. they are equal. The interpolation of such vectors would yield exactly the same vertex as the per vertex vectors, hence normalized (we assumed that the vertex vectors were normlized).

    A simple example is when one considers a directional light. The direction is constant for all fragments, so if the direction is previously normalized, we can skip the normalization step in the fragment shader.
    如果顶点向量没有单位化,那么不但它的模不等于1,而且一般情况下,它的方向也是错误的
    如果有一个定向光,并且这个定向光是单位化的,这个时候就不需要单位化了

  • 相关阅读:
    SQL Server 2008的审核功能
    在SSMS(2008)中对数据库对象进行搜索和筛选
    关于在ASP.NET应用程序中异步调用Web Service的解决方案
    SSIS 2008中的Data Profiler任务
    开始Windows Embedded之旅
    在Access中计算两个日期之间的工作日天数
    当PrintForm遇到"RPC服务不可用的错误”
    REST 的知识 【转载】
    在C#中实现类似Eval这类动态求值的函数【转载】
    行内数据
  • 原文地址:https://www.cnblogs.com/lizhengjin/p/1543220.html
Copyright © 2011-2022 走看看