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

原文地址:https://www.cnblogs.com/sifenkesi/p/11925153.html

时间: 2024-10-29 16:59:24

Skyshop代码解析的相关文章

ffmpeg代码解析

void avdevice_register_all(void){    static int initialized;    if (initialized)        return;    initialized = 1;    /* devices */    REGISTER_INOUTDEV(ALSA,             alsa);    REGISTER_INDEV   (AVFOUNDATION,     avfoundation);    REGISTER_INDEV

[nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC

一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻转状态, 即指示灯D1 以8Hz 的速率翻转状态 COMPARE0 中断中点亮指示灯D2 二.nRF51822的内部RTC结构: NRF51822 有两个RTC 时钟:RTC0,RTC1.两个RTC 均为24 位,使用LFCLK 低频时钟,并带有12 位分频器,可产生TICK.compare 和溢出

(转)Java二进制指令代码解析

转自http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html Java二进制指令代码解析 Java源码在运行之前都要编译成为字节码格式(如.class文件),然后由ClassLoader将字节码载入运行.在字节码文件中,指令代码只是其中的一部分,里面还记录了字节码文件的编译版本.常量池.访问权限.所有成员变量和成员方法等信息(详见Java字节码格式详解).本文主要简单介绍不同Java指令的功能以及在代码中如何解析二进制指令. Ja

Storm中的LocalState 代码解析

官方的解释这个类为: /** * A simple, durable, atomic K/V database. *Very inefficient*, should only be * used for occasional reads/writes. Every read/write hits disk. */ 简单来理解就是这个类每次读写都会将一个Map<Object, Object>的对象序列化存储到磁盘中,读的时候将其反序列化. 构造函数指定的参数就是你在磁盘中存储的目录,同时也作为

Java二进制指令代码解析

http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html http://blog.csdn.net/sum_rain/article/details/39892219 http://www.blogjava.net/DLevin/archive/2011/09/13/358497.html Java二进制指令代码解析 小注:去年在看<深入解析JVM>书的时候做的一些记录,同时参考了<Java虚拟机规范>.只是对指令的

[nRF51822] 12、基础实验代码解析大全 &#183; 实验19 - PWM

一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指在一个周期内,信号处于高电平的时间占整个信号周期的百分比,方波的占空比是50%. 2) 调制频率:周期的倒数. 3) 脉冲宽度:信号处于高电平的时间. 二.nRF51822的PWM产生: NRF51822 通过Timer.PPI 和GPIOTE 的配合实现PWM 的功能,由Timer 产生一个事件,

[nRF51822] 11、基础实验代码解析大全 &#183; 实验16 - 内部FLASH读写

 一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识: EN-nRF51D 开发板使用NRF51822 芯片为nRF51822-QFAA,如下图所示,共有256KBFLASH,256 页,页大小为1024 字节. NRF51822 内部FLASH 写流程如下: 三.代码解析: main: 1 int main(void) 2 { 3 ... 4 5

java集合框架之java HashMap代码解析

 java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/article/java-hashmap-java-collection.html 签名(signature) public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Se

KTV播放重要代码解析

KTV播放重要代码解析 第一步: 搭建好KTV点歌界面,然后要实现的是歌星点歌,点击窗体的Load事件写如下代码: private void FrmZhu_Load(object sender, EventArgs e) { //读取MyResource表中的图片路径,放入到imagePath变量中 string sql = "select resource_path from resource_path  where resource_id=1"; SqlConnection con