- 最后登录
- 2014-10-23
- 注册时间
- 2011-7-19
- 阅读权限
- 90
- 积分
- 81303
 
- 纳金币
- -1
- 精华
- 11
|
What is generated
Unity’s “surface shader code generator” would take this, generate actual vertex & pixel shaders, and compile them to various target platforms. With default settings in Unity 3.0, it would make this shader support:
■Forward renderer and Deferred Lighting (Light Pre-Pass) renderer.
■Objects with precomputed lightmaps and without.
■Directional, Point and Spot lights; with projected light cookies or without; with shadowmaps or without. Well ok, this is only for forward renderer because in Deferred Lighting the lighting happens elsewhere.
■For Forward renderer, it would compile in support for lights computed per-vertex and spherical harmonics lights computed per-object. It would also generate extra additive blended pass if needed for the case when additional per-pixel lights have to be rendered in separate passes.
■For Deferred Lighting, it would generate base pass that outputs normals & specular power; and a final pass that combines albedo with lighting, adds in any lightmaps or emissive lighting etc.
■It can optionally generate a shadow caster rendering pass (needed if custom vertex position modifiers are used for vertex shader based animation; or some complex alpha-test effects are done).
For example, here’s code that would be compiled for a forward-rendered base pass with one directional light, 4 per-vertex point lights, 3rd order SH lights; optional lightmaps (I suggest just scrolling down):
#pragma vertex vert
_
surf
#pragma fragment frag
_
surf
#pragma fragmentoption ARB
_
fog
_
exp2
#pragma fragmentoption ARB
_
precision
_
hint
_
fastest
#pragma multi
_
compile
_
fwdbase
#include "HLSLSupport.cginc"
#include "UnityCG.cginc"
#include "Lighting.cginc"
#include "AutoLight.cginc"
s***ct Input {
float2 uv
_
MainTex : TEXCOORD0;
};
sampler2D
_
MainTex;
sampler2D
_
BumpMap;
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = tex2D (
_
MainTex, IN.uv
_
MainTex).rgb;
o.Normal = UnpackNormal (tex2D (
_
BumpMap, IN.uv
_
MainTex));
}
s***ct v2f
_
surf {
V2F
_
POS
_
FOG;
float2 hip
_
pack0 : TEXCOORD0;
#ifndef LIGHTMAP
_
OFF
float2 hip
_
lmap : TEXCOORD1;
#else
float3 lightDir : TEXCOORD1;
float3 vlight : TEXCOORD2;
#endif
LIGHTING
_
COORDS(3,4)
};
#ifndef LIGHTMAP
_
OFF
float4 unity
_
LightmapST;
#endif
float4
_
MainTex
_
ST;
v2f
_
surf vert
_
surf (appdata
_
full v) {
v2f
_
surf o;
PositionFog( v.vertex, o.pos, o.fog );
o.hip
_
pack0.xy = TRANSFORM
_
TEX(v.texcoord,
_
MainTex);
#ifndef LIGHTMAP
_
OFF
o.hip
_
lmap.xy = v.texcoord1.xy * unity
_
LightmapST.xy + unity
_
LightmapST.zw;
#endif
float3 worldN = mul((float3x3)
_
Object2World, SCALED
_
NORMAL);
TANGENT
_
SPACE
_
ROTATION;
#ifdef LIGHTMAP
_
OFF
o.lightDir = mul (rotation, ObjSpaceLightDir(v.vertex));
#endif
#ifdef LIGHTMAP
_
OFF
float3 shlight = ShadeSH9 (float4(worldN,1.0));
o.vlight = shlight;
#ifdef VERTEXLIGHT
_
ON
float3 worldPos = mul(
_
Object2World, v.vertex).xyz;
o.vlight += Shade4PointLights (
unity
_
4LightPosX0, unity
_
4LightPosY0, unity
_
4LightPosZ0,
unity
_
LightColor0, unity
_
LightColor1, unity
_
LightColor2, unity
_
LightColor3,
unity
_
4LightAtten0, worldPos, worldN );
#endif // VERTEXLIGHT
_
ON
#endif // LIGHTMAP
_
OFF
TRANSFER
_
VERTEX
_
TO
_
FRAGMENT(o);
return o;
}
#ifndef LIGHTMAP
_
OFF
sampler2D unity
_
Lightmap;
#endif
half4 frag
_
surf (v2f
_
surf IN) : COLOR {
Input surfIN;
surfIN.uv
_
MainTex = IN.hip
_
pack0.xy;
SurfaceOutput o;
o.Albedo = 0.0;
o.Emission = 0.0;
o.Specular = 0.0;
o.Alpha = 0.0;
o.Gloss = 0.0;
surf (surfIN, o);
half atten = LIGHT
_
ATTENUATION(IN);
half4 c;
#ifdef LIGHTMAP
_
OFF
c = LightingLambert (o, IN.lightDir, atten);
c.rgb += o.Albedo * IN.vlight;
#else // LIGHTMAP
_
OFF
half3 lmFull = DecodeLightmap (tex2D(unity
_
Lightmap, IN.hip
_
lmap.xy));
#ifdef SHADOWS
_
SCREEN
c.rgb = o.Albedo * min(lmFull, atten*2);
#else
c.rgb = o.Albedo * lmFull;
#endif
c.a = o.Alpha;
#endif // LIGHTMAP
_
OFF
return c;
}
Of those 90 lines of code, 10 are your original surface shader code; the remaining 80 would have to be pretty much written by hand in Unity 2.x days (well ok, less code would have to be written because 2.x had less rendering features). But wait, that was only base pass of the forward renderer! It also generates code for additive pass, for deferred base pass, deferred final pass, optionally for shadow caster pass and so on.
So this should be an easier to write lit shaders (it is for me at least). I hope this will also increase the number of Unity users who can write shaders at least 3 times (i.e. to 30 up from 10!). It should be more future proof to accomodate changes to the lighting pipeline we’ll do in Unity next.
转自官方英文blog
http://blogs.unity3d.com/2010/07/17/unity-3-technology-surface-shaders/
|
|