DX渲染反射

静态反射

//计算反射
float3 ReflectionColor = GetReflectionColor(MatConstBuffer, ModelNormal, MVOut.WorldPosition.xyz);

float3 FresnelSchlickMethod(float3 InF0,float3 InObjectPointNormal,float3 InDirection,int InPowM)
{
	return InF0 + (1.f - InF0) * pow(1.f - saturate(dot(InObjectPointNormal, InDirection)),InPowM);
}

float4 GetMaterialBaseColor(MaterialConstBuffer MatConstBuffer,float2 InTexCoord)
{
	if (MatConstBuffer.BaseColorIndex != -1)
	{
		return SimpleTexture2DMap[MatConstBuffer.BaseColorIndex].Sample(TextureSampler, InTexCoord);
	}

	return MatConstBuffer.BaseColor;
}

float3 GetMaterialNormals(
	MaterialConstBuffer MatConstBuffer, 
	float2 InTexCoord,
	float3 InUnitWorldNormal,
	float3 InWorldTangent)
{
	if (MatConstBuffer.NormalIndex != -1)
	{
		float4 SampleNormal = SimpleTexture2DMap[MatConstBuffer.NormalIndex].Sample(AnisotropicSampler, InTexCoord);
	
		//[0,1]->[-1,1] => [0,1] * 2.f = [0,2] => [0-2]-1.f = [-1,1];
		float3 NormalsInTangentSpace = 2.0f * SampleNormal.rgb - 1.f;

		//拿到世界TBN
		float3x3 TBN = GetBuildTBNMatrix(InUnitWorldNormal, InWorldTangent);

		//把切线空间下的采样法线转为世界的法线
		return mul(NormalsInTangentSpace,TBN);
	}

	return InUnitWorldNormal;
}

float4 GetMaterialSpecular(MaterialConstBuffer MatConstBuffer, float2 InTexCoord)
{
	if (MatConstBuffer.SpecularIndex != -1)
	{
		return SimpleTexture2DMap[MatConstBuffer.SpecularIndex].Sample(TextureSampler, InTexCoord);
	}

	return float4(MatConstBuffer.SpecularColor,1.f);
}

float3 GetReflect(float3 InUnitWorldNormal,float3 WorldPosition)
{
	float3 ViewDirection = normalize(ViewportPosition.xyz - WorldPosition);
	return reflect(-ViewDirection, InUnitWorldNormal);
}

float3 GetRefract(float3 InUnitWorldNormal, float3 WorldPosition,float InRefractiveValue)
{
	float3 ViewDirection = normalize(ViewportPosition.xyz - WorldPosition);
	return refract(-ViewDirection,InUnitWorldNormal,InRefractiveValue);
}

float3 GetReflectionSampleColor(float3 InUnitWorldNormal,float3 NewReflect)
{
	return SimpleCubeMap.Sample(TextureSampler, NewReflect);
}

float GetShininess(MaterialConstBuffer MatConstBuffer)
{
	return 1.f - MatConstBuffer.MaterialRoughness;
}

float3 FresnelSchlickFactor(MaterialConstBuffer MatConstBuffer, float3 InUnitWorldNormal, float3 InReflect)
{
	return FresnelSchlickMethod(MatConstBuffer.FresnelF0, InUnitWorldNormal, InReflect,5);
}

float3 FresnelSchlickRoughness(float NV, float3 F0, float Roughness)
{
	return F0 + (max(float3(1.0 - Roughness, 1.0 - Roughness, 1.0 - Roughness), F0) - F0) * pow(1.0 - NV, 5.0);
}
//获取反射的颜色
float3 GetReflectionColor(MaterialConstBuffer MatConstBuffer, float3 InUnitWorldNormal, float3 WorldPosition)
{
	float3 NewReflect = GetReflect(InUnitWorldNormal, WorldPosition);
	float3 SampleReflectionColor = GetReflectionSampleColor(InUnitWorldNormal, NewReflect);
	float Shininess = GetShininess(MatConstBuffer);
	float3 FresnelFactor = FresnelSchlickFactor(MatConstBuffer, InUnitWorldNormal, NewReflect);

	return SampleReflectionColor * FresnelFactor * Shininess;
}

动态反射

在Obj周围架设六个摄像机(六个方向)进行采样,因此将摄像机层分层给管线使用。

离屏渲染

应用:截屏、AO、阴影、反射

相当于GPU绘制了多个看不到的RTV——上述的六个相机每个渲染成一个RTV。

六个RTV组成CubeMap(在Shader中)给反射和折射进行采样

代码上的变化:摄像机层分离、RT层分离

折射

采样方法如上。

但要注意的是:开启折射的物体不是透明物体,它在折射不透明物体渲染层。

 

{
//先计算折射
float3 NewRefract = GetRefract(ModelNormal, MVOut.WorldPosition.xyz, MatConstBuffer.Refraction);
float3 SampleRefractColor = GetReflectionSampleColor(ModelNormal, NewRefract);//采样

//计算反射
float3 NewReflect = GetReflect(ModelNormal, MVOut.WorldPosition.xyz);
float3 SampleReflectionColor = GetReflectionSampleColor(ModelNormal, NewReflect);//采样

//算A通道
float3 V = normalize(ViewportPosition.xyz - MVOut.WorldPosition.xyz);
float Shininess = GetShininess(MatConstBuffer);
float3 FresnelFactor = FresnelSchlickFactor(MatConstBuffer, ModelNormal, V);

float3 Color = lerp(SampleRefractColor , SampleReflectionColor, pow(Shininess * FresnelFactor,2));

MVOut.Color.xyz += Color;
break;
}

//折射
float3 GetRefract(float3 InUnitWorldNormal, float3 WorldPosition,float InRefractiveValue)
{
	float3 ViewDirection = normalize(ViewportPosition.xyz - WorldPosition);
	return refract(-ViewDirection,InUnitWorldNormal,InRefractiveValue);
}

//反射
float3 GetReflect(float3 InUnitWorldNormal,float3 WorldPosition)
{
	float3 ViewDirection = normalize(ViewportPosition.xyz - WorldPosition);
	return reflect(-ViewDirection, InUnitWorldNormal);
}

 

阴影

代码上的变化:PSO层分离。

1.偏移补偿(DX12支持) BY 斜率

解决粉刺——产生原因:摄像机屏幕上的相邻两个像素同时看向一个文素,分别对应同一个文素的暗面和亮面。但在计算中一个文素对应一个值,所有亮面变暗了(反之亦然),就形成了粉刺。

偏移一下让整个文素在阴影内或外即可。

 

ShaderViewMatrix:灯光位置

平行光:正交矩阵(DepthBias=100000)

聚光灯:透视矩阵(DepthBias=1000--平衡粉刺和阴影飞出去之间的效果)

百分比渐进算法(PCF)

4采样

九采样

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值