概述
因为黑潮之上的场景卡通渲染的确不错,项目组觉得可以学习下他们的风格。
所以我就,你懂的,趁他们在内测期间继续用截帧工具搞起!
这次还是用到了RenderDoc。
具体分析
一、地板的渲染
主要用到了7张贴图,实际LightMap和ShadowMap都没啥用处,因为都是黑漆漆的,没有实际的数据。
主要用到的贴图为Tex0主贴图,_NormalTex法线贴图,
Tex2是比较特殊处理过的贴图,里面R通道是高光贴图,G通道是粗糙贴图,B通道没用到。
还有两个cubemap。
因为RenderDoc可以不小心看到他们的shader源码(虽然是打乱过的),所以下面对他们的代码进行分析。以下两句代码是像天书吧?其实就是diffuse color和高光颜色。
_5090 = _5013 + ((((vec3(_2803) * _2582) * 1.0) * _5070) * DirLightAttr[1].xyz);
_5089 = _5012 + ((((vec3(max(0.0, ((0.5 / max((_2803 * ((_2557 * (1.0 - _2586)) + _2586)) + (_2557 * ((_2803 * (1.0 - _2586)) + _2586)), 9.9999997473787516355514526367188e-06)) * (_2918 / ((3.1415927410125732421875 * _2928) * _2928))) * _2803)) * (vec3(clamp(50.0 * _2577.y, 0.0, 1.0) * _2853) + (_2577 * (1.0 - _2853)))) * 1.0) * _5070) * DirLightAttr[1].xyz);
漫反射颜色:
其中,_2803是NdotL,
_2582是主贴图颜色*自定义的BaseColor.xyz。
_5070是Lightmap,因为该贴图是全黑色的,代码根据判断把_5070的值设为了1,不用管。
DirLightAttr[1].xyz是灯光颜色。
那么 其实就是float3 diffuseCol = NdotL*Tex0.rgb*BaseColor.xyz*DirLightAttr[1].xyz;
高光颜色:
根据研究PBR的经验,一看就看到了
(_2918 / ((3.1415927410125732421875 * _2928) * _2928)
这个不就是a2 / (UNITY_PI * (val * val));吗?
也就是BRDF的 DTerm的公式。
half BRDF_DTerm(float NdotH, float i_roughness) {
//DGGX = a^2 / π((a^2 – 1) (n · h)^2 + 1)^2
float a2 = i_roughness * i_roughness;
float val = ((a2 - 1) * (NdotH * NdotH) + 1);
return a2 / (UNITY_PI * (val * val));
}
然后
(0.5 / max((_2803 * ((_2557 * (1.0 - _2586)) + _2586)) + (_2557 * ((_2803 * (1.0 - _2586)) + _2586))
不就是
0.5 / ((NdotL * (1 - k) + k) + (NdotV * (1 - k) + k));吗?
half BRDF_GTerm(float NdotL, float NdotV, float i_roughness) {
//G(l,v,h)=1/(((n·l)(1-k)+k)*((n·v)(1-k)+k))
float k = i_roughness * i_roughness / 2;
return 0.5 / ((NdotL * (1 - k) + k) + (NdotV * (1 - k) + k));
}
也就是说,他们是使用了 BRDF (双向反射分布函数),也就是标准PBR的高光公式。
哈哈哈哈,真是服了。这可能就是工作多年的直觉吧。
那么,知道了他们的做法后,其实不需要他们的代码,我们自己写一个PBR的代码,再使用他们的模型和贴图,照样可以模拟出他们类似的效果。
上面是在unity里,经过自己参数的地面效果,下面是黑潮之上的,我是不知道为什么,即使是同一份代码,
同样的参数,他们的渲染效果颜色可以那么纯,实际他们的主贴图颜色和渲染的颜色差别非常大。
有人就问了,人家游戏里就这效果?哪里二次元了?
后处理
哦,经过截帧工具,我看到了别人还有个后处理的公式,这个公式简直神了。
经过和美术的讨论,作用是提升色阶的。
fixed4 frag(v2f i) : SV_Target
{
fixed4 _118 = tex2D(_MainTex, i.uv);
float3 _128 = _118.xyz * Param0.x;
float3 _134 = (_128 / (_128 + (float3)(0.187))) * 1.03499996662139892578125;
return fixed4(_134.x, _134.y, _134.z, 1);
}
能将我上面的场景瞬间变成
或者调整参数,更亮
这下子场景就有点像二次元了。不过可能因为我或者截帧工具看不到一些其他的信息,所以和黑潮之上的
最终场景渲染效果还是有一定的距离,也有可能他们不是用unity来做的,而是自己研发的引擎。
但是他们的做法,我们倒是明白了。
因为版权原因,他们的资源就不上传了,感兴趣的自己用截帧工具看看哈。
这里只上传地板渲染和后处理的shader代码。
下篇文章会分析他们的炫酷的建筑渲染。
下篇文章传送门:Unity复刻《黑潮之上》场景渲染(二)
源码下载:
链接:https://pan.baidu.com/s/1_mRYlSb4qg5OjlsobBSZUw
提取码:iy74