BlueRoseNote/03-UnrealEngine/卡通渲染相关资料/Toon 眼睛反射与视差效果.md
2023-06-29 11:55:02 +08:00

3.8 KiB
Raw Blame History

PBR Refrection有问题

//input anteriorChamberDepth 贴图 使用HeightMap
//input radius
//input mask 贴图
//input texcoord
//input n 折射率比值
//input frontNormalW 贴图float3(0,0,1) Local=>World

// 角膜区域突起的模型 height = max(-positionL.z  eyeIrisDepth, 0.0); 
// 球形模型 Plot[Max[1.0 - 18.4 * r * r, 0.0], {r, 0, 0.3}]
float height = anteriorChamberDepth ;//* saturate( 1.0 - 18.4 * radius * radius ); 

float3 normalW=Parameters.WorldNormal;
float3 viewW= mul(float3(0,0,1),(float3x3)View.ViewToTranslatedWorld);//CameraViewToTranslatedWorld

// refractedW
float w = n * dot( normalW, viewW );
float k = sqrt( 1.0 + ( w - n ) * ( w + n ) );
float3 refractedW = ( w - k ) * normalW - n * viewW;
refractedW=-normalize(refractedW);

//float3 frontNormalW=mul(float(0,0,1),float(3x3)GetPrimitiveData(Parameters.PrimitiveId).LocalToWorld) * -1;
float cosAlpha = dot(frontNormalW, refractedW);
float dist = height / cosAlpha;
float3 offsetW = dist * refractedW;
float2 offsetL = mul(offsetW, (float3x2)GetPrimitiveData(Parameters.PrimitiveId).WorldToLocal);
texcoord += float2(mask, -mask) * offsetL;

return texcoord;

原始代码

// 角膜区域突起的模型
// Alternatively, use a displacement map
// height = max(-positionL.z  eyeIrisDepth, 0.0); 

// 球形模型
// Plot[Max[1.0 - 18.4 * r * r, 0.0], {r, 0, 0.3}]
height = anteriorChamberDepth * saturate( 1.0 - 18.4 * radius * radius ); 

// refractedW
float w = n * dot( normalW, viewW );
float k = sqrt( 1.0 + ( w - n ) * ( w + n ) );
float3 refractedW = ( w - k ) * normalW - n * viewW;

float cosAlpha = dot(frontNormalW, -refractedW);
float dist = height / cosAlpha;
float3 offsetW = dist * refractedW;
float2 offsetL = mul(offsetW, (float3x2) worldInverse);
texcoord += float2(mask, -mask) * offsetL;

Matcap反射效果

float2 CalcMatcapUV(FMaterialPixelParameters Parameters,float3 normalTexture)
{
	float3 ViewVector=Parameters.CameraVector * -1;
	float3 ViewSpaceRightVector=normalize(cross(ViewVector , mul( float3(0.0,1.0,0.0) , ResolvedView.ViewToTranslatedWorld )));
	float3 ViewSpaceUpVector=cross(ViewVector ,ViewSpaceRightVector);

	float3x3 Matrix=float3x3(
		ViewSpaceRightVector.x,ViewSpaceUpVector.x,ViewVector.x,
		ViewSpaceRightVector.y,ViewSpaceUpVector.y,ViewVector.y,
		ViewSpaceRightVector.z,ViewSpaceUpVector.z,ViewVector.z
	);

	float3 ZeroOneNormal=mul(normalize(Parameters.WorldNormal+normalTexture),Matrix)*0.5+0.5;
	return float2(ZeroOneNormal.x,ZeroOneNormal.y*-1);
}

这个不太行

//input normalTexture 法线贴图
float3 TangentWS=Parameters.TangentToWorld[0];
float3 NormalWS=Parameters.TangentToWorld[2];
float3 BinormalWS=cross(NormalWS, TangentWS);

float3 worldNormal;
worldNormal.x = dot(float3(TangentWS.x,BinormalWS.x,NormalWS.x), normalTexture);
worldNormal.y = dot(float3(TangentWS.y,BinormalWS.y,NormalWS.y), normalTexture);
worldNormal.z = dot(float3(TangentWS.z,BinormalWS.z,NormalWS.z), normalTexture);
worldNormal = normalize(worldNormal);

float3 e = normalize(GetWorldPosition(Parameters) -  ResolvedView.WorldCameraOrigin);
float3 reflectVector = reflect(e, worldNormal);
float3 reflectVectorVS = normalize(mul(reflectVector,ResolvedView.TranslatedWorldToView));
float m = 2.82842712474619 * sqrt(reflectVectorVS.z + 1.0);
float2 cap = reflectVectorVS.xy / m + 0.5;
cap=cap*0.5 + 0.5;
return cap;

高光贴图位置调整

//input float2 LeftUp,LeftDown,RightUp,RightDown;

float3 viewW = mul(float3(0,0,1),(float3x3)View.ViewToTranslatedWorld);
float3 viewL = mul(viewW, (float3x2)GetPrimitiveData(Parameters.PrimitiveId).WorldToLocal);
float2 viewL2D = normalize(viewL.xy);

float2 Left=lerp(LeftUp,LeftDown,viewL2D.y);
float2 Right=lerp(RightUp,RightDown,viewL2D.y);
return lerp(Left,Right,viewL2D.x);

焦散

  • dot(Parameters.WorldNormal,View.DirectionalLightDirection);
  • Fresnel

乘以焦散Mask即可