XDGE Render_ShaderMode_Transmi(一) 光透射着色1
XDRender_ShaderMode_Transmi(一) 光透射着色1
前言
理论点:https://www.cnblogs.com/BaiPao-XD/p/13789743.html
1、这里我关注的是BTDF的部分,并采取最理想的情况,来观察和选取不同的着色模型。
2、其中ShaderMode单独实现一个, 并参与到ObjectRenderPass
3、由于这里是初步开始, 所以我建立的多个选项, 根据ShaderFeature做不同选择来实验不同的透射衰减
4、本章大约有N小节,这里为透射入门部分,每个实现模式均是一个透射部分的变体。
转载请说明来源(白袍小道)
!!小道下山了哦 -——!
正文
一、最简化的BTDF模拟
首先明确一下BTDF、BSDF、BSSRDF
1、BTDF、BSDF、BSSRDF
三者关系可以用一张图来说明问题,
2、BTDF的含义
这里我们关注的BTDF为透射部分,明确一下BTDF
BTDF | |
---|---|
含义 | 穿越介质的那部分光照的辐射亮度和辐射照度的比例就被称之为双向透射分布函数 |
图 | |
关注 | 光穿过后的部分的分布情况,一个关注点是衰减过程,一个关注点是出来后的分布 |
3、最理想情况
透射出的部分的强度,是一种均匀只和该光路的入射点和透射出的点距离相关,换句话说BSSRDF那部分简化了。
有了以上几个前提,我们在回过头关注下比较理想BTDF的模型。
分布
这里还是可以用BRDF变形来做
衰减
在知识点图中出现的透射率Transmittance,就是为了搞这里
到这里为止,我们明确了要FIX调的东西。
二、最简化透射
具体的解释参考:https://www.cnblogs.com/BaiPao-XD/p/13789743.html中的透射率部分。
先不关心具体实现,我们来看影响因子,然后用最简化简化简化简化的方式先搞一个出来,找点感觉。
1、Visibility Function
一个内部遮挡,既然是最简化我们PASS掉或者理想化掉(人话:who are you 哈哈)
2、相位函数
宏观上光线在介质中经过散射到各方向上的概率分布。既然是最简化我们PASS掉或者理想化掉(人话:who are you 哈哈)
3、光的方向,位置
这个可以整
4、辐射强度关于位置的距离的变化函数,
这个我们用最最最Easy方式,距离比。
确定了我们第一个需要搞定的是距离变化影响的辐射强度
1、第一种扁球的理想距离
就是类似扁球的模型,这个厚度就是边缘薄中间厚
这里的描述是站在光源的角度LightDir和NormalDir(注意是透射),ViewDir是参与分布而不是这里.
2、第二种通过光空间下这点的前后深度偏移来求厚度,从而搞定距离
3、视线方向的深度来查找
(也可以把颜色单独出来,查找的图只保存一个数值曲线变化)
4、其他简单变体
这里变体还是指的是利用距离来引起一些列变化。
三、实现
a、渲染阶段仅为为ObjectRenderPass的不透明PASS
透射不一定是透明,嘿嘿,莫要混淆。
b、确定ShaderMode,并加入到PASS中
c、开整
由于篇幅问题,这里就先列举第一个也是图中的。一种最最最SX的方式,看着像其实完全不符合,不过凑合来吧。
1、扁球的理想距离的第一种方式(最最最简单的变化)
XDArt_RenderLightFunction.hlsl
这里我写了一个GGX_DirectLightTransmis_T001
对BRDF高光部分减弱下,然后多出一个透射
float QtRange = 0.8 ;
float srcnl = dot(normal, lightDir);
//这里也可以只要背光部分
srcnl = srcnl * vSpecTerm_F;
srcnl = srcnl >QtRange? QtRange:srcnl;
srcnl = srcnl <-QtRange? -QtRange:srcnl;
srcnl = srcnl>0? QtRange - srcnl : QtRange + srcnl;
srcnl = srcnl * 1 / QtRange;
srcnl = srcnl * srcnl;
float3 DirectLightResult = kd * diffColor + (1.0-srcnl)* specColor + trmiscolor * srcnl;
XDArt_RenderLight_BSSRDF.hlsl
这里命名有问题,但想到BSDF经常会BSSRDF就写一块了
我就简单对DirectLight搞搞:XDSimpleFragment_TransmiLit01
///------------直接光照部分--------------------
{
for (int i = 0; i < GetDirectionalLightCount(); i++)
{
vLight = GetDirectionalLight (i);
lightDir= normalize(vLight.direction).xyz;
lightColor= vLight.color;
float3 trmiscolor = emission.rgb;
DirectLightResult += GGX_DirectLightTransmis_T001(
lightColor,
trmiscolor,
normal,lightDir,viewDir,Albedo,roughness,Metallic,
F0);
}
}
XDArt_ShaderMode_TransmittanceLit.shader
选用TransmiLit01,输入部分随意
Pass
{
Name "TransmittanceLit"
Tags {"LightMode" = "DefaultLitTransmitance"}
HLSLPROGRAM
#include "../ShaderLibrary/Simple/XDArt_ShaderMode_DefaultLitTransnis.hlsl"
#pragma multi_compile __ _DIFFCUSE_MAP
#pragma multi_compile __ _NORMALMAP
#pragma vertex DefaultLitTransmis_Vertex
#pragma fragment DefaultLitTransmiLit01_Fragment
ENDHLSL
}
Pass
{
Name "DepthOnly"
Tags {"LightMode" = "DepthOnly"}
XDArt_CustomTransmittanceLitTT.shader
一个扩展的,就多了Input部分的MRAO(金属粗糙AO)纹理采样
![image-20201011021131102](XDRender_ShaderMode_Transmi.assets/image-20201011021131102.png
Name "TransmittanceLit"
Tags {"LightMode" = "DefaultLitTransmitance"}
#pragma vertex DefaultLitTransmis_Vertex
#pragma fragment DefaultLitTransmiLit01_TT_Fragment
TEXTURE2D(_RouAOMap);
SAMPLER(sampler_RouAOMap);
inline void DefaultLitTransmiLit01_TT_SurfaceData(DefaultLit_Varyings input, out SurfaceData outSurfaceData)
{
#ifdef _DIFFCUSE_MAP
half4 albedoAlpha = _BaseColor * SAMPLE_TEXTURE2D(_DiffcuseMap,sampler_DiffcuseMap, input.baseUV);
#else
half4 albedoAlpha = _BaseColor;
#endif
outSurfaceData.alpha = albedoAlpha.r;
outSurfaceData.albedo = albedoAlpha.rgb;
float3 rmao_sample = SAMPLE_TEXTURE2D(_RouAOMap,sampler_RouAOMap, input.baseUV).b * _OcclusionStrength;
outSurfaceData.metallic = rmao_sample.r;
outSurfaceData.specular = _SpecColor;
outSurfaceData.smoothness = 1.0-rmao_sample.g;
#ifdef _NORMALMAP
float3 normalTS = SampleNormal(input.baseUV, TEXTURE2D_ARGS(_NormalMap, sampler_NormalMap), 1.0);
outSurfaceData.normalWS = TransformTangentToWorld(normalTS,half3x3(input.tangentWS.xyz, input.bitangentWS.xyz, input.normalWS.xyz));
#else
outSurfaceData.normalWS = input.normalWS;
#endif
outSurfaceData.occlusion = rmao_sample.b * _OcclusionStrength;
outSurfaceData.emission = _EmissionColor;
}
说明
1、后续透射部分,也是按那四个元素来。其中相位函数是比较麻烦的,不过这部分模型已经有很多Pape了,可以参考和分析。
2、XDRender后续,会将前面的Core(纹理,空间,编码 等等补齐)
3、透射部分的距离变体部分下一节未完待续
备注
未完太多后续待续,
转载请说明来源(白袍小道)