• 一个有趣的模拟光照的shader(类似法线贴图)


      最近使用unity,碰到到一个很有趣的例子.场景无光线,却模拟出了光照,效果挺好.其思路与法线贴图原理异曲同工.

      原作者提供的效果印象深刻.

      模型除了使用原来的diffuse贴图外,还用到了一张模拟记录了"光照"信息的贴图(见机器人头上的贴图).这一点与法线贴图是一致的.

      这个方法比较简单,也比较死.思路很巧.

      分析一下贴图,有效范围基本是一个圆形.以前在学习法线贴图时,就遇到过法线投射在贴图的情景(http://www.cnblogs.com/flytrace/p/3387748.html).当各个方向的法线投影到一个正平面时,它形成一个圆.

      法线贴图本质就是为了预先保存法线信息.那几乎就可以引申出来了,我们也可以保存一个冒充的法线(光线)的信息,根据这个信息我们可以还原一个"伪"的光照过程.这个贴图就反过来利用了这一点.将模型的法线转换到model-view空间,再假设法线被投影到一个正平面(贴图上).于是法线的投影点可换算为贴图的uv坐标.此时在该点我们保存一个颜色值,可以与模型的diffuse贴图颜色进行计算,模拟出光照的效果.  

                    struct v2f
                    {
                        float4 pos    : SV_POSITION;
                        float2 uv     : TEXCOORD0;
                        float2 cap    : TEXCOORD1;
                    };
                    uniform float4 _MainTex_ST;
                    
                    v2f vert (appdata_base v)
                    {
                        v2f o;
                        o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
                        o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                        
                        half2 capCoord;
                        capCoord.x = dot(UNITY_MATRIX_IT_MV[0].xyz,v.normal);
                        capCoord.y = dot(UNITY_MATRIX_IT_MV[1].xyz,v.normal);
                        o.cap = capCoord * 0.5 + 0.5;
                        
                        return o;
                    }
                    
                    uniform sampler2D _MainTex;
                    uniform sampler2D _MatCap;
                    
                    fixed4 frag (v2f i) : COLOR
                    {
                        fixed4 tex = tex2D(_MainTex, i.uv);
                        fixed4 mc = tex2D(_MatCap, i.cap);
                        
                        return (tex + (mc*2.0)-1.0);
                    }

      capCoord.x = dot(UNITY_MATRIX_IT_MV[0].xyz,v.normal);

      capCoord.y = dot(UNITY_MATRIX_IT_MV[1].xyz,v.normal);

      上边2行是这里比较关键的一步,把法线转换到view空间.参看(http://www.cnblogs.com/flytrace/p/3379816.html)说明了原理.总之法线不能直接使用model-view矩阵转换到view空间.

      o.cap = capCoord * 0.5 + 0.5;

      上边是把法线值转换到纹理区间[0,1],之后在fragment shader通过这个值去贴图里查找对应的颜色值.

      这种手法似乎叫MatCap shader.这里是些卡通效果,其他地方有更真实的.

  • 相关阅读:
    一个测试HTML Method的例子
    eXtplorer:在线管理网站文件的利器
    PHPXref:PHP文件交叉引用工具
    统计MySQL数据库大小
    PHP函数glob()
    PclZip:PHP压缩与解压缩
    PHP发送有附件的电子邮件[转]
    查找表中的主键
    CentOS6.4简单配置Cobar
    CentOS6.4 安装mysql cmake的参数说明
  • 原文地址:https://www.cnblogs.com/flytrace/p/3395911.html
Copyright © 2020-2023  润新知