浏览代码

HDRenderPipeline: Replace tangentToWorld by the correct term worldToTangent

/Branch_Batching2
Sebastien Lagarde 7 年前
当前提交
14dc6caa
共有 6 个文件被更改,包括 29 次插入35 次删除
  1. 18
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitData.hlsl
  2. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl
  3. 2
      Assets/ScriptableRenderPipeline/HDRenderPipeline/Material/MaterialUtilities.hlsl
  4. 15
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl
  5. 10
      Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl
  6. 9
      Assets/TestScenes/HDTest/LayeredLitTest/Mesh/Materials.meta

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


input.mikktsBino = flipSign * input.mikktsBino;
// TOCHECK: seems that we don't need to invert any genBasisTB(), sign cancel. Which is expected as we deal with surface gradient.
#else
input.tangentToWorld[1] = flipSign * input.tangentToWorld[1]; // bitangent
input.tangentToWorld[2] = flipSign * input.tangentToWorld[2]; // normal
input.worldToTangent[1] = flipSign * input.worldToTangent[1]; // bitangent
input.worldToTangent[2] = flipSign * input.worldToTangent[2]; // normal
#endif
#endif
}

// For planar the view vector is the world view vector (unless we want to support object triplanar ? and in this case used TransformWorldToObject)
// TODO: do we support object triplanar ? See ComputeLayerTexCoord
float3 viewDirTS = isPlanar ? float3(-V.xz, V.y) : TransformWorldToTangent(V, input.tangentToWorld);
float3 viewDirTS = isPlanar ? float3(-V.xz, V.y) : TransformWorldToTangent(V, input.worldToTangent);
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);

LayerTexCoord layerTexCoord;
GetLayerTexCoord(input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.tangentToWorld[2].xyz, layerTexCoord);
input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
ApplyPerPixelDisplacement(input, V, layerTexCoord);

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.tangentToWorld[2].xyz, _HorizonFade);
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);
// Caution: surfaceData must be fully initialize before calling GetBuiltinData
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);

// For planar the view vector is the world view vector (unless we want to support object triplanar ? and in this case used TransformWorldToObject)
// TODO: do we support object triplanar ? See ComputeLayerTexCoord
float3 viewDirTS = isPlanar ? float3(-V.xz, V.y) : TransformWorldToTangent(V, input.tangentToWorld);
float3 viewDirTS = isPlanar ? float3(-V.xz, V.y) : TransformWorldToTangent(V, input.worldToTangent);
int numSteps = (int)lerp(_PPDMaxSamples, _PPDMinSamples, viewDirTS.z);
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirTS, maxHeight, ppdParam);

LayerTexCoord layerTexCoord;
GetLayerTexCoord(input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.tangentToWorld[2].xyz, layerTexCoord);
input.positionWS, input.worldToTangent[2].xyz, layerTexCoord);
ApplyPerPixelDisplacement(input, V, layerTexCoord);

surfaceData.metallic = SURFACEDATA_BLEND_SCALAR(surfaceData, metallic, weights);
// Init other unused parameter
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.tangentWS = input.worldToTangent[0].xyz;
surfaceData.materialId = 0;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;

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);
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.tangentToWorld[2].xyz, _HorizonFade);
surfaceData.specularOcclusion *= GetHorizonOcclusion(V, surfaceData.normalWS, input.worldToTangent[2].xyz, _HorizonFade);
GetBuiltinData(input, surfaceData, alpha, depthOffset, builtinData);
}

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


normalTS *= ADD_IDX(_NormalScale);
#else
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D_BIAS(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv, bias), 1.0);
normalTS = TransformObjectToTangent(normalOS, input.tangentToWorld);
normalTS = TransformObjectToTangent(normalOS, input.worldToTangent);
normalTS.xy *= ADD_IDX(_NormalScale); // Scale in tangent space
normalTS = (normalTS);
#endif

normalTS *= ADD_IDX(_NormalScale);
#else
float3 normalOS = UnpackNormalRGB(SAMPLE_TEXTURE2D(layerTex, SAMPLER_NORMALMAP_IDX, ADD_IDX(layerTexCoord.base).uv), 1.0);
normalTS = TransformObjectToTangent(normalOS, input.tangentToWorld);
normalTS = TransformObjectToTangent(normalOS, input.worldToTangent);
normalTS.xy *= ADD_IDX(_NormalScale); // Scale in tangent space
normalTS = (normalTS);
#endif

#ifdef _TANGENTMAP
#ifdef _NORMALMAP_TANGENT_SPACE_IDX // Normal and tangent use same space
float3 tangentTS = SAMPLE_LAYER_NORMALMAP(ADD_IDX(_TangentMap), ADD_ZERO_IDX(sampler_TangentMap), ADD_IDX(layerTexCoord.base), 1.0);
surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.tangentToWorld);
surfaceData.tangentWS = TransformTangentToWorld(tangentTS, input.worldToTangent);
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.tangentWS = input.worldToTangent[0].xyz;
#endif
// TODO: Is there anything todo regarding flip normal but for the tangent ?

// Layered shader only support materialId 0
surfaceData.materialId = 0;
surfaceData.tangentWS = input.tangentToWorld[0].xyz;
surfaceData.tangentWS = input.worldToTangent[0].xyz;
surfaceData.anisotropy = 0;
surfaceData.specular = 0.04;

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


#ifdef SURFACE_GRADIENT
normalWS = resolveNormalFromSurfaceGradient(input.vtxNormalWS, normalTS);
#else
normalWS = TransformTangentToWorld(normalTS, input.tangentToWorld);
normalWS = TransformTangentToWorld(normalTS, input.worldToTangent);
#endif
// NdotV should not be negative for visible pixels, but it can happen due to the

15
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/FragInputs.hlsl


float3 vT3, vB3;
#else
float3 tangentToWorld[3]; // These 3 vectors are normalized (no need for the material to normalize) and these are only for UVSet 0
// TODO: confirm with Morten following statement
// Our TBN is orthogonal but is maybe not orthonormal in order to be compliant with external bakers (Like xnormal that use mikktspace).
// (xnormal for example take into account the interpolation when baking the normal and normalizing the tangent basis could cause distortion).
float3 worldToTangent[3]; // These 3 vectors are normalized (no need for the material to normalize) and these are only for UVSet 0
#endif
// For two sided lighting

FragInputs output;
ZERO_INITIALIZE(FragInputs, output);
output.tangentToWorld[0] = float3(0.0, 0.0, 1.0);
output.tangentToWorld[2] = float3(0.0, 0.0, 1.0);
output.worldToTangent[0] = float3(0.0, 0.0, 1.0);
output.worldToTangent[2] = float3(0.0, 0.0, 1.0);
return output;
}

result = float3(input.texCoord3, 0.0);
break;
case DEBUGVIEWVARYING_VERTEX_TANGENT_WS:
result = input.tangentToWorld[0].xyz * 0.5 + 0.5;
result = input.worldToTangent[0].xyz * 0.5 + 0.5;
result = input.tangentToWorld[1].xyz * 0.5 + 0.5;
result = input.worldToTangent[1].xyz * 0.5 + 0.5;
result = input.tangentToWorld[2].xyz * 0.5 + 0.5;
result = input.worldToTangent[2].xyz * 0.5 + 0.5;
break;
case DEBUGVIEWVARYING_VERTEX_COLOR:
result = input.color.rgb; needLinearToSRGB = true;

10
Assets/ScriptableRenderPipeline/HDRenderPipeline/ShaderPass/VaryingMesh.hlsl


// mikkts for conventional vertex level tspace (no normalizes is mandatory)
output.mikktsTang = input.interpolators2.xyz;
// bitangent on the fly option in xnormal to reduce vertex shader outputs. Also described in https://wiki.blender.org/index.php/Dev:Shading/Tangent_Space_Normal_Maps
output.mikktsBino = (input.interpolators2.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale() * cross(input.interpolators1, input.interpolators2.xyz); // TODO: use CreateTangentToWorld instead once we clean code
output.mikktsBino = (input.interpolators2.w > 0.0 ? 1.0 : -1.0) * GetOddNegativeScale() * cross(input.interpolators1, input.interpolators2.xyz); // TODO: use CreateWorldToTangent instead once we clean code
// prepare for surfgrad formulation without breaking compliance (use exact same scale as applied to interpolated vertex normal to avoid breaking compliance).
output.mikktsTang *= renormFactor;
output.mikktsBino *= renormFactor;

// Normalize the normal/tangent after interpolation
float3 normalWS = normalize(input.interpolators1);
float4 tangentWS = float4(normalize(input.interpolators2.xyz), input.interpolators2.w > 0.0 ? 1.0 : -1.0);
float3x3 tangentToWorld = CreateTangentToWorld(normalWS, tangentWS.xyz, tangentWS.w);
output.tangentToWorld[0] = tangentToWorld[0];
output.tangentToWorld[1] = tangentToWorld[1];
output.tangentToWorld[2] = tangentToWorld[2];
float3x3 worldToTangent = CreateWorldToTangent(normalWS, tangentWS.xyz, tangentWS.w);
output.worldToTangent[0] = worldToTangent[0];
output.worldToTangent[1] = worldToTangent[1];
output.worldToTangent[2] = worldToTangent[2];
#endif // SURFACE_GRADIENT
#endif

9
Assets/TestScenes/HDTest/LayeredLitTest/Mesh/Materials.meta


fileFormatVersion: 2
guid: e8f6ad2e481134b4fa6108a280b52de7
folderAsset: yes
timeCreated: 1484331445
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
正在加载...
取消
保存