Skip to content
woctordho edited this page Aug 23, 2023 · 9 revisions

关于shader的说明

Nova的转场(transtrans2)和特效(vfx)的实现方式是用MaterialPool动态创建带有相应shader的material,添加到sprite或者摄像机上。

Shader的特殊property

  • _MainTex:要显示的图像本身
    • 对于第一类转场(trans),_MainTex是转场后的图像
  • _SubTex:用于第一类转场,转场前的图像
    • 把第一类转场应用到摄像机时,先把转场前摄像机拍下的图像截图,设为_SubTex,再把场景设置成转场后的状态,_MainTex就是此时摄像机拍下的图像
  • _SubColor:用于第一类转场,转场前的颜色(转场后的颜色由frag中的i.color输入)
  • _T:控制特效的显示程度,0为完全不显示,1为完全显示
    • 对于第一类转场,_T从1变到0,_T = 1时显示_SubTex_T = 0时显示_MainTex
    • 对于第二类转场,先把_T从0变到1,再把_MainTex换成转场后的图像,再把_T从1变到0
    • vfx动画一般只需要控制_T,如果需要分别控制各个property,可以用vfx_multi

Shader proto与shader variant

我们需要把每个shader复制成多个变种(variant),并且比Unity提供的shader variant更加灵活。因此我们先给每个shader编写一个模板,称为shader proto,然后用Tools/Resources/generate_shaders.py生成正式的shader文件。

Shader proto放在Assets/Nova/ShaderProtos/文件夹下,生成的shader放在Assets/Nova/Resources/Shaders/文件夹下。

generate_shaders.py同时会parse所有shader的property,保存到Assets/Nova/Sources/Generated/ShaderInfoDatabase.csAssets/Nova/Lua/shader_info.lua,用于在C#和Lua代码中读取这些metadata。

Shader variant有如下几种:

  • Default:用于sprite,普通的shader,与背景按照alpha混合,在输出前会把RGB乘上alpha
  • Multiply:用于sprite,与背景混合时变暗
  • Screen:用于sprite,与背景混合时变亮
  • PP:用于摄像机的post processing stack,没有需要混合的背景,_MainTex的RGB已经与alpha相乘,会根据画面缩放来调整模糊半径等参数
  • Premul:用于渲染流程,_MainTex的RGB已经与alpha相乘

如果shader proto的第一行是VARIANTS: 某些variant,用英文逗号分隔(比如ShowSecondTexture.shaderproto),则只会生成那些variant,否则默认生成所有variant。

Shader proto中还有一些关键词会被替换,实现详见generate_shaders.py

  • $VARIANT_NAME$:Unity的shader名称中的variant部分
  • $VARIANT_TAGS$:variant对应的混合模式
  • $DEF_IADD_RGBA$:定义宏IADD_RGBA,对于PP和Premul,展开成x.rgb += x.a * y.rgb; x.a += y.a
    • 对于其他variant,展开成x += y
  • $VARIANT_RGB$:对于Default、Multiply和Screen,在输出颜色之前把alpha应用到RGB通道
    • 对于其他variant,什么都不做
  • $DEF_GSCALE$:对于PP,定义变量_GScaleRenderManager会将它设为画面的缩放倍数
    • 对于其他variant,什么都不做
  • $GSCALE$:对于PP,替换为_GScale,用于根据画面缩放来调整模糊半径等参数
    • 对于其他variant,替换为1.0
Clone this wiki locally