您的位置:首页 > 移动开发 > Unity3D

Unity Shader 表面着色器边缘光(Rim Lighting)二

2015-10-08 23:34 519 查看
这一节我们要实现下面的效果



(图一)



(图二)

首先针对图一我们创建一个材质,并把颜色改成红色的,然后我们就得到了一个很普通的红色小球。



我们只需要在鼠标进入的时候把材质的Shader换成带边缘光的Shader就行了。

我们新建一个c#文件取名为ShowSelected.cs.然后把这个脚本文件赋值给小球。

我们来看一下ShowSelected.cs中的代码,几乎每一句都有注释:

using UnityEngine;
using System.Collections;

public class ShowSelected : MonoBehaviour {

public Shader selectedShader;
public Color outterColor;

private Color myColor ;
private Shader myShader;
private bool Selected = false;

// Use this for initialization
void Start () {
//保存原来的颜色值和shader,以便鼠标移出时恢复
myColor = GetComponent<Renderer>().material.color;
myShader = GetComponent<Renderer>().material.shader;
//鼠标移入时要使用的shader
selectedShader = Shader.Find("Custom/Rim Lighting2");
if(!selectedShader)
{
enabled = false;
return;
}
}
//鼠标进入
void OnMouseEnter() {
//替换Shader
GetComponent<Renderer>().material.shader = selectedShader;
//设置边缘光颜色值
GetComponent<Renderer>().material.SetColor("_RimColor",outterColor);
//设置纹理颜色值
GetComponent<Renderer>().material.SetColor("_MainColor",myColor);
}
//鼠标移出
void OnMouseExit(){
//恢复颜色值
GetComponent<Renderer>().material.color = myColor;
//恢复shader
GetComponent<Renderer>().material.shader = myShader;
}
}


我们来看一下带边缘光的Shader的代码:

Shader "Custom/Rim Lighting2" {
//属性域
Properties {
//纹理颜色
_MainColor ("Main Color", Color) = (1,1,1,1)
//主纹理属性
_MainTex ("Texture", 2D) = "white" {}
//法线贴图纹理属性
_BumpMap ("Bumpmap", 2D) = "bump" {}
//边缘光颜色值
_RimColor ("Rim Color", Color) = (1,1,1,1)
//边缘光强度值
_RimPower ("Rim Power", Range(0.5,8.0)) = 3.0
}
SubShader {
//标明渲染类型是不透明的物体
Tags { "RenderType" = "Opaque" }
//标明CG程序的开始
CGPROGRAM
//声明表面着色器函数
#pragma surface surf Lambert
//定义着色器函数输入的参数Input
struct Input {
//主纹理坐标值
float2 uv_MainTex;
//法线贴图坐标值
float2 uv_BumpMap;
//视图方向
float3 viewDir;
};
//声明对属性的引用
float4 _MainColor;
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _RimColor;
float _RimPower;
//表面着色器函数
void surf (Input IN, inout SurfaceOutput o) {
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);

//赋值颜色信息
o.Albedo = tex.rgb * _MainColor.rgb;
//赋值法线信息
o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal));
//赋值自发光颜色信息
o.Emission = _RimColor.rgb * pow (rim, _RimPower);
}
//标明CG程序的结束
ENDCG
}
Fallback "Diffuse"
}


这样就可以实现图一中的效果了

我们来看看图二的效果是怎么实现的

同样我们新建一个C#文件,取名为ShowSelectedBump.cs,我们来看一下这个CS文件中的代码,同样每一句都有注释

using UnityEngine;
using System.Collections;

public class ShowSelectedBump : MonoBehaviour {

public Shader selectedShader;
public Color outterColor;

private Color myColor ;
private Shader myShader;
private SkinnedMeshRenderer sRenderer;
private bool Selected = false;

// Use this for initialization
void Start () {
sRenderer = GetComponentInChildren<SkinnedMeshRenderer>();
//保存原来的颜色值和shader,以便鼠标移出时恢复
myColor = sRenderer.material.color;
myShader = sRenderer.material.shader;
//鼠标移入时要使用的shader
selectedShader = Shader.Find("Custom/RimLightSpecBump");
if(!selectedShader)
{
enabled = false;
return;
}
}

//鼠标进入
void OnMouseEnter() {
//替换Shader
sRenderer.material.shader = selectedShader;
//设置边缘光颜色值
sRenderer.material.SetColor("_RimColor",outterColor);
//设置纹理颜色值
sRenderer.material.SetColor("_MainColor",myColor);
}
//鼠标移出
void OnMouseExit(){
//恢复颜色值
sRenderer.material.color = myColor;
//恢复shader
sRenderer.material.shader = myShader;
}

}
我们看到处理动画模型的ShowSelectedBump.cs和ShowSelected.cs唯一不同的是这一句代码

sRenderer = GetComponentInChildren<SkinnedMeshRenderer>();


只是获取模型的渲染组件不同而已,我们的shader文件用的是同一个。

这样就可以很方便的实现图二的效果了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: