[UnityShader2]頂點片段著色器例項(六)
阿新 • • 發佈:2019-01-31
1.棋盤效果
cg函式:floor(x),返回不大於x的最大整數
cg函式:frac(x),返回x的小數部分
原理:
a.在頂點程式中,uv的範圍為(0,_Density)
b.在片段程式中,對uv取整然後除以2,得到的數類似為:0 / 0.5 / 1 / 1.5 / 2 /等,x和y相加取小數,要麼0,要麼0.5,乘以2後要麼0,要麼1,即達到要麼黑要麼白的效果。
Shader "Unlit/Checkerboard" { Properties { _Density ("Density", Range(2,50)) = 30 } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; float _Density; v2f vert (float4 pos : POSITION, float2 uv : TEXCOORD0) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, pos); o.uv = uv * _Density; return o; } fixed4 frag (v2f i) : SV_Target { float2 c = i.uv; c = floor(c) / 2; float checker = frac(c.x + c.y) * 2; return checker; } ENDCG } } }
2.
Shader "Unlit/Triplanar" { Properties { _MainTex ("Texture", 2D) = "white" {} _Tiling ("Tiling", Float) = 1.0 _OcclusionMap("Occlusion", 2D) = "white" {} } SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag struct v2f { half3 objNormal : TEXCOORD0; float3 coords : TEXCOORD1; float2 uv : TEXCOORD2; float4 pos : SV_POSITION; }; float _Tiling; v2f vert (float4 pos : POSITION, float3 normal : NORMAL, float2 uv : TEXCOORD0) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, pos); o.coords = pos.xyz * _Tiling; o.objNormal = normal; o.uv = uv; return o; } sampler2D _MainTex; sampler2D _OcclusionMap; fixed4 frag (v2f i) : SV_Target { // use absolute value of normal as texture weights half3 blend = abs(i.objNormal); // make sure the weights sum up to 1 (divide by sum of x+y+z) blend /= dot(blend,1.0); // read the three texture projections, for x,y,z axes fixed4 cx = tex2D(_MainTex, i.coords.yz); fixed4 cy = tex2D(_MainTex, i.coords.xz); fixed4 cz = tex2D(_MainTex, i.coords.xy); // blend the textures based on weights fixed4 c = cx * blend.x + cy * blend.y + cz * blend.z; // modulate by regular occlusion map c *= tex2D(_OcclusionMap, i.uv); return c; } ENDCG } } }
3.簡單的漫反射
a.我們可以通過宣告pass中的“LightMode”這個tag,從而告訴unity我們需要什麼光照資訊。unity預設的渲染管線是正向渲染。
b.[NoScaleOffset] - material inspector will not show texture tiling/offset fields for texture properties with this attribute.
具體計算原理:http://blog.csdn.net/lyh916/article/details/50906272
Shader "Lit/Simple Diffuse" { Properties { [NoScaleOffset] _MainTex ("Texture", 2D) = "white" {} } SubShader { Pass { // indicate that our pass is the "base" pass in forward // rendering pipeline. It gets ambient and main directional // light data set up; light direction in _WorldSpaceLightPos0 // and color in _LightColor0 Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" // for UnityObjectToWorldNormal #include "UnityLightingCommon.cginc" // for _LightColor0 struct v2f { float2 uv : TEXCOORD0; fixed4 diff : COLOR0; // diffuse lighting color float4 vertex : SV_POSITION; }; v2f vert (appdata_base v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = v.texcoord; // get vertex normal in world space half3 worldNormal = UnityObjectToWorldNormal(v.normal); // dot product between normal and light direction for // standard diffuse (Lambert) lighting half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); // factor in the light color o.diff = nl * _LightColor0; return o; } sampler2D _MainTex; fixed4 frag (v2f i) : SV_Target { // sample texture fixed4 col = tex2D(_MainTex, i.uv); // multiply by lighting col *= i.diff; return col; } ENDCG } } }
4.帶環境光的漫反射
Shader "Lit/Diffuse With Ambient"
{
Properties
{
[NoScaleOffset] _MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Pass
{
Tags {"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
struct v2f
{
float2 uv : TEXCOORD0;
fixed4 diff : COLOR0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata_base v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
half3 worldNormal = UnityObjectToWorldNormal(v.normal);
half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz));
o.diff = nl * _LightColor0;
// the only difference from previous shader:
// in addition to the diffuse lighting from the main light,
// add illumination from ambient or light probes
// ShadeSH9 function from UnityCG.cginc evaluates it,
// using world space normal
o.diff.rgb += ShadeSH9(half4(worldNormal,1));
return o;
}
sampler2D _MainTex;
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
col *= i.diff;
return col;
}
ENDCG
}
}
}