Skyshop.代码解析
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
};
#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
#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查询。
#ifdef MARMO_PACKED_UV
o.texcoord.zw = v.texcoord1.xy;
#endif
#ifdef MARMO_PACKED_VERTEX_COLOR
o.texcoord.zw = v.color.rg;
o.worldP.w = v.color.b;
#endif
Skyshop.代码解析的更多相关文章
- VBA常用代码解析
031 删除工作表中的空行 如果需要删除工作表中所有的空行,可以使用下面的代码. Sub DelBlankRow() DimrRow As Long DimLRow As Long Dimi As L ...
- [nRF51822] 12、基础实验代码解析大全 · 实验19 - PWM
一.PWM概述: PWM(Pulse Width Modulation):脉冲宽度调制技术,通过对一系列脉冲的宽度进行调制,来等效地获得所需要波形. PWM 的几个基本概念: 1) 占空比:占空比是指 ...
- [nRF51822] 11、基础实验代码解析大全 · 实验16 - 内部FLASH读写
一.实验内容: 通过串口发送单个字符到NRF51822,NRF51822 接收到字符后将其写入到FLASH 的最后一页,之后将其读出并通过串口打印出数据. 二.nRF51822芯片内部flash知识 ...
- [nRF51822] 10、基础实验代码解析大全 · 实验15 - RTC
一.实验内容: 配置NRF51822 的RTC0 的TICK 频率为8Hz,COMPARE0 匹配事件触发周期为3 秒,并使能了TICK 和COMPARE0 中断. TICK 中断中驱动指示灯D1 翻 ...
- [nRF51822] 9、基础实验代码解析大全 · 实验12 - ADC
一.本实验ADC 配置 分辨率:10 位. 输入通道:5,即使用输入通道AIN5 检测电位器的电压. ADC 基准电压:1.2V. 二.NRF51822 ADC 管脚分布 NRF51822 的ADC ...
- java集合框架之java HashMap代码解析
java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...
- Kakfa揭秘 Day8 DirectKafkaStream代码解析
Kakfa揭秘 Day8 DirectKafkaStream代码解析 今天让我们进入SparkStreaming,看一下其中重要的Kafka模块DirectStream的具体实现. 构造Stream ...
- linux内存管理--slab及其代码解析
Linux内核使用了源自于 Solaris 的一种方法,但是这种方法在嵌入式系统中已经使用了很长时间了,它是将内存作为对象按照大小进行分配,被称为slab高速缓存. 内存管理的目标是提供一种方法,为实 ...
- MYSQL常见出错mysql_errno()代码解析
如题,今天遇到怎么一个问题, 在理论上代码是不会有问题的,但是还是报了如上的错误,把sql打印出來放到DB中却可以正常执行.真是郁闷,在百度里面 渡 了很久没有相关的解释,到时找到几个没有人回复的 & ...
随机推荐
- 肖哥讲jquery:
jquery 是一个模块 一个库 js封装的一个库 导入jq <script src="jquery.js"></script> <script ...
- 检索式chatbot:
小夕从7月份开始收到第一场面试邀请,到9月初基本结束了校招(面够了面够了T_T),深深的意识到今年的对话系统/chatbot方向是真的超级火呀.从微软主打情感计算的小冰,到百度主打智能家庭(与车联网? ...
- 浅谈C++ STL vector 容器
浅谈C++ STL vector 容器 本篇随笔简单介绍一下\(C++STL\)中\(vector\)容器的使用方法和常见的使用技巧.\(vector\)容器是\(C++STL\)的一种比较基本的容器 ...
- SpringCloud微服务常见组件理解
概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...
- FineUIPro v6.0.1 小版本更新!
这次修正了 v6.0.0版本的几个问题,建议所有用户升级到此版本: +修正调用F.addMainTab时可能出现JS错误的问题(34484135,1450561644). -仅在未调用F.ini ...
- java基础 Unsafe
参考文章: https://tech.meituan.com/2019/02/14/talk-about-java-magic-class-unsafe.html
- 【前端知识体系-JS相关】深入理解JavaScript异步和单线程
1. 为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Jav ...
- redis集群之Sentinel
目前我们讲的 Redis 还只是主从方案,最终一致性.读者们可思考过,如果主节点凌晨3 点突发宕机怎么办?就坐等运维从床上爬起来,然后手工进行从主切换,再通知所有的程序把地址统统改一遍重新上线么?毫无 ...
- 如何保障MySQL主从复制关系的稳定性?关键词(新特性、crash-safe)
一 前言 MySQL 主从架构已经被广泛应用,保障主从复制关系的稳定性是大家一直关注的焦点.MySQL 5.6 针对主从复制稳定性提供了新特性: slave 支持 crash-safe.该功能可以解决 ...
- python asyncio run_until_complete
import asyncio def callback(loop, i): print("success time {} {}".format(i, loop.time())) a ...