文章目录
- 前言
- 一、SimpleLit片元着色器大体框架
- 1、传入 和 返回
- 2、GPU实例化部分
- 3、准备 BlinnPhong 光照模型计算需要的 SurfaceData
- 4、准备 BlinnPhong 光照模型计算需要的 InputData
- 5、进行 BlinnPhong 的计算、雾效颜色混合及透明度计算
- 二、准备SurfaceData
- 1、SurfaceData结构体包含什么:
- 2、初始化SurfaceData:
- 3、漫反射颜色及透明度计算
- 4、混合漫反射颜色 与 透明度
- 5、玻璃效果纹理采样、金属度、镜面反射颜色 及 光滑度
- 6、自发光纹理采样
- 在这里插入图片描述
- 三、准备InputData
- 1、InputData结构体包含什么
- 2、初始化InputData
- 1、法线贴图相关
- 2、视线向量计算 及计算前的向量归一化
- 3、阴影因子计算
- 4、额外灯相关计算
- 5、全局光照相关计算
- 6、光照贴图相关计算
前言
在上篇文章中,我们了解了Unity中URP下SimpleLit中的顶点着色器。
- Unity中URP下的SimpleLit顶点着色器
我们在这篇文章中,来了解一下Unity中URP下SimpleLit中的片元着色器。有助于我们之后写自己的光照Shader。
一、SimpleLit片元着色器大体框架
1、传入 和 返回
- 这里传入参数为 顶点着色器输出的Varyings结构体
- 返回结果用 out修饰来代替函数前的返回类型
2、GPU实例化部分
3、准备 BlinnPhong 光照模型计算需要的 SurfaceData
4、准备 BlinnPhong 光照模型计算需要的 InputData
5、进行 BlinnPhong 的计算、雾效颜色混合及透明度计算
由此可以看出:SimpleLit 的片元着色器中
我们最重要的部分是:
- 准备SurfaceData
- 准备InputData
- 最后 BlinnPhong 的计算
二、准备SurfaceData
1、SurfaceData结构体包含什么:
- albedo:漫反射颜色
- specular:镜面反射颜色
- metallic:金属度
- smoothness:平滑度
- normalTS:法线
- emission:自发光颜色
2、初始化SurfaceData:
3、漫反射颜色及透明度计算
- 透明度计算时,会把漫反射透明度 和 主颜色透明度进行相乘混合
- AlphaDiscard:对透明度做处理
4、混合漫反射颜色 与 透明度
- 用我们的漫反射颜色 与 主要颜色混合
- 用我们的透明度 与 输出颜色混合
5、玻璃效果纹理采样、金属度、镜面反射颜色 及 光滑度
6、自发光纹理采样
三、准备InputData
1、InputData结构体包含什么
- positionWS、positionCS:顶点在世界空间 和 齐次裁剪空间下的数据
- normalWS:世界空间下的法线数据
- viewDirectionWS:视线向量
- shadowCoord:阴影相关
- fogCoord:雾效混合因子
- vertexLighting:顶点光照颜色
- bakedGI:全局光照烘焙颜色
- shadowMask:阴影遮罩
- tangentToWorld:切线转化到世界空间的转化矩阵
2、初始化InputData
void InitializeInputData(Varyings input, half3 normalTS, out InputData inputData){inputData = (InputData)0;inputData.positionWS = input.positionWS;#ifdef _NORMALMAPhalf3 viewDirWS = half3(input.normalWS.w, input.tangentWS.w, input.bitangentWS.w);inputData.tangentToWorld = half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz);inputData.normalWS = TransformTangentToWorld(normalTS, inputData.tangentToWorld);#elsehalf3 viewDirWS = GetWorldSpaceNormalizeViewDir(inputData.positionWS);inputData.normalWS = input.normalWS;#endifinputData.normalWS = NormalizeNormalPerPixel(inputData.normalWS);viewDirWS = SafeNormalize(viewDirWS);inputData.viewDirectionWS = viewDirWS;#if defined(REQUIRES_VERTEX_SHADOW_COORD_INTERPOLATOR)inputData.shadowCoord = input.shadowCoord;#elif defined(MAIN_LIGHT_CALCULATE_SHADOWS)inputData.shadowCoord = TransformWorldToShadowCoord(inputData.positionWS);#elseinputData.shadowCoord = float4(0, 0, 0, 0);#endif#ifdef _ADDITIONAL_LIGHTS_VERTEXinputData.fogCoord = InitializeInputDataFog(float4(inputData.positionWS, 1.0), input.fogFactorAndVertexLight.x);inputData.vertexLighting = input.fogFactorAndVertexLight.yzw;#elseinputData.fogCoord = InitializeInputDataFog(float4(inputData.positionWS, 1.0), input.fogFactor);inputData.vertexLighting = half3(0, 0, 0);#endif#if defined(DYNAMICLIGHTMAP_ON)inputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.dynamicLightmapUV, input.vertexSH, inputData.normalWS);#elseinputData.bakedGI = SAMPLE_GI(input.staticLightmapUV, input.vertexSH, inputData.normalWS);#endifinputData.normalizedScreenSpaceUV = GetNormalizedScreenSpaceUV(input.positionCS);inputData.shadowMask = SAMPLE_SHADOWMASK(input.staticLightmapUV);#if defined(DEBUG_DISPLAY)#if defined(DYNAMICLIGHTMAP_ON)inputData.dynamicLightmapUV = input.dynamicLightmapUV.xy;#endif#if defined(LIGHTMAP_ON)inputData.staticLightmapUV = input.staticLightmapUV;#elseinputData.vertexSH = input.vertexSH;#endif#endif}