浏览代码

HDRenderPipeline: Fix issue with SurfaceGradient + update flip/mirror normal

/Branch_Batching2
Sebastien Lagarde 7 年前
当前提交
d252ad49
共有 2 个文件被更改,包括 11 次插入27 次删除
  1. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  2. 28
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl


{
float3 vertexNormalWS = input.worldToTangent[2];
layerTexCoord.vertexTangentWS0 = input.worldToTangent[1];
layerTexCoord.vertexBitangentWS0 = input.worldToTangent[2];
layerTexCoord.vertexTangentWS0 = input.worldToTangent[0];
layerTexCoord.vertexBitangentWS0 = input.worldToTangent[1];
// TODO: We should use relative camera position here - This will be automatic when we will move to camera relative space.
float3 dPdx = ddx_fine(input.positionWS);

void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
ApplyDoubleSidedFlip(input); // Apply double sided flip on the vertex normal
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);

// so it allow us to correctly deal with detail normal map and optimize the code for the layered shaders
float3 normalTS;
float alpha = GetSurfaceData(input, layerTexCoord, surfaceData, normalTS);
ApplyDoubleSidedMirror(input, normalTS); // Apply double sided mirror on the final normalTS
GetNormalAndTangentWS(input, V, normalTS, surfaceData.normalWS, surfaceData.tangentWS);
// Done one time for all layered - cumulate with spec occ alpha for now
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);

void GetSurfaceAndBuiltinData(FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
{
ApplyDoubleSidedFlip(input); // Apply double sided flip on the vertex normal
ApplyDoubleSidedFlipOrMirror(input); // Apply double sided flip on the vertex normal
LayerTexCoord layerTexCoord;
ZERO_INITIALIZE(LayerTexCoord, layerTexCoord);

surfaceData.coatPerceptualSmoothness = 1.0;
surfaceData.specularColor = float3(0.0, 0.0, 0.0);
ApplyDoubleSidedMirror(input, normalTS); // Apply double sided mirror on the final normalTS
GetNormalAndTangentWS(input, V, normalTS, surfaceData.normalWS, surfaceData.tangentWS);
// Done one time for all layered - cumulate with spec occ alpha for now
surfaceData.specularOcclusion = SURFACEDATA_BLEND_SCALAR(surfaceData, specularOcclusion, weights);

28
Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl


#endif
}
// To flip in case of double sided, we must flip the vertex normal and this will apply to the whole process either in surface gradient or not.
// As here we are in the function call GetSurfaceAndBuiltinData(), the tangent space is already built, so we need to flip both normal and bitangent.
// Flipping or mirroring a normal can be done directly on the tangent space. This has the benefit to apply to the whole process either in surface gradient or not.
void ApplyDoubleSidedFlip(inout FragInputs input)
void ApplyDoubleSidedFlipOrMirror(inout FragInputs input)
float flipSign = input.isFrontFace ? 1.0 : _DoubleSidedConstants.x; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
input.worldToTangent[1] = flipSign * input.worldToTangent[1]; // bitangent
input.worldToTangent[2] = flipSign * input.worldToTangent[2]; // normal
// To get a flipped normal with the tangent space, we must flip bitangent (because it is construct from the normal) and normal
// To get a mirror normal with the tangent space, we only need to flip the normal and not the tangent
float2 flipSign = input.isFrontFace ? float2(1.0, 1.0) : _DoubleSidedConstants.yz; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
input.worldToTangent[1] = flipSign.x * input.worldToTangent[1]; // bitangent
input.worldToTangent[2] = flipSign.y * input.worldToTangent[2]; // normal
#endif
#endif
}
// To mirror a normal: in ws reflect around the vertex normal / in tangent space apply minus on the z component.
// For surface gradient it is sufficient to take the opposite of the surface gradient.
void ApplyDoubleSidedMirror(FragInputs input, inout float3 normalTS)
{
#ifdef _DOUBLESIDED_ON
// _DoubleSidedConstants is float3(-1, -1, -1) in flip mode and float3(1, 1, -1) in mirror mode
float flipSign = input.isFrontFace ? 1.0 : -_DoubleSidedConstants.x; // TOCHECK : GetOddNegativeScale() is not necessary here as it is apply for tangent space creation.
#ifdef SURFACE_GRADIENT
normalTS = flipSign * normalTS;
#else
normalTS.z *= flipSign;
#endif
#endif
}

正在加载...
取消
保存