有朋友私信我问我为啥很久不更新博客,是不是转行了...我当然不可能承认自己懒啊,只能回复说太忙了.不过项目开发中,确实很难有时间和心力去总结和思考一些东西,不过现在忙完一些项目以后,我又回来了.
渲染技术这个东西,在项目前期我并没有投入太多精力去思考,在当时的环境下我更看中手游的性能,我做端游,可以无限地挖掘电脑的性能,比如多线程去处理角色的软件蒙皮之类,但是做手游,则要保护手机的硬件资源,防止手机耗电快发热.比如限帧30fps.直到两年前经历了一次美术和技术的撕逼以后,我才重新思考了一下这个东西.整个过程也很有趣,老板觉得游戏画面不行,其实是美术做得不好,但是美术领导用了一堆次世代的技术名词来忽悠老板说我们技术不行,啥都不支持...一个页游公司的美术整天吹嘘次世代我也是醉了,真正做过次世代的我反而成了外行...次世代本身就是个大坑,手游上投入的性价比更低,很多大点的公司都深陷次世代的泥潭,我要对游戏的技术负责和把关,撕逼是难免的.但是撕逼归撕逼,想要画面好是大家的共同心愿,能不能在保证效率和投入性价比的情况下,提升一些画面呢?
我的想法是,一些牛逼技术是一定是要有的,如果性能有问题,那么尽量优化,甚至限制性的使用,有总比没有好,不管是为了应付美术,还是老板,当然这不是我的初衷.我作为一个热爱引擎的程序员,画面好本身就是我们追求的东西.做技术的一定要有追求.
然后对整个渲染技术架构思考了几天,做出了一个大胆的想法,就是升级Unity4到Unity5,然后放弃Unity自带的surface shader和实时光照,利用Unity5新增的shader_feature功能自己写一套比较万能通用的standard shader,而避免整个项目一堆乱七八糟混乱的shader.至于为什么要这么干,主要原因有几个.
1.角色的动态光照,用全局shader参数来模拟灯光,比在Unity场景里面摆几个光源的效率更高一些.
2.surface shader的一些默认的定制会占据一些texture interpolator,对于我实现扩展一些效果有限制.而且不够清爽.
3.一些特殊效果需要场景所有对象shader的支持,比如天气系统的渐变过渡.如果所有shader都自己写的,那会特别方便.
4.Unity4的时候,光照图和Unity的动态光源是不能叠加的,如果自己实现的动态光源,就可以叠加的,当然Unity5后来是可以叠加的.
我这套shader基本涵盖了场景中的所有对象:
1.物件用SceneStandard.shader(有PBR版本)
2.角色用CharacterStandard.shader(有PBR版本)
3.粒子用ParticleStandard.shader
4.天空用SkyBox.shader
5.地形用TerrainT4M.shader
6.水面用Water.shader
7.小草用Grass.shader
整个场景的光照方案,场景用光照图 + 全局shader光源,角色用全局shader光源 + projector shadowmap.对于角色和场景,都有两套shader,一套传统光照模型,一套PBR光照模型.
以一个传统光照模型的SceneStandard.shader来说.
Shader "Luoyinan/Scene/SceneStandard"
{
Properties
{
_Color ("Main Color", Color) = (1, 1, 1, 1)
_MainTex("Main Texture RGB(Albedo) A(Gloss & Alpha)", 2D) = "white" {}
_NormalTex("Normal Texture", 2D) = "bump" {}
_GlossTex ("Gloss Texture", 2D) = "white" {}
_HalfLambert("Half Lambert", Range (0.5, 1)) = 0.75
_SpecularIntensity("Specular Intensity", Range (0, 2)) = 0
_SpecularSharp("Specular Sharp",Float) = 32
_SpecularLuminanceMask("Specular Luminance Mask", Range (0, 2)) = 0
}
SubShader
{
Tags
{
"Queue" = "Background"
"RenderType" = "Opaque" // 支持渲染到_CameraDepthNormalsTexture
}
Pass
{
Lighting Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fog
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
#pragma shader_feature _NORMAL_MAP
#pragma shader_feature _LUMINANCE_MASK_ON
#pragma multi_compile LIGHTMAP_OFF LIGHTMAP_ON
#pragma multi_compile __ _FADING_ON
#pragma multi_compile __ _POINT_LIGHT
#pragma multi_compile __ _FANCY_STUFF
struct appdata_lightmap
{
float4 vertex : POSITION;
half2 texcoord : TEXCOORD0;
half2 texcoord1 : TEXCOORD1;
#if _FANCY_STUFF
half3 normal : NORMAL;
#if _NORMAL_MAP
half4 tang