|
|
|
|
|
|
// To have more precision encode the sign of xy in a separate uint |
|
|
|
uint octTangentSign = (octTangentWS.x < 0.0 ? 1 : 0) | (octTangentWS.y < 0.0 ? 2 : 0); |
|
|
|
|
|
|
|
outGBuffer2 = float4(abs(octTangentWS), surfaceData.anisotropy, PackFloatInt8bit(surfaceData.metallic, octTangentSign, 4.0)); |
|
|
|
outGBuffer2 = float4(abs(octTangentWS), surfaceData.anisotropy * 0.5 + 0.5, PackFloatInt8bit(surfaceData.metallic, octTangentSign, 4.0)); |
|
|
|
} |
|
|
|
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT) |
|
|
|
{ |
|
|
|
|
|
|
inGBuffer2.r = (octTangentSign & 1) ? -inGBuffer2.r : inGBuffer2.r; |
|
|
|
inGBuffer2.g = (octTangentSign & 2) ? -inGBuffer2.g : inGBuffer2.g; |
|
|
|
float3 tangentWS = UnpackNormalOctEncode(inGBuffer2.rg); |
|
|
|
float anisotropy = inGBuffer2.b; |
|
|
|
float anisotropy = inGBuffer2.b * 2 - 1; |
|
|
|
|
|
|
|
FillMaterialIdAnisoData(bsdfData.roughness, bsdfData.normalWS, tangentWS, anisotropy, bsdfData); |
|
|
|
} |
|
|
|
else if (bsdfData.materialId == MATERIALID_LIT_CLEAR_COAT && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_CLEAR_COAT)) |
|
|
|
|
|
|
preLightData.TdotV = dot(bsdfData.tangentWS, V); |
|
|
|
preLightData.BdotV = dot(bsdfData.bitangentWS, V); |
|
|
|
preLightData.anisoGGXLambdaV = GetSmithJointGGXAnisoLambdaV(preLightData.TdotV, preLightData.BdotV, NdotV, bsdfData.roughnessT, bsdfData.roughnessB); |
|
|
|
// Tangent = highlight stretch (anisotropy) direction. Bitangent = grain (brush) direction. |
|
|
|
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(bsdfData.bitangentWS, iblNormalWS, V, bsdfData.anisotropy); |
|
|
|
// For positive anisotropy values: tangent = highlight stretch (anisotropy) direction, bitangent = grain (brush) direction. |
|
|
|
float3 grainDirWS = (bsdfData.anisotropy >= 0) ? bsdfData.bitangentWS : bsdfData.tangentWS; |
|
|
|
float3 anisoIblNormalWS = GetAnisotropicModifiedNormal(grainDirWS, iblNormalWS, V, abs(bsdfData.anisotropy)); |
|
|
|
|
|
|
|
// NOTE: If we follow the theory we should use the modified normal for the different calculation implying a normal (like NdotV) and use iblNormalWS |
|
|
|
// into function like GetSpecularDominantDir(). However modified normal is just a hack. The goal is just to stretch a cubemap, no accuracy here. |
|
|
|