本系列主要參考《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. JSON 数据使用

    当用不同的数据的模板需要更换时.假设数据点的量.使用json非常方便. json物: var JSONObject= { "name":"Bill Gates" ...

  2. JBoss配置解决高并发连接异常问题(转)

    这两天一个项目在做压力测试的时候,发现只要并发数超过250个,连续测试两轮就会有连接异常出现,测试轮数越多出现越频繁,异常日志如下: Caused by: com.caucho.hessian.cli ...

  3. C# 判断文件的真实格式

    为了防止图片木马,通过后缀判断文件的格式是不准确的.可以通过这种方式进行判断. static void Main(string[] args) { string path = @"C:\Us ...

  4. swift类名称显示变量

    <span style="background-color: rgb(255, 255, 255); color: rgb(51, 51, 51); font-family: Aria ...

  5. XCL-Charts画一个图(CurveChart)

    情节线图与往常不同的是,它是一个比较特殊线位置计算.所以我得到一个单独的类.相同.只需要输入数据源的基类, 加,控制要添加的.你可以画出你自己主动设置按照预期的效果. 代码: //图基类 chart ...

  6. C++学习笔记13-类继承

    1.  类模板的 static 成员[不同于C#中的static] 类模板能够像随意其它类一样声明static 成员.下面代码: template <class T> class Foo ...

  7. LeetCode 48 Anagrams

    Given an array of strings, return all groups of strings that are anagrams. Note: All inputs will be ...

  8. Bootstrap(2)整体架构

    Bootstrap(2)整体架构 大多数Bootstrap的使用者都认为Bootstrap只提供了CSS组件 和JavaScript插件,其实CSS组件和JavaScript插件只是Bootstrap ...

  9. jQuery.reveal弹出层

    jQuery.reveal弹出层使用 最近用到弹出层,还得自定义UI,原本用的artDialog太庞大,不合适了,于是就找到了这个东西,又小又好用,基础的弹出遮罩都有了,想要什么还不是Coder自己说 ...

  10. Display Database Image using MS SQL Server 2008 Reporting Services

    原文 Display Database Image using MS SQL Server 2008 Reporting Services With the new release of MS SQL ...