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

【Unity Shaders and Effects Cookbook】Diffuse Shading

2015-11-09 21:24 579 查看
1. 基础的shader 写法

Shader "CookbookShaders/BasicDiffuse"
{
Properties
{
_MainTex(“Base(RGB)”,2D) = “white”{}
}

SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200

CGPROGRAM
#pragma surface surf Lambert
sampler2D _MainTex;
struct Input
{
float2 uv_MainTex;
};

void surf (Input IN, inout SurfaceOutput o)
{
float4 c;
c =  tex2D((_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}

ENDCG
}

FallBack "Diffuse"
}




Adding Properties to a Surface Shader

1 Properties 块创建UI模块,从而在UI 中控制输入Shader中的变量,就像D3D 中的set



比如 EmissiveColor ("Emissive Color", Color) = (1,1,1,1) 表示颜色,默认值(1,1,1,1)

2 接下来在Subshader中CGPROGRAM下面声明 properties 中的变量

float4 _EmissiveColor;

float4 _AmbientColor;

float _MySliderValue;

3 把放射光(Emissivecolor)+ 环境光(Ambientcolor) 相加,用pow 函数处理,指数来自UI的滑动slider

void surf (Input IN, inout SurfaceOutput o)

{

float4 c;

c = pow((_EmissiveColor + _AmbientColor), _MySliderValue);

o.Albedo = c.rgb;

o.Alpha = c.a;

}

创建一个自定义的漫反射光照模型

1. 修改#pragma,告诉Shader 使用BasicDiffu 光照模型

# pragma surface surf BasicDiffuse

2. 在SubShder中 添加下面的代码

inline float4 LightingBasicDiffuse(Surfaceoutput s, fixed3 lightDir, fixed atten)
{
float difLight = max(0, dot(s.Normal, lightDir));
float4  col;
col.rgb = s.Albedo * _LightColor0.rgb * (difLight * atten * 2);
col.a = s.Alpha;
return col;
}


其中,创建一个新的光照模型函数,有三种光照模型可以使用,如下

half4 LightingName(SurfaceOutput s, half3 lightDir, half atten) {} 不要使用viewDir

half4 LightingName(SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) 需要使用view

half4 LightingName(SurfanceOutput s, half4 light){}

dot 函数判断两个空间向量的方向是平行(1)还是垂直(-1)

创建 Half Lambert 光照模型

Half Lambert 是通过阈值调整低光区的表面光照(as a way of getting the lighting to show the surface

of an object in low-light areas)。Half Lambert光照模型是Valve公司在制作”半条命“游戏时发明的,用来给在比较暗的区域显示物体。总体来说,该光照模型提高了物体表面的漫反射光。

inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
float difLight = dot (s.Normal, lightDir);
float hLambert = difLight * 0.5 + 0.5;

float4 col;
col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2);
col.a = s.Alpha;
return col;
}


如上,Half Lambert 技术,通过 乘以0.5 ,加上0.5 , 实现把范围调整到0.5 ~ 1.0



Shader "CookbookShaders/Chapter1/HalfLambertDiffuse"
{
Properties
{
_EmissiveColor ("Emissive Color", Color) = (1,1,1,1)
_AmbientColor  ("Ambient Color", Color) = (1,1,1,1)
_MySliderValue ("This is a Slider", Range(0,10)) = 2.5
}

SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200

CGPROGRAM
#pragma surface surf BasicDiffuse
#pragma target 3.0
float4 _EmissiveColor;
float4 _AmbientColor;
float _MySliderValue;

inline float4 LightingBasicDiffuse (SurfaceOutput s, fixed3 lightDir, fixed atten)
{
float difLight = dot (s.Normal, lightDir);
float hLambert = difLight * 0.5 + 0.5;

float4 col;
col.rgb = s.Albedo * _LightColor0.rgb * (hLambert * atten * 2);
col.a = s.Alpha;
return col;
}
struct Input
{
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutput o)
{
float4 c;
c =  pow((_EmissiveColor + _AmbientColor), _MySliderValue);

o.Albedo = c.rgb;
o.Alpha = c.a;
}

ENDCG
}

FallBack "Diffuse"
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: