Unity3D ShaderLab 使用贴图对模型的高光进行遮罩

前面研究了高光效果的实现,再说说现很多游戏用到的高光贴图技术,因为它可以让3D美工更容易控制最终的视觉效果。

这也就为我们提供了另外的方式,我们可以在同一个着色器上实现垫型表面和光亮表面,也可以使用贴图来控制镜面高光的范围或者高光强度,

以实现一个表面是广泛的镜面高光而另一面确是细小的高光。

新建一个shader,一个材质球。老规矩双击shader脚本,在编辑器中编写代码吧。

1.Properties:

Properties {

_MainTint("Diffuse Tint",Color) = (,,,)

_MainTex ("Base (RGB)", 2D) = "white" {}

_SpecularColor("Specular Tint",Color)=(,,,)

_SpecularMask("Specular Texture",2D)="white"{}

_SpecularPower("Specular Power",Range(,))=

}

2.SubShader中修改CGPROGRAM,加入输出结构体SurfaceMyOutput,修改Input结构体:

CGPROGRAM

#pragma surface surf TexPhong

sampler2D _MainTex;

float4 _MainTint;

float4 _SpecularColor;

sampler2D _SpecularMask;

float _SpecularPower;

struct SurfaceMyOutput{

fixed3 Albedo;

fixed3 Normal;

fixed3 Emission;

fixed3 SpecularColor;

half Specular;

fixed Gloss;

fixed Alpha;

};

struct Input {

float2 uv_MainTex;

float2 uv_SpecularMask;

};

3.实现自定义光照模型LightingTexPhong

inline fixed4 LightingTexPhong(SurfaceMyOutput s,fixed3 lightDir,half3 viewDir, fixed atten){

float diff = dot(s.Normal,lightDir);

float3 reflection = normalize(3.0*s.Normal*diff-lightDir);

float spec = pow(max(,dot(reflection,viewDir)), _SpecularPower)*s.Specular;

float3 finalSpec = s.SpecularColor * spec*_SpecularColor.rgb;

fixed4 c;

c.rgb = (s.Albedo*_LightColor0.rgb*diff)+(_LightColor0.rgb*finalSpec);

c.a = s.Alpha;

return c;

}

4.修改surf函数

void surf (Input IN, inout SurfaceMyOutput o) {

float4 c = tex2D (_MainTex, IN.uv_MainTex)*_MainTint;

float4 specMask = tex2D(_SpecularMask,IN.uv_SpecularMask)*_SpecularColor;

o.Albedo = c.rgb;

o.Specular = specMask.r;

o.SpecularColor = specMask.rgb;

o.Alpha = c.a;

}

修改完毕后,返回unity设置参数,最终效果如下。

在上面的代码编写过程中,我们需要将表面函数的信息传递给给光照函数,因为我们在光照函数内部不能得到一个物体表面的uv,

所以我们需要通过input结构体来访问数据,唯一途径就是使用surf函数,为了建立数据关系,我们自定义了结构体SurfaceMyOutput,

用这个结构体作为容器存储表面着色器中所有最终数据。这样光照函数和surf函数都可以访问它的内部数据。

然后,我们告诉surf函数和光照函数使用output结构体是我们自定义的SurfaceMyOutput结构体,而不是着色器内置的。

最后我们只需要使用tex2D函数就可以访问纹理讯息返回值,直接传递给SurfaceMyOutput结构体,完成了这些,我们就可以在光照函数中访问讯息纹理。

code start --------------------------------------------------------------------------

Shader "91YGame/TexPhong" {
Properties {
_MainTint("Diffuse Tint",Color) = (,,,)
_MainTex ("Base (RGB)", 2D) = "white" {} _SpecularColor("Specular Tint",Color)=(,,,)
_SpecularMask("Specular Texture",2D)="white"{}
_SpecularPower("Specular Power",Range(0.5,))=
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD CGPROGRAM
#pragma surface surf TexPhong sampler2D _MainTex;
float4 _MainTint;
float4 _SpecularColor;
sampler2D _SpecularMask;
float _SpecularPower; struct SurfaceMyOutput{
fixed3 Albedo;
fixed3 Normal;
fixed3 Emission;
fixed3 SpecularColor;
half Specular;
fixed Gloss;
fixed Alpha;
}; struct Input {
float2 uv_MainTex;
float2 uv_SpecularMask;
}; inline fixed4 LightingTexPhong(SurfaceMyOutput s,fixed3 lightDir,half3 viewDir, fixed atten){
float diff = dot(s.Normal,lightDir);
float3 reflection = normalize(3.0*s.Normal*diff-lightDir); float spec = pow(max(,dot(reflection,viewDir)), _SpecularPower)*s.Specular;
float3 finalSpec = s.SpecularColor * spec*_SpecularColor.rgb; fixed4 c;
c.rgb = (s.Albedo*_LightColor0.rgb*diff)+(_LightColor0.rgb*finalSpec);
c.a = s.Alpha;
return c;
} void surf (Input IN, inout SurfaceMyOutput o) {
float4 c = tex2D (_MainTex, IN.uv_MainTex)*_MainTint;
float4 specMask = tex2D(_SpecularMask,IN.uv_SpecularMask)*_SpecularColor;
o.Albedo = c.rgb;
o.Specular = specMask.r;
o.SpecularColor = specMask.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}

code end ---------------------------------------------------------------------------

Unity3D ShaderLab 使用贴图对模型的高光进行遮罩的更多相关文章

  1. Unity3D ShaderLab 静态贴图光照模型

    Unity3D ShaderLab 静态贴图光照模型 其实在unity的光照模型中,我们可以把光照讯息烘培进入一个2D贴图,来实现着色器的光照效果. 下面是在unity中关闭灯光和打开灯光的对比效果. ...

  2. Unity3D ShaderLab法线贴图

    Unity3D ShaderLab法线贴图 说到法线贴图,应该算是我们最常使用的一种增强视觉效果的贴图.将法线贴图的各个像素点座位模型的法线,这样我们的光照可以模拟出高分辨率的效果, 同时也保持较低的 ...

  3. Unity3D ShaderLab 立方体图的菲涅尔反射

    Unity3D ShaderLab 立方体图的菲涅尔反射 菲涅尔反射是反射类型中比较常见的一种类型,当我们的视线正对物体表面,那么反射量会明显增加, 我们几乎可以在任何支持反射类型的物体表面看到这种情 ...

  4. Unity3D ShaderLab立方体图的法线渲染

    Unity3D ShaderLab立方体图的法线渲染 某些情况下,我们希望立方体图的材质球上产生法线效果,来更多的表现细节,比如菱形花纹的玻璃,冰块的表面. 在帧数的协调下,我们可以通过input结构 ...

  5. Unity3D ShaderLab 立方体图的反射遮罩

    Unity3D ShaderLab 立方体图的反射遮罩 上一篇,简单的介绍了立方体图的反射,那么我们能不能使用一张纹理对其进行指定遮罩呢?这样美工可以更好的控制图像的效果. 我们接着使用上一篇的sha ...

  6. Unity3D ShaderLab 简单的立方体图反射

    Unity3D ShaderLab 简单的立方体图反射 反射是着色器模拟现实环境的一个关键因素,它能使我们的着色器渲染效果更加具备视觉冲击,因为他利用了我们周围的环境, 让着色器反射外界的场景信息并将 ...

  7. Unity3D ShaderLab压缩混合纹理贴图

    Unity3D ShaderLab压缩混合纹理贴图 纹理可以用于存储大量的数据,我们可以把多个图像打包存储在单一的RGBA纹理上,然后通过着色器代码提取这些元素, 我们就可以使用每个图片的RGBA通道 ...

  8. Unity3D 导入贴图、模型等资源文件时自动设置参数

    脚本继承至AssetPostprocessor, 存放在Editor目录下! using UnityEngine; using System.Collections; using UnityEdito ...

  9. Unity3D ShaderLab 漫反射卷积光照模型

    Unity3D ShaderLab 漫反射卷积光照模型 漫反射卷积[Diffuse convolution]是一个模糊立方体的过程,它保留了立方图的整体光照强度,只模糊了细节. 这种效果在我们要活得一 ...

随机推荐

  1. 模拟器的tableView的分割线不显示

    只有iOS9和iPhone6 plus模拟器上TableView分割线不会显示. 原因: 由于iPhone6 plus的分辨率较高,开发的时候同常都使用command + 3 或者 command + ...

  2. matlab c# 混合编程

    MWArray错误: matlab 64位 vs 32位 1. visual studio没有专门的64位版.但32位版可以在64位系统上面正常使用.2.安装VS2010的时候,在安装选项里面,选择了 ...

  3. ubuntu 软件安装的几种方法

    说明:由于图形化界面方法(如Add/Remove... 和Synaptic Package Manageer)比较简单,所以这里主要总结在终端通过命令行方式进行的软件包安装.卸载和删除的方法. 一.U ...

  4. jquery返回上一页面

    window.location.href=document.referrer;   返回然后刷新 window.history.back(-1);  返回不刷新

  5. c++ 普通高精减

    //c++ 普通高精减 //codevs 3115 高精度练习之减法 //内容简单,就不注释了. //注意下,&&优先级高于||. #include<cstdio>#inc ...

  6. mapreduce job提交流程源码级分析(三)

    mapreduce job提交流程源码级分析(二)(原创)这篇文章说到了jobSubmitClient.submitJob(jobId, submitJobDir.toString(), jobCop ...

  7. PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments)

    1:PowerMock.expectNew(Class<T> type, Class<?>[] parameterTypes, Object... arguments) 如果你 ...

  8. zoj2132-The Most Frequent Number

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2132 The Most Frequent Number Time Limi ...

  9. JavaScript 在函数中使用Ajax获取的值作为函数的返回值

    解决:JavaScript 在函数中使用Ajax获取的值作为函数的返回值,结果无法获取到返回值 原因:ajax默认使用异步方式,要将异步改为同步方式 案例:通过区域ID,获取该区域下所有的学校 var ...

  10. 使用rgba色实现背景色透明

    父元素css属性:background-color: #000;  background: rgba(0,0,0,.5); //现代浏览器属性,使用rgba色实现透明,对子属性不继承  filter: ...