SSAO笔记

材料:

1.基于屏幕的:normal和深度贴图、噪波图

2.采样体积:14个向量组成的体积

用AO层管理上述材料(存在PSO中,再给寄存器调用)

对噪波进行双边模糊

采样体

struct FSampleVolumeBuffer
{
	FSampleVolumeBuffer();

public:
	void BuildVolumeBuffer();
	void BuildRandomVolumeBuffer();

	void Update(XMFLOAT4 *InBuffer);
public:
	void* GetVolumeBuffer() {return VolumeBuffer.data();}

protected:
	std::vector<fvector_4d> VolumeBuffer;
};

噪波图

不同:构建自己的上传堆

BuildDescriptors();
BuildRenderTargetRTV();
BuildSRVDescriptors();
BuildRTVDescriptors();
 

创建资源(定义颜色)

上传缓冲区

深度

a_z{}:视口空间下,点的深度/Z坐标(直接采样自深度贴图)

a:视口空间下,点的位置

V:点的近剪裁面位置

V_z{}:点的近剪裁面空间位置的Z坐标

b:在环境光反射方向上 长度为遮蔽距离的点(自己设置)——如果反射方向与反向方向相反,通过sign反转。然后根据b、c在近剪裁面UI坐标相同,采样深度,判断有无遮蔽。

根据A和C的位置关系累加一个值(这个值在反面为0,证明与C和A的距离有关)

这个值叫遮敝率:14条采样光线,判断有多少条被遮蔽(\frac{h}{N}

可及率=1-这个值(有多少条关系没被遮蔽)

双边模糊(双边保留模糊)BilateralBlur

更加平滑

1.构建正态分布的模糊权重(卷积)

if (bReBuildBlurWeights)
{
	BlurWeights.clear();
}

if (BlurWeights.size() == 0)
{
	BlurRadius = ceil(InSigma * 2.f);

	BlurWeights.resize(2.f * BlurRadius + 1);

	float Len = 2.f * pow(InSigma, 2);
	float Weights = 0.f;
	for (int i = -BlurRadius;i<= BlurRadius; ++i)
	{
		float Value = (float)i;
		BlurWeights[i + BlurRadius] = expf(-pow(Value, 2) / Len);
		Weights += BlurWeights[i + BlurRadius];
	}

	//将权重值 映射到 0 - 1
	for (int i = 0; i < BlurWeights.size(); i++)
	{
		BlurWeights[i] /= Weights;
	}
}

模糊考虑的因素:1.法线  2.深度

根据UV采样AO图和原来的颜色混合,再乘以权重

结果除以总权重

Shader:


float4 PixelShaderMain(MeshVertexOut MVOut) :SV_TARGET
{
	float BlurWeights[12] =
	{
		 Float4BlurWeights[0].x, Float4BlurWeights[0].y, Float4BlurWeights[0].z,Float4BlurWeights[0].w,
		 Float4BlurWeights[1].x, Float4BlurWeights[1].y, Float4BlurWeights[1].z,Float4BlurWeights[1].w,
		 Float4BlurWeights[2].x, Float4BlurWeights[2].y, Float4BlurWeights[2].z,Float4BlurWeights[2].w,
	};

	//单位偏移值
	float2 TexOffset;
	if (bHorizontalBlur)
	{
		TexOffset = float2(InversionSize.x,0.f);
	}
	else
	{
		TexOffset = float2(0.f,InversionSize.y);
	}

	//中间的权重对应的法线核深度颜色
	float Weights = BlurWeights[BlurRadius];
	float4 Color = Weights * SampleAcceptMap.SampleLevel(TextureSampler, MVOut.TexCoord, 0.0f);
	
	float3 MatchingNormal = SampleNormalMap.SampleLevel(TextureSampler, MVOut.TexCoord, 0.0f).xyz;
	float MatchingViewDepth = DepthNdcSpaceToViewSpace(SampleDepthMap.SampleLevel(DepthSampler, MVOut.TexCoord, 0.0f).r);
	
	//偏移后的权重对应的法线核深度颜色
	for (float i = -BlurRadius; i <= BlurRadius; i++)
	{
		if (i == 0)
		{
			continue;
		}

		float2 TexCoord = MVOut.TexCoord + i * TexOffset;
		float3 Normal = SampleNormalMap.SampleLevel(TextureSampler, TexCoord, 0.0f).xyz;
		float ViewDepth = DepthNdcSpaceToViewSpace(SampleDepthMap.SampleLevel(DepthSampler, TexCoord, 0.0f).r);

		if (dot(Normal, MatchingNormal) >= 0.8f && abs(ViewDepth - MatchingViewDepth) <= 0.2f)
		{
			float Weight = BlurWeights[BlurRadius + i];
			Color += Weight * SampleAcceptMap.SampleLevel(TextureSampler,TexCoord, 0.0f);
		
			Weights += Weight;
		}
	}
	
	return Color / Weights;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值