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

Unity shader学习之Forward Rendering Path

2017-07-17 15:23 393 查看
Forward rendering path

shader如下:

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/Forward Rendering"
{
Properties
{
_MainTex("Main Texture", 2D) = "white" {}
_Specular("Specular", Color) = (1,1,1,1)
_Gloss("Gloss", Range(8,256)) = 8
}

SubShader
{
Pass
{
Tags
{
"LightMode" = "ForwardBase"
}

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase

#include "UnityCg.cginc"
#include "Lighting.cginc"

sampler2D _MainTex;
fixed4 _Specular;
float _Gloss;

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};

struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
float4 worldPos: TEXCOORD2;
};

v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
return o;
}

fixed4 frag(v2f i) : SV_TARGET
{
fixed4 albedo = tex2D(_MainTex, i.uv);
fixed4 ambient = albedo * UNITY_LIGHTMODEL_AMBIENT;

float3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos.xyz));
float3 worldView = normalize(UnityWorldSpaceViewDir(i.worldPos.xyz));
fixed4 diff = albedo * _LightColor0 * max(0, dot(i.worldNormal, worldLight));

float3 halfDir = normalize(worldView + worldLight);
fixed4 spec = albedo * _Specular * pow(max(0, dot(halfDir, i.worldNormal)), _Gloss);

fixed4 col = ambient + diff + spec;
return col;
}

ENDCG
}

Pass
{
Tags
{
"LightMode" = "ForwardAdd"
}
Blend One One

CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd

#include "UnityCg.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"

sampler2D _MainTex;
fixed4 _Specular;
float _Gloss;

struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal : NORMAL;
};

struct v2f
{
float4 pos : SV_POSITION;
float2 uv : TEXCOORD0;
float3 worldNormal : TEXCOORD1;
float4 worldPos: TEXCOORD2;
};

v2f vert(appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.worldPos = mul(unity_ObjectToWorld, v.vertex);
return o;
}

fixed4 frag(v2f i) : SV_TARGET
{
fixed4 albedo = tex2D(_MainTex, i.uv);

float3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos.xyz));
float3 worldView = normalize(UnityWorldSpaceViewDir(i.worldPos.xyz));
fixed4 diff = albedo * _LightColor0 * max(0, dot(i.worldNormal, worldLight));

float3 halfDir = normalize(worldView + worldLight);
fixed4 spec = albedo * _Specular * pow(max(0, dot(halfDir, i.worldNormal)), _Gloss);

// 参考 AutoLight.cginc
float atten;
#ifdef USING_DIRECTIONAL_LIGHT
atten = 1;
#else
float4 lightCoord = mul(unity_WorldToLight, i.worldPos);
#ifdef POINT
atten = tex2D(_LightTexture0, dot(lightCoord.xyz,lightCoord.xyz).xx).UNITY_ATTEN_CHANNEL;
#elif SPOT
atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).xx).UNITY_ATTEN_CHANNEL;
#endif
#endif

fixed4 col = (diff + spec) * atten;
return col;
}

ENDCG
}
}

Fallback "VertexLit"
}


计算衰减因子的代码:

float atten;
#ifdef USING_DIRECTIONAL_LIGHT
atten = 1;
#else
float4 lightCoord = mul(unity_WorldToLight, i.worldPos);
#ifdef POINT
atten = tex2D(_LightTexture0, dot(lightCoord.xyz,lightCoord.xyz).xx).UNITY_ATTEN_CHANNEL;
#elif SPOT
atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).xx).UNITY_ATTEN_CHANNEL;
#endif
#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: