zoukankan      html  css  js  c++  java
  • 关于法线贴图

    问题:为什么需要把法线纹理的“Texture Type”设置成“Normal Map”才能正确显示。

    回答:这样的设置可以让Unity根据不同平台对纹理进行压缩,通过UnpackNormal函数对法线纹理进行正确的采样,即“将把颜色通道变成一个适合于实时法向映射的格式”。

     

    问题:把“Texture Type”设置成“Normal Map”后,有一个复选框是“Create from grayscale”,这个是做什么用的。

    回答:默认是Tangent-Space Normal Map,勾选后就表示Grayscale Height Map

     

    问题:为什么要使用Tangent Space

    回答:模型自带的法线,是属于Object-Space Normal Map,输出到贴图上是五颜六色的。

      法线贴图上的法线,是属于Tangent-Space Normal Map,整体是一个蓝色的,unity只支持这种发现纹理。   

    这两种法线贴图各有优缺点,但总的来说切空间法线贴图更实用,二者的优点如下:

    模型法线:记录绝对发现信息,实现简单直观,UV接缝处好平滑;

    切空间法线:记录相对值,自由度高,可进行UV动画,可充用NormalMap,可压缩(法线是单位向量,可通过两个值推导出第三个值)。

     

    问题:光照计算,转换到那个空间

    回答:如果使用模型自带的法线时,我们一般把所有信息转换到World Space中;如果是使用法线纹理,一般是转换到Tangent Space中。

     

    问题:法线矩阵转换的特殊之处

    回答:对法线的转换需要使用矩阵的逆转置矩阵,比如将normal从模型坐标转换到世界坐标:

    o.worldNormal = mul(SCALED_NORMAL(float3x3)_World2Object);  

    使用的是_World2Object而不是_Object2World

    还有比如:

    float3 norm = mul((float3x3)UNITY_MATRIX_IT_MV, v.normal);

    使用的是UNITY_MATRIX_IT_MV,以保证缩放以后发现仍然垂直于物体表面。

    ps:unity5以后可以直接使用函数将模型转换到world坐标:

    fixed3 worldNormal = UnityObjectToWorldNormal(v.normal)  

     

    使用法线贴图进行光照计算:

    Shader "Custom/NormalMap"
    {
        Properties{
            _Bump ("Bump", 2D) = "white"{}
            _Color ("Color", Color) = (1, 1, 1, 1)
            _Gloss ("Gloss" , float) = 10
        }
        SubShader
        {
            Pass
            {
                Tags{"LightMode" = "ForwardBase"}
     
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                
                #include "UnityCG.cginc"
     
                struct v2f{
                    float2 uv : TEXCOORD0;
                    float4 vertex : SV_POSITION;
                    float3 ldir : TEXCOORD1;
                    float3 vdir : TEXCOORD2;
                };
     
                v2f vert (appdata_tan v)
                {
                    v2f o;
                    o.vertex = UnityObjectToClipPos(v.vertex);
                    o.uv = v.texcoord;
     
                    TANGENT_SPACE_ROTATION;
                    o.vdir = mul(rotation,ObjSpaceViewDir(v.vertex));
                    o.ldir = mul(rotation,ObjSpaceLightDir(v.vertex));
                    return o;
                }
                
                sampler2D _Bump;
                fixed4 _Color;
                float _Gloss;
                fixed4 _LightColor0;
                sampler2D _CameraDepthTexture;
     
                fixed4 frag (v2f i) : SV_Target
                {
                    fixed4 result;
     
                    float3 tNormal = normalize(UnpackNormal(tex2D(_Bump,i.uv * 10)));
                    float3 tLDir = normalize(i.ldir);
                    float3 tVDir = normalize(i.vdir);
                    //半兰伯特光照模型
                    float lCoeff = dot(tNormal,tLDir) * 0.5 + 0.5;
                    //兰伯特光照模型
                    //float lCoeff = saturate(dot(tNormal,tLDir));
     
                    //phone光照模型
                    //float vCoeff = saturate(dot(reflect(-tLDir,tNormal),tVDir));
                    //blinn-phone光照模型
                    float vCoeff = saturate(dot(normalize(tLDir + tVDir),tNormal));
                    return _Color * lCoeff + _LightColor0 * pow(vCoeff,_Gloss);
                }
                ENDCG
            }
        }
    }

     

     

     

     

  • 相关阅读:
    Css_加载样式
    Mvc4_@RenderBody()和@RenderSection()
    C#_观察者模式
    Mvc4_MvcPager 概述
    Mvc4_Area的应用
    Nginx 服务器性能参数设置
    Nginx变量的实现机制
    天下无雾
    Nginx Http框架的理解
    【转】websocket协议规范
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/6483697.html
Copyright © 2011-2022 走看看