|
|
|
|
|
|
// Perform a POM in each direction and modify appropriate texture coordinate |
|
|
|
ppdParam.uv = layerTexCoord.base.uvZY; |
|
|
|
viewDirTS = float3(V.x > 0.0 ? uvZY : -uvZY, V.x); |
|
|
|
viewDirTS *= GetInverseObjectScale().xzy; // Switch from Y-up to Z-up |
|
|
|
unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize |
|
|
|
unitAngle = saturate(FastACosPos(abs(viewDirUV.z)) * INV_HALF_PI); // TODO: optimize |
|
|
|
numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle); |
|
|
|
float2 offsetZY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, planeHeight); |
|
|
|
|
|
|
|
|
|
|
height = layerTexCoord.triplanarWeights.x * planeHeight; |
|
|
|
NdotV = layerTexCoord.triplanarWeights.x * abs(viewDirTS.z); |
|
|
|
viewDirTS *= GetInverseObjectScale().xzy; // Switch from Y-up to Z-up |
|
|
|
unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize |
|
|
|
unitAngle = saturate(FastACosPos(abs(viewDirUV.z)) * INV_HALF_PI); // TODO: optimize |
|
|
|
numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle); |
|
|
|
float2 offsetXZ = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, planeHeight); |
|
|
|
|
|
|
|
|
|
|
NdotV += layerTexCoord.triplanarWeights.y * abs(viewDirTS.z); |
|
|
|
viewDirTS *= GetInverseObjectScale().xzy; // Switch from Y-up to Z-up |
|
|
|
unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize |
|
|
|
unitAngle = saturate(FastACosPos(abs(viewDirUV.z)) * INV_HALF_PI); // TODO: optimize |
|
|
|
numSteps = (int)lerp(_PPDMinSamples, _PPDMaxSamples, unitAngle); |
|
|
|
float2 offsetXY = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, planeHeight); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NdotV = 1; // TODO. |
|
|
|
NdotV += layerTexCoord.triplanarWeights.z * abs(viewDirTS.z); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
|
|
|
float3 viewDirTS = isPlanar ? float3(uvXZ, V.y) : TransformWorldToTangent(V, input.worldToTangent); |
|
|
|
viewDirTS *= GetInverseObjectScale().xzy; // Switch from Y-up to Z-up |
|
|
|
|
|
|
|
NdotV = viewDirTS.z; |
|
|
|
NdotV = abs(viewDirTS.z); |
|
|
|
float unitAngle = saturate(FastACosPos(viewDirUV.z) * INV_HALF_PI); // TODO: optimize |
|
|
|
float unitAngle = saturate(FastACosPos(abs(viewDirUV.z)) * INV_HALF_PI); // TODO: optimize |
|
|
|
// POM uses a normalized view vector in the UV space to intersect the heightmap within a 1x1x1 box. |
|
|
|
float2 offset = ParallaxOcclusionMapping(lod, _PPDLodThreshold, numSteps, viewDirUV, 1, ppdParam, height); |
|
|
|
|
|
|
|
// Apply offset to all UVSet0 / planar |
|
|
|