提交 c117e87c 编写于 作者: GamebabyRockSun_QQ's avatar GamebabyRockSun_QQ

修正辐照度预积分贴图计算的重要性采样算法

上级 a49c995c
......@@ -48,7 +48,7 @@ float2 IntegrateBRDF(float NdotV, float roughness)
float NdotH = max(H.z, 0.0); // N = (0.0f, 0.0f, 1.0f);
float VdotH = max(dot(V, H), 0.0);
if (NdotL > 0.0)
if ( NdotL > 0.0 )
{
float G = GeometrySmith_IBL(N, V, L, roughness);
float G_Vis = (G * VdotH) / (NdotH * NdotV);
......
......@@ -10,72 +10,50 @@ struct ST_GRS_HLSL_PS_INPUT
float3 m_v4WPos : POSITION;
};
float2 UniformOnDisk(float Xi)
{
float theta = TWO_PI * Xi;
return float2(cos(theta), sin(theta));
}
float3 CosOnHalfSphere(float2 Xi)
{
float r = sqrt(Xi.x);
float2 pInDisk = r * UniformOnDisk(Xi.y);
float z = sqrt(1 - Xi.x);
return float3(pInDisk, z);
}
float4 Quarternion_ZTo(float3 to)
{
// from = (0, 0, 1)
//float cosTheta = dot(from, to);
//float cosHalfTheta = sqrt(max(0, (cosTheta + 1) * 0.5));
float cosHalfTheta = sqrt(max(0, (to.z + 1) * 0.5));
//float3 axisSinTheta = cross(from, to);
// 0 0 1
// to.x to.y to.z
//float3 axisSinTheta = float3(-to.y, to.x, 0);
float twoCosHalfTheta = 2 * cosHalfTheta;
return float4(-to.y / twoCosHalfTheta, to.x / twoCosHalfTheta, 0, cosHalfTheta);
}
float4 Quarternion_Inverse(float4 q)
{
return float4(-q.xyz, q.w);
}
float3 Quarternion_Rotate(float4 q, float3 p)
{
// Quarternion_Mul(Quarternion_Mul(q, float4(p, 0)), Quarternion_Inverse(q)).xyz;
float4 qp = float4(q.w * p + cross(q.xyz, p), -dot(q.xyz, p));
float4 invQ = Quarternion_Inverse(q);
float3 qpInvQ = qp.w * invQ.xyz + invQ.w * qp.xyz + cross(qp.xyz, invQ.xyz);
return qpInvQ;
}
float3 CosOnHalfSphere(float2 Xi, float3 N)
{
float3 p = CosOnHalfSphere(Xi);
float4 rot = Quarternion_ZTo(N);
return Quarternion_Rotate(rot, p);
}
float4 PSMain(ST_GRS_HLSL_PS_INPUT stPSInput) :SV_Target
{
float3 N = normalize(stPSInput.m_v4WPos.xyz);
float3 irradiance = float3(0.0f,0.0f,0.0f);
const uint SAMPLE_NUM = GRS_INT_SAMPLES_CNT;
// 计算切空间
float3 Up = float3(0.0f, 1.0f, 0.0f);
float fdot = dot(Up, N);
if ((1.0 - fdot) > 1e-6)
{
Up = float3(1.0f, 0.0f, 0.0f);
}
float3 Right = normalize(cross(Up, N));
Up = normalize(cross(N, Right));
N = normalize(cross(Right, Up));
float theta = 0.0f;
float phi = 0.0f;
float2 Xi;
float3 L;
const uint SAMPLE_NUM = 4096u;
// 蒙特卡洛积分循环
for (uint i = 0u; i < SAMPLE_NUM; i++)
{
float2 Xi = Hammersley(i, SAMPLE_NUM);
float3 L = CosOnHalfSphere(Xi, N);
// 产生均匀分布随机数
Xi = Hammersley(i, SAMPLE_NUM);
// 根据 CDF 反函数计算指定分布的随机变量
phi = TWO_PI * Xi.x;
theta = asin(sqrt(Xi.y));
// 球坐标转换到笛卡尔坐标(切空间)
L = float3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
// 切空间转换到世界坐标空间
L = L.x * Right + L.y * Up + L.z * N;
// 采样求和统计入射辐照度
irradiance += g_texHDREnvCubemap.Sample(g_sapLinear, L).xyz;
}
// 取平均得到最终结果
irradiance *= 1.0 / float(SAMPLE_NUM);
return float4(irradiance,1.0f);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册