浏览代码

Improve the precision of the tangent vector stored within the G-buffer

/stochastic_alpha_test
Evgenii Golubev 7 年前
当前提交
18b135d5
共有 2 个文件被更改,包括 13 次插入9 次删除
  1. 20
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  2. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl

20
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Encode normal on 20bit with oct compression + 2bit of sign
float2 octNormalWS = PackNormalOctEncode((surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT) ? surfaceData.coatNormalWS : surfaceData.normalWS);
// To have more precision encode the sign of xy in a separate uint
uint octNormalSign = (octNormalWS.x > 0.0 ? 1 : 0) + (octNormalWS.y > 0.0 ? 2 : 0);
uint octNormalSign = (octNormalWS.x < 0.0 ? 1 : 0) | (octNormalWS.y < 0.0 ? 2 : 0);
// Store octNormalSign on two bits with perceptualRoughness
outGBuffer1 = float4(abs(octNormalWS), PackFloatInt10bit(PerceptualSmoothnessToPerceptualRoughness(surfaceData.perceptualSmoothness), octNormalSign, 4.0), PackMaterialId(surfaceData.materialId));

{
// Encode tangent on 16bit with oct compression
float2 octTangentWS = PackNormalOctEncode(surfaceData.tangentWS);
outGBuffer2 = float4(octTangentWS * 0.5 + 0.5, surfaceData.anisotropy, PackFloatInt8bit(surfaceData.metallic, 0.0, 4.0));
// 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));
}
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT)
{

int octNormalSign;
UnpackFloatInt10bit(inGBuffer1.b, 4.0, bsdfData.perceptualRoughness, octNormalSign);
inGBuffer1.r *= (octNormalSign & 1) ? 1.0 : -1.0;
inGBuffer1.g *= (octNormalSign & 2) ? 1.0 : -1.0;
inGBuffer1.r = (octNormalSign & 1) ? -inGBuffer1.r : inGBuffer1.r;
inGBuffer1.g = (octNormalSign & 2) ? -inGBuffer1.g : inGBuffer1.g;
bsdfData.normalWS = UnpackNormalOctEncode(float2(inGBuffer1.r, inGBuffer1.g));
bsdfData.roughness = PerceptualRoughnessToRoughness(bsdfData.perceptualRoughness);

else if (bsdfData.materialId == MATERIALID_LIT_ANISO && HasMaterialFeatureFlag(MATERIALFEATUREFLAGS_LIT_ANISO))
{
float metallic;
int unused;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, unused);
int octTangentSign;
UnpackFloatInt8bit(inGBuffer2.a, 4.0, metallic, octTangentSign);
float3 tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0));
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;
FillMaterialIdAnisoData(bsdfData.roughness, bsdfData.normalWS, tangentWS, anisotropy, bsdfData);
}

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


ApplyDepthOffsetPositionInput(V, depthOffset, GetWorldToHClipMatrix(), posInput);
#endif
float3 interpolatedVertexNormal = input.worldToTangent[2].xyz;
// We perform the conversion to world of the normalTS outside of the GetSurfaceData
// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;

正在加载...
取消
保存