类Surface Shader 的代码
如果只是写一些类似内置渲染管线时,Surface Shader的代码. 仅需要修改以下两点
重写InputData 初始化函数(可选)
struct InputData { float3 positionWS; float4 positionCS; float3 normalWS; half3 viewDirectionWS; float4 shadowCoord; half fogCoord; half3 vertexLighting; half3 bakedGI; float2 normalizedScreenSpaceUV; half4 shadowMask; half3x3 tangentToWorld; };仅当你需要在片元着色器中修改InputData的值时,才需要重写InputData的初始化函数,对于顶点位置的修改,可以在顶点着色器中完成
重写SurfaceData 初始化函数(大部分简单效果只需要重写SurfaceData的初始化函数就行,就像我们在Surface Shader 中做的那样)
struct SurfaceData { half3 albedo; half3 specular; half metallic; half smoothness; half3 normalTS; half3 emission; half occlusion; half alpha; half clearCoatMask; half clearCoatSmoothness; };就像是 Surface Shader 中一样,将你修改后的albedo,metallic,smoothness等参数传入SurfaceData 结构
编写需要重构BRDF光照Shader
这个需求通常发生在,
需要简化BRDF光照,以减少光源计算的开销
增强BRDF的光照计算,以达到更准确的效果
需要在BRDF的基础上,叠加新的光照细节,常见于 皮肤,车漆等需要二次高光的材质
在上文的基础上,再重写 BRDF初始化函数及其结构体
重写 BRDF Data 结构体(可选)
struct BRDFData { half3 albedo; half3 diffuse; half3 specular; half reflectivity; half perceptualRoughness; half roughness; half roughness2; half grazingTerm; // We save some light invariant BRDF terms so we don't have to recompute // them in the light loop. Take a look at DirectBRDF function for detailed explaination. half normalizationTerm; // roughness * 4.0 + 2.0 half roughness2MinusOne; // roughness^2 - 1.0 };如果你只是想要在原本的pbr上再叠加新的光照效果,通常不需要重写BRDF Data,如皮肤或车漆材质的二次高光
即,如果你还需要正常的PBR效果,就无需修改PBRData结构体
重写UniversalFragmentPBR函数
Unity对PBR效果的实现都在这个函数中完成
重写GlobalIllumination函数
在GlobalIllumination函数中, 通过GlossyEnvironmentReflection提供反射,EnvironmentBRDF提供直接光照的BRDF
GlobalIllumination 函数
GlobalIllumination //计算全局光照
├─ GlossyEnvironmentReflection //计算间接反射(采样反射探针)
└─ EnvironmentBRDF //将计算出的环境反射结果与间接漫反射(BakedGI)混合,最终输出得到GlobalGILightingPhysicallyBased 函数
LightingPhysicallyBased //计算直接光照
└─DirectBRDFSpecular 计算镜面高光反射编写自定义光照效果的Shader
这个应用是最广泛的,NPR渲染,各向异性的毛发等效果
- 直接舍弃BRDF相关的代码
- 自己创建相关的光照结构体,例如 NPRData, ToonData,以对应的光照模型命名
- 重写 UniversalFragmentPBR函数, 建议改成UniversalFragmentNPR,或UniversalFragmentToon等,以对应的光照模型命名
- 重写GlobalIllumination函数
本篇核心
Unity为我们提供了一个比较完善的光照Shader框架,因此我建议沿用他们设计的框架,这有利于我们去兼容一些Unity特性
一些KeyWord
#pragma multi_compile _ _ADDITIONAL_LIGHTS_VERTEX _ADDITIONAL_LIGHTS
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _LIGHT_LAYERS
#pragma multi_compile _ _FORWARD_PLUS