zoukankan      html  css  js  c++  java
  • Skyshop.代码解析

    MarmosetInput.cginc:
    Input结构定义:
    struct Input
    {
           #if defined(MARMO_PACKED_UV) || defined(MARMO_PACKED_VERTEX_OCCLUSION) ||  defined(MARMO_PACKED_VERTEX_COLOR)
                  float4 texcoord;
           #else
                  float2 texcoord;
           #endif
           
           float3 worldNormal;
           
           #if defined(MARMO_SPECULAR_DIRECT) || defined(MARMO_SPECULAR_IBL)
                  float3 viewDir;
           #endif
           
           #if defined(MARMO_COMPUTE_WORLD_POS)
                  #ifdef MARMO_U5_WORLD_POS
                  float3 worldPos;     //this is free in Unity 5
                  #endif
           #else
                  float4 worldP;             //lets write our own
           #endif
           #if defined(MARMO_VERTEX_COLOR) || defined(MARMO_VERTEX_LAYER_MASK)
                  half4 color : COLOR;
           #elif defined(MARMO_VERTEX_OCCLUSION)
                  half2 color : COLOR;
           #endif
           
           #ifdef MARMO_DIFFUSE_VERTEX_IBL
                  float3 vertexIBL;
           #endif
           INTERNAL_DATA
    };

    Output结构定义:

    struct MarmosetOutput
    {
           half3 Albedo; //diffuse map RGB
           half Alpha;          //diffuse map A
           half3 Normal; //world-space normal
           half3 Emission;      //contains IBL contribution
           half Specular;       //specular exponent (required by Unity)
           #ifdef MARMO_SPECULAR_DIRECT
                  half3 SpecularRGB;   //specular mask
           #endif
    };

    Unity自带的Output结构定义:

    struct SurfaceOutput
    {
        fixed3 Albedo;
        fixed3 Normal;
        fixed3 Emission;
        half Specular;
        fixed Gloss;
        fixed Alpha;
    };
    
    // Metallic workflow
    struct SurfaceOutputStandard
    {
        fixed3 Albedo;      // base (diffuse or specular) color
        fixed3 Normal;      // tangent space normal, if written
        half3 Emission;
        half Metallic;      // 0=non-metal, 1=metal
        // Smoothness is the user facing name, it should be perceptual smoothness but user should not have to deal with it.
        // Everywhere in the code you meet smoothness it is perceptual smoothness
        half Smoothness;    // 0=rough, 1=smooth
        half Occlusion;     // occlusion (default 1)
        fixed Alpha;        // alpha for transparencies
    };
    
    // Specular workflow
    struct SurfaceOutputStandardSpecular
    {
        fixed3 Albedo;      // diffuse color
        fixed3 Specular;    // specular color
        fixed3 Normal;      // tangent space normal, if written
        half3 Emission;
        half Smoothness;    // 0=rough, 1=smooth
        half Occlusion;     // occlusion (default 1)
        fixed Alpha;        // alpha for transparencies
    };

    MarmosetDirect.cginc:
    直接光照的主要代码,去掉deferred lighting相关的代码。
    #ifndef MARMOSET_DIRECT_CGINC
    #define MARMOSET_DIRECT_CGINC
    // Core
    inline float3 wrapLighting(float DP, float3 scatter)
    {
        scatter *= 0.5;
        float3 integral = float3(1.0,1.0,1.0)-scatter;
        float3 light = saturate(DP * integral + scatter);
        float shadow = (DP*0.5+0.5);
        shadow *= shadow;
        return light * integral * shadow;
    }
    // NOTE: some intricacy in shader compiler on some GLES2.0 platforms (iOS) needs 'viewDir' & 'h'
    // to be mediump instead of lowp, otherwise specular highlight becomes too bright.
    inline half4 marmosetLighting (MarmosetOutput s, half3 viewDir, half3 lightDir, half3 lightColor)
    {
        half4 frag = half4(0.0,0.0,0.0,s.Alpha);        
        #if defined(MARMO_DIFFUSE_DIRECT) || defined(MARMO_SPECULAR_DIRECT)
            half3 L = lightDir;
            half3 N = s.Normal;
            #ifdef MARMO_HQ
                L = normalize(L);
            #endif
        #endif
            
        #ifdef MARMO_DIFFUSE_DIRECT
            half dp = saturate(dot(N,L));
            
            #ifdef MARMO_DIFFUSE_SCATTER
                float4 scatter = _Scatter * _ScatterColor;
                half3 diff = wrapLighting(dp, scatter.rgb);
                diff *= 2.0 * s.Albedo.rgb; //*2.0 to match Unity
            #else
                half3 diff = (2.0 * dp) * s.Albedo.rgb; //*2.0 to match Unity
            #endif
            frag.rgb = diff * lightColor;
        #endif
        
        #ifdef MARMO_SPECULAR_DIRECT
            half3 H = normalize(viewDir+L);
            float specRefl = saturate(dot(N,H));
            half3 spec = pow(specRefl, s.Specular*512.0);
            #ifdef MARMO_HQ
                //self-shadowing blinn
                #ifdef MARMO_DIFFUSE_DIRECT
                    spec *= saturate(10.0*dp);
                #else
                    spec *= saturate(10.0*dot(N,L));
                #endif
            #endif
            spec *= lightColor;
            frag.rgb += (0.5 * spec) * s.SpecularRGB; //*0.5 to match Unity
        #endif
        return frag;
    }
    //forward lighting
    inline half4 LightingMarmosetDirect( MarmosetOutput s, half3 lightDir, half3 viewDir, half atten )
    {
        return marmosetLighting( s, viewDir, lightDir, _LightColor0 * atten);
    }
    inline half4 LightingMarmosetDirect( MarmosetOutput s, half3 viewDir, UnityGI gi )
    {
        fixed4 c;
        c = marmosetLighting (s, viewDir, gi.light.dir, gi.light.color);
        
        #ifdef UNITY_LIGHT_FUNCTION_APPLY_INDIRECT
            c.rgb += s.Albedo * gi.indirect.diffuse;
        #endif
        return c;
    }
    inline void LightingMarmosetDirect_GI (MarmosetOutput s, UnityGIInput giInput, inout UnityGI gi)
    {
        gi = UnityGlobalIllumination(giInput, 1.0, s.Normal);
    }
    #endif

    MarmosetSurf.cginc:
    旧版本的surf代码:
    #ifndef MARMOSET_SURF_CGINC
    #define MARMOSET_SURF_CGINC
    void MarmosetSurf(Input IN, inout MarmosetOutput OUT)
    {
           #define uv_diff IN.uv_MainTex
           #define uv_spec IN.uv_MainTex
           #define uv_bump IN.uv_MainTex
           #define uv_glow IN.uv_MainTex
           //DIFFUSE
           #if defined(MARMO_DIFFUSE_DIRECT) || defined(MARMO_DIFFUSE_IBL)
                  half4 diff = tex2D( _MainTex, uv_diff );
                  diff *= _Color;
                  //camera exposure is built into OUT.Albedo
                  diff.rgb *= _ExposureIBL.w;
                  OUT.Albedo = diff.rgb;
                  OUT.Alpha = diff.a;
                  #ifdef MARMO_PREMULT_ALPHA
                         OUT.Albedo *= diff.a;
                  #endif
           #else
                  OUT.Albedo = half3(0.0,0.0,0.0);
                  OUT.Alpha = 1.0;
           #endif
           
           //NORMALS
           #ifdef MARMO_NORMALMAP
                  float3 N = UnpackNormal(tex2D(_BumpMap,uv_bump));
                  #ifdef MARMO_HQ
                         N = normalize(N);
                  #endif
                  OUT.Normal = N; //N is in tangent-space
           #else
                  //OUT.Normal is not modified when not normalmapping
                  float3 N = OUT.Normal; //N is in world-space
                  #ifdef MARMO_HQ
                         N = normalize(N);
                  #endif
           #endif
           
           //SPECULAR
           #if defined(MARMO_SPECULAR_DIRECT) || defined(MARMO_SPECULAR_IBL)
                  half4 spec = tex2D(_SpecTex, uv_spec);
                  float3 E = IN.viewDir; //E is in whatever space N is
                  #ifdef MARMO_HQ
                         E = normalize(E);
                         half fresnel = splineFresnel(N, E, _SpecInt, _Fresnel);
                  #else
                         half fresnel = fastFresnel(N, E, _SpecInt, _Fresnel);         
                  #endif
                  
                  //camera exposure is built into OUT.Specular
                  spec.rgb *= _SpecColor.rgb * fresnel * _ExposureIBL.w;
                  OUT.Specular = spec.rgb;
                  half glossLod = glossLOD(spec.a, _Shininess);
                  OUT.Gloss = glossExponent(glossLod);
                  //conserve energy by dividing out specular integral
                  OUT.Specular *= specEnergyScalar(OUT.Gloss);
           #endif
           
           //SPECULAR IBL
           #ifdef MARMO_SPECULAR_IBL
                  #ifdef MARMO_NORMALMAP
                         float3 R = WorldReflectionVector(IN, OUT.Normal);
                  #else
                         float3 R = IN.worldRefl;
                  #endif
                  #ifdef MARMO_SKY_ROTATION
                         R = mulVec3(_SkyMatrix,R); //per-fragment matrix multiply,  expensive
                  #endif
                  #ifdef MARMO_MIP_GLOSS
                         half3 specIBL = glossCubeLookup(_SpecCubeIBL, R, glossLod);
                  #else
                         half3 specIBL = specCubeLookup(_SpecCubeIBL, R)*spec.a;
                  #endif
                  OUT.Emission += specIBL.rgb * spec.rgb * _ExposureIBL.y;
           #endif
           
           //DIFFUSE IBL
           #ifdef MARMO_DIFFUSE_IBL
                  N = WorldNormalVector(IN,N); //N is in world-space
                  #ifdef MARMO_SKY_ROTATION
                         N = mulVec3(_SkyMatrix,N); //per-fragment matrix multiply,  expensive
                  #endif
                  half3 diffIBL = diffCubeLookup(_DiffCubeIBL, N);
                  OUT.Emission += diffIBL * diff.rgb * _ExposureIBL.x;
           #endif
           
           
           //GLOW
           #ifdef MARMO_GLOW
                  half4 glow = tex2D(_Illum, uv_glow);
                  glow.rgb *= _GlowColor.rgb;
                  glow.rgb *= _GlowStrength;
                  glow.a *= _EmissionLM;
                  glow.rgb += OUT.Albedo * glow.a;
                  OUT.Emission += glow.rgb * _ExposureIBL.w;
           #endif
    }
    #endif

    IBL实现的两个关键函数:

    half3 diffCubeLookup(samplerCUBE diffCube, float3 worldNormal)
    {
           half4 diff = texCUBE(diffCube, worldNormal);
           return fromRGBM(diff);
    }
    half3 specCubeLookup(samplerCUBE specCube, float3 worldRefl)
    {
           half4 spec = texCUBE(specCube, worldRefl);
           return fromRGBM(spec);
    }

        IBL.diffuse使用world normal查询,IBL.specular使用world reflection查询。

    宏定义解析:
    MARMO_DIFFUSE_SPECULAR_COMBINED 
        Diffuse/Specular合并
        _MainTex.RGBA = RGB表示Diffuse,A表示Specular强度和Gloss
    MARMO_PACKED_UV
        UV打包
    #ifdef MARMO_PACKED_UV
        o.texcoord.zw = v.texcoord1.xy;
    #endif

    MARMO_PACKED_VERTEX_COLOR
        顶点色打包
    #ifdef MARMO_PACKED_VERTEX_COLOR            
        o.texcoord.zw = v.color.rg;
        o.worldP.w = v.color.b;
    #endif
  • 相关阅读:
    第11章 接口与内部类
    第10章 多态
    API接口设计之token、timestamp、sign具体实现
    JDK 监控和故障处理工具
    分布式id生成方案
    SQL优化
    自定义对象存入Redis
    OAuth(开放授权)
    Hystrix使用
    Session机制详解
  • 原文地址:https://www.cnblogs.com/sifenkesi/p/11925153.html
Copyright © 2011-2022 走看看