浏览代码

HDRenderPipeline: Missing file for POM

/main
sebastienlagarde 8 年前
当前提交
937ba3f0
共有 2 个文件被更改,包括 114 次插入18 次删除
  1. 72
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl
  2. 60
      Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl

72
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitData.hlsl


// TODO: Handle BC5 format, currently this code is for DXT5nm
// THis function below must call UnpackNormalmapRGorAG
float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
float3 SampleLayerNormal(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{

}
// This version is for normalmap with AG encoding only (use with details map)
float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
float3 SampleLayerNormalAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{

// This version is for normalmap with RGB encoding only, i.e non encoding. It is necessary to use this abstraction to handle correctly triplanar
// plus consistent with the normal scale parameter
float3 SampleNormalLayerRGB(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
float3 SampleLayerNormalRGB(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
{
if (layerUV.isTriplanar)
{

// Macro to improve readibility of surface data
#define SAMPLE_LAYER_TEXTURE2D(textureName, samplerName, coord) SampleLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights)
#define SAMPLE_LAYER_TEXTURE2D_LOD(textureName, samplerName, coord, lod) SampleLayerLod(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, lod)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleNormalLayer(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleNormalLayerAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleNormalLayerRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP(textureName, samplerName, coord, scale) SampleLayerNormal(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_AG(textureName, samplerName, coord, scale) SampleLayerNormalAG(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
#define SAMPLE_LAYER_NORMALMAP_RGB(textureName, samplerName, coord, scale) SampleLayerNormalRGB(TEXTURE2D_PARAM(textureName, samplerName), coord, layerTexCoord.weights, scale)
// This function apply per pixel displacement mapping algorithm
// It will determine offset for uv coordinate to apply.
// Note that we also need to affect ligthmaps uv, so FragInputs will be modfy too
// This function return current sampled heights (up to 4) + height at intersection
void ApplyDisplacement(FragInputs input, inout LayerTexCoord layerTexCoord)
{
#if defined(_HEIGHTMAP) && defined(_PER_PIXEL_DISPLACEMENT)
// Transforms 2D UV by scale/bias property
#define TRANSFORM_TEX(tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
// ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
// Change the number of samples per ray depending on the viewing angle for the surface.
// Oblique angles require smaller step sizes to achieve more accurate precision for computing displacement.
int numSteps = (int)lerp(_PPPMaxSamples, _PPPMinSamples, viewDirTS.z);
// View vector is from the point to the camera, but we want to raymarch from camera to point, so reverse the sign
// The length of viewDirTS vector determines the furthest amount of displacement:
// float parallaxLimit = -length(viewDirTS.xy) / viewDirTS.z;
// float2 parallaxDir = normalize(Out.viewDirTS.xy);
// float2 parallaxMaxOffsetTS = parallaxDir * parallaxLimit;
// Above code simplify to
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z) /* * _POMHeightMapScale.x */;
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS;
#ifdef _LAYER_COUNT
ParallaxOcclusionMappingLayer0(layerTexCoord, numSteps, texOffsetPerStep);
ParallaxOcclusionMappingLayer1(layerTexCoord, numSteps, texOffsetPerStep);
ParallaxOcclusionMappingLayer2(layerTexCoord, numSteps, texOffsetPerStep);
ParallaxOcclusionMappingLayer3(layerTexCoord, numSteps, texOffsetPerStep);
#else
ParallaxOcclusionMappingLayer(layerTexCoord, numSteps, texOffsetPerStep);
#endif
// TODO: We are supposed to modify lightmaps coordinate (fetch in GetBuiltin), but this isn't the same uv mapping, so can't apply the offset here...
// Let's assume it will be "fine" as indirect diffuse is often low frequency
#endif
}
#ifndef LAYERED_LIT_SHADER

GetLayerTexCoord(input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.tangentToWorld[2].xyz, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
ApplyDisplacement(input, viewDirTS, layerTexCoord);
ApplyDisplacement(input, layerTexCoord);
float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON

GetLayerTexCoord(input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
input.positionWS, input.tangentToWorld[2].xyz, layerTexCoord);
// Transform view vector in tangent space
float3 viewDirTS = TransformWorldToTangent(V, input.tangentToWorld);
float height0 = ApplyDisplacement0(input, viewDirTS, layerTexCoord);
float height1 = ApplyDisplacement1(input, viewDirTS, layerTexCoord);
float height2 = ApplyDisplacement2(input, viewDirTS, layerTexCoord);
float height3 = ApplyDisplacement3(input, viewDirTS, layerTexCoord);
float depthOffset = 0.0;
ApplyDisplacement(input, layerTexCoord);
float height0 = SampleHeightmap0(LayerTexCoord layerTexCoord);
float height1 = SampleHeightmap1(LayerTexCoord layerTexCoord);
float height2 = SampleHeightmap2(LayerTexCoord layerTexCoord);
float height3 = SampleHeightmap3(LayerTexCoord layerTexCoord);
float depthOffset = 0.0;
#ifdef _DEPTHOFFSET_ON
ApplyDepthOffsetPositionInput(V, depthOffset, posInput);
#endif

60
Assets/ScriptableRenderLoop/HDRenderPipeline/Material/Lit/LitDataInternal.hlsl


ADD_IDX(layerTexCoord.details).uvXY = TRANSFORM_TEX(uvXY, ADD_IDX(_DetailMap));
}
float ADD_IDX(SampleHeightmap)(LayerTexCoord layerTexCoord)
{
#if defined(_HEIGHTMAP)
return (SAMPLE_TEXTURE2D(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap)).r - ADD_IDX(_HeightCenter)) * ADD_IDX(_HeightAmplitude);
#else
return 0.0;
#endif
}
void ADD_IDX(ParallaxOcclusionMappingLayer)(inout LayerTexCoord layerTexCoord, float numSteps, float2 texOffsetPerStep)
{
float2 uv = ADD_IDX(layerTexCoord.base).uv;
// Convention: 1.0 is top, 0.0 is bottom - POM is always inward, no extrusion
float stepSize = 1.0 / (float)numSteps;
// Compute lod as we will sample inside a lop (so can't use regular sampling)
float lod = CALCULATE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap), uv);
// Do a first step before the loop to init all value correctly
float2 texOffsetCurrent = uv;
float prevHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap), texOffsetCurrent, lod).r * ADD_IDX(_HeightAmplitude);
texOffsetCurrent += texOffsetPerStep;
float currHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap), texOffsetCurrent, lod).r * ADD_IDX(_HeightAmplitude);
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
// Have we found a height below our ray height ? then we have an intersection
if (currHeight > rayHeight)
break; // end the loop
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
// Sample height map which in this case is stored in the alpha channel of the normal map:
currHeight = SAMPLE_TEXTURE2D_LOD(ADD_IDX(_HeightMap), ADD_IDX(sampler_HeightMap), texOffsetCurrent, lod).r * ADD_IDX(_HeightAmplitude);
}
// Found below and above points, now perform line interesection (ray) with piecewise linear heightfield approximation
float t0 = rayHeight + stepSize;
float t1 = rayHeight;
float delta0 = t0 - prevHeight;
float delta1 = t1 - currHeight;
#define POM_REFINE 0
#if POM_REFINE
#else
float t = (t0 * delta1 - t1 * delta0) / (delta1 - delta0);
float2 offset = uv + (1 - t) * texOffsetPerStep * numSteps;
#endif
// Apply offset
ADD_IDX(layerTexCoord.base).uv += offset;
ADD_IDX(layerTexCoord.details).uv += offset;
}
// Return opacity
float ADD_IDX(GetSurfaceData)(FragInputs input, LayerTexCoord layerTexCoord, out SurfaceData surfaceData, out float3 normalTS)
{

正在加载...
取消
保存