纳金网

标题: Unity 3 technology – Surface Shaders(二) [打印本页]

作者: 会飞的鱼    时间: 2011-11-25 15:22
标题: Unity 3 technology – Surface Shaders(二)




           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/
         

作者: tc    时间: 2012-1-19 23:00
鉴于你今年的良好表现,新年将至,别人都在祝福你新年快乐,我觉得换一种新颖的方式祝福你,那就是:天天开心,事事顺利,雷打不动的祝福属于你!

作者: 奇    时间: 2012-4-18 23:21
凡系斑竹滴话要听;凡系朋友滴帖要顶!

作者: 菜刀吻电线    时间: 2012-5-7 23:18
佩服,好多阿 ,哈哈

作者: tc    时间: 2012-11-4 23:23
真不错,全存下来了.

作者: 奇    时间: 2013-2-20 23:35
加精、加亮滴铁子,尤其要多丁页丁页

作者: C.R.CAN    时间: 2013-2-28 23:18
发了那么多,我都不知道该用哪个给你回帖了,呵呵





欢迎光临 纳金网 (http://go.narkii.com/club/) Powered by Discuz! X2.5