本系列主要參考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同一时候会加上一点个人理解或拓展。

这里是本书全部的插图。这里是本书所需的代码和资源(当然你也能够从官网下载)。

========================================== 切割线 ==========================================

写在前面

上一篇里,我们学习了一些技巧来初步优化Shader。这次,我们学习很多其它的技术来实现一个更复杂的Shader:Normal-Mapped Specular Shader。这些技术包含:使用光照函数的两个新变量halfasview或者approxview,降低使用的贴图数量,以及对贴图进行更好的压缩。

准备工作

  1. 创建一个新的场景和一个球体,加入一个平行光。
  2. 创建一个新的Shader和Material,能够命名为MobileShader。
  3. 把Shader赋给Material,把Material赋给球体。

实现

  1. 首先,还是改动Properties块。本节我们须要一张diffuse贴图,它的alpha通道值相应像素的光滑度(Gloss);以及一张法线贴图,和高光指数的滑动条。
    	Properties {
    _Diffuse ("Base (RGB) Specular Amount (A)", 2D) = "white" {}
    _NormalMap ("Normal Map", 2D) = "bump"{}
    _SpecIntensity ("Specular Width", Range(0.01, 1)) = 0.5
    }

    解释:一直没有彻底搞懂Unity SurfaceOutput里面各变量的计算细节。这里再详解下。SurfaceOutput里面的内置变量能够见这篇,例如以下:

    struct SurfaceOutput {
    half3 Albedo; // 该像素的反射率,反应了像素的基色
    half3 Normal; // 该像素的法线方向
    half3 Emission; // 该像素的自发光颜色,使得即便没有光照也能够物体本身也能够发出光
    half Specular; // 该像素的高光指数
    half Gloss; // 该像素的高光光滑度,值越大高光反射越清晰,反之越模糊
    half Alpha; // 该像素的不透明度
    };
  2. 以下是建立#pragma声明。这能够控制Surface Shader各属性的开关,使得Shader更高效或者更低效:
    		CGPROGRAM
    #pragma surface surf MobileBlinnPhong exclude_path:prepass nolightmap noforwardadd halfasview

    解释忽略延迟光照,不支持光照贴图,仅仅接受一个单一的平行光光源作为逐像素光源。最后,使用halfasview声明告诉Unity,我们使用一个介于光照方向和观察方向之间的half vector来取代真正的观察方向viewDir来计算光照函数。这将加速Shader的处理时间,由于这是基于逐顶点而非逐像素计算而得的。尽管这样得到的结果是近似值,但对于移动平台来说足够了。

  3. 建立和Properties块中各变量的联系。和之前不同,我们这次使用fixed来得到高光指数滑条的值:
    		sampler2D _Diffuse;
    sampler2D _NormalMap;
    fixed _SpecIntensity;
  4. 得到贴图的UV坐标。在上一篇就提过,为了节省变量空间,我们仅使用一个UV值:
    		struct Input
    {
    half2 uv_Diffuse;
    };
  5. 由于我们在声明中加入了新的变量,我们能够在光照函数中使用新的參数:
    		inline fixed4 LightingMobileBlinnPhong (SurfaceOutput s, fixed3 lightDir, fixed3 halfDir, fixed atten)
    {
    fixed diff = max (0, dot (s.Normal, lightDir));
    fixed nh = max (0, dot (s.Normal, halfDir));
    fixed spec = pow (nh, s.Specular * 128) * s.Gloss; fixed4 c;
    c.rgb = (s.Albedo * _LightColor0.rgb * diff + _LightColor0.rgb * spec) * (atten * 2);
    c.a = 0.0;
    return c;
    }
  6. 最后,我们在surf函数中完毕对像素颜色的计算:
    		void surf (Input IN, inout SurfaceOutput o)
    {
    fixed4 diffuseTex = tex2D (_Diffuse, IN.uv_Diffuse);
    o.Albedo = diffuseTex.rgb;
    o.Gloss = diffuseTex.a;
    o.Alpha = 0.0;
    o.Specular = _SpecIntensity;
    o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_Diffuse));
    }
最后,得到的效果例如以下:

解释

我们最后总结一下使用过的全部技术:优化变量类型,共享UV坐标,降低处理的光源个数,让Shader仅仅工作在特定的渲染器上,使用近似值取代精确值,以及降低或压缩贴图。

【Unity Shaders】Mobile Shader Adjustment —— 为手机定制Shader的更多相关文章

  1. 【Unity Shaders】使用CgInclude让你的Shader模块化——创建CgInclude文件存储光照模型

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  2. 【Unity Shaders】使用CgInclude让你的Shader模块化——Unity内置的CgInclude文件

    本系列主要參考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同一时候会加上一点个人理解或拓展. 这里是本书全部的插图. 这里是本书所需的代码 ...

  3. 【Unity Shaders】使用CgInclude让你的Shader模块化——使用#define指令创建Shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  4. 【Unity Shaders】Mobile Shader Adjustment—— 什么是高效的Shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  5. Unity Shaders Vertex & Fragment Shader入门

    http://blog.csdn.net/candycat1992/article/details/40212735 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Sha ...

  6. 【Unity Shaders】Vertex & Fragment Shader入门

    写在前面 三个月以前,在一篇讲卡通风格的Shader的最后,我们说到在Surface Shader中实现描边效果的弊端,也就是只对表面平缓的模型有效.这是因为我们是依赖法线和视角的点乘结果来进行描边判 ...

  7. 【Unity Shaders】Shader学习资源和Surface Shader概述

    写在前面 写这篇文章的时候,我断断续续学习Unity Shader半年了,其实还是个门外汉.我也能体会很多童鞋那种想要学好Shader却无从下手的感觉.在这个期间,我找到一些学习Shader的教程以及 ...

  8. 【Unity Shaders】Transparency —— 透明的cutoff shader

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  9. 【Unity Shaders】Diffuse Shading——在Surface Shader中使用properties

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

随机推荐

  1. 将cocos2dx+lua创建的游戏port到windows phone

    在整个Port的过程中遇到的问题总结例如以下 1.一定要使用最新版本号的cocos2dx,原因大家看一下changelog就知道了,近期的cocos2dx版本号都是在修windows phone上的b ...

  2. Linux 的 Shell

    一个:Shell 概念 shell 这个词是不奇怪,意思是 "壳" 这是间OS 用户和芯层之间的相互作用,在linux系统.用户可以通过命令终端.使用shell 命令向下传达他们的 ...

  3. CSDN个人空间能再烂吗?

    CSDN空间你敢再烂么? 从CSDN博客跳转到CSDN个人空间的入口还算明显,可是想从个人空间跳转到博客,可真是众里寻他千百度.跳转接口怎么寻都寻不到.根本没有这个跳转的入口.唯一的途径仅仅能从写博文 ...

  4. jqm的多列布局demo,html5的多列布局demo,多列布局的具体解说,html5开发实例具体解释

    因为移动设备屏幕宽度较小,所以一般不建议使用多列布局.但有时你可能须要并排放置一些元素(如button之类的). jQuery Mobile通过约定的类名ui-grid来提供了一种基于css的多列布局 ...

  5. POJ 3579- Median

     Description Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of n ...

  6. 8年,属于 HTML 5 春天的到来悄悄!

    [核心提示] 在 8 年时间中,HTML 5 为整个行业都带来了什么.标准终于确定后又会产生什么样的变革呢? 微博微信Twitter对于非常多人来说,非常有可能在微信的朋友圈里玩过「围住神经猫」,也非 ...

  7. NSIS:迅雷5.8.6.600自由定制版脚本及下载

    原文 NSIS:迅雷5.8.6.600自由定制版脚本及下载 虽然现在迅雷已升级到7.2版本,但作为一款下载工具,我们可能只是需要它的下载功能,所以,体积小资源占用也小的迅雷5便成了我们更好的选择.今天 ...

  8. java volatile的一个验证反例(转)

    网上关于java volatile的资料已经不少了,但搜了好久也没看到谁用代码很好地验证过使不使用volatile的差异.最近自己写了个测试,意外的看到了两者的明显区别,为什么说意外呢,因为根据我的测 ...

  9. HDU4893:Wow! Such Sequence!(段树lazy)

    Problem Description Recently, Doge got a funny birthday present from his new friend, Protein Tiger f ...

  10. oracle11g ASM(修复损坏的磁盘组头asm修复2)

    --编KFED [oracle@rac2 lib]$cd $ORACLE_HOME/rdbms/lib [oracle@rac2 lib]$ pwd /u01/app/oracle/product/1 ...