@@ -121,7 +121,7 @@ float4 SampleLayerLod(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV, f
121121
122122// TODO: Handle BC5 format, currently this code is for DXT5nm
123123// THis function below must call UnpackNormalmapRGorAG
124- float3 SampleNormalLayer (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
124+ float3 SampleLayerNormal (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
125125{
126126 if (layerUV.isTriplanar)
127127 {
@@ -143,7 +143,7 @@ float3 SampleNormalLayer(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layerUV
143143}
144144
145145// This version is for normalmap with AG encoding only (use with details map)
146- float3 SampleNormalLayerAG (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
146+ float3 SampleLayerNormalAG (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
147147{
148148 if (layerUV.isTriplanar)
149149 {
@@ -166,7 +166,7 @@ float3 SampleNormalLayerAG(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV layer
166166
167167// This version is for normalmap with RGB encoding only, i.e non encoding. It is necessary to use this abstraction to handle correctly triplanar
168168// plus consistent with the normal scale parameter
169- float3 SampleNormalLayerRGB (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
169+ float3 SampleLayerNormalRGB (TEXTURE2D_ARGS (layerTex, layerSampler), LayerUV layerUV, float3 weights, float scale)
170170{
171171 if (layerUV.isTriplanar)
172172 {
@@ -190,12 +190,9 @@ float3 SampleNormalLayerRGB(TEXTURE2D_ARGS(layerTex, layerSampler), LayerUV laye
190190// Macro to improve readibility of surface data
191191#define SAMPLE_LAYER_TEXTURE2D (textureName, samplerName, coord) SampleLayer (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights)
192192#define SAMPLE_LAYER_TEXTURE2D_LOD (textureName, samplerName, coord, lod) SampleLayerLod (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, lod)
193- #define SAMPLE_LAYER_NORMALMAP (textureName, samplerName, coord, scale) SampleNormalLayer (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
194- #define SAMPLE_LAYER_NORMALMAP_AG (textureName, samplerName, coord, scale) SampleNormalLayerAG (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
195- #define SAMPLE_LAYER_NORMALMAP_RGB (textureName, samplerName, coord, scale) SampleNormalLayerRGB (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
196-
197- // Transforms 2D UV by scale/bias property
198- #define TRANSFORM_TEX (tex,name) ((tex.xy) * name##_ST.xy + name##_ST.zw)
193+ #define SAMPLE_LAYER_NORMALMAP (textureName, samplerName, coord, scale) SampleLayerNormal (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
194+ #define SAMPLE_LAYER_NORMALMAP_AG (textureName, samplerName, coord, scale) SampleLayerNormalAG (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
195+ #define SAMPLE_LAYER_NORMALMAP_RGB (textureName, samplerName, coord, scale) SampleLayerNormalRGB (TEXTURE2D_PARAM (textureName, samplerName), coord, layerTexCoord.weights, scale)
199196
200197#ifndef LAYERED_LIT_SHADER
201198
@@ -225,15 +222,32 @@ void GetLayerTexCoord(float2 texCoord0, float2 texCoord1, float2 texCoord2, floa
225222 positionWS, normalWS, isTriplanar, layerTexCoord);
226223}
227224
225+ void ApplyPerPixelDisplacement (FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
226+ {
227+ #if defined (_HEIGHTMAP) && defined (_PER_PIXEL_DISPLACEMENT)
228+
229+ // ref: https://www.gamedev.net/resources/_/technical/graphics-programming-and-theory/a-closer-look-at-parallax-occlusion-mapping-r3262
230+ float3 viewDirTS = TransformWorldToTangent (V, input.tangentToWorld);
231+ // Change the number of samples per ray depending on the viewing angle for the surface.
232+ // Oblique angles require smaller step sizes to achieve more accurate precision for computing displacement.
233+ // int numSteps = (int)lerp(_PPPMaxSamples, _PPPMinSamples, viewDirTS.z);
234+ int numSteps = (int )lerp (15 , 15 , viewDirTS.z); // TEMP
235+
236+ ParallaxOcclusionMappingLayer (layerTexCoord, numSteps, viewDirTS);
237+
238+ // 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...
239+ // Let's assume it will be "fine" as indirect diffuse is often low frequency
240+ #endif
241+ }
242+
228243void GetSurfaceAndBuiltinData (FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
229244{
230245 LayerTexCoord layerTexCoord;
231246 GetLayerTexCoord (input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
232247 input.positionWS, input.tangentToWorld[2 ].xyz, layerTexCoord);
233248
234- // Transform view vector in tangent space
235- float3 viewDirTS = TransformWorldToTangent (V, input.tangentToWorld);
236- ApplyDisplacement (input, viewDirTS, layerTexCoord);
249+
250+ ApplyPerPixelDisplacement (input, V, layerTexCoord);
237251 float depthOffset = 0.0 ;
238252
239253#ifdef _DEPTHOFFSET_ON
@@ -404,20 +418,33 @@ void GetLayerTexCoord(float2 texCoord0, float2 texCoord1, float2 texCoord2, floa
404418 positionWS, normalWS, isTriplanar, layerTexCoord);
405419}
406420
421+ void ApplyPerPixelDisplacement (FragInputs input, float3 V, inout LayerTexCoord layerTexCoord)
422+ {
423+ #if defined (_HEIGHTMAP) && defined (_PER_PIXEL_DISPLACEMENT)
424+ float3 viewDirTS = TransformWorldToTangent (V, input.tangentToWorld);
425+ int numSteps = (int )lerp (15 , 15 , viewDirTS.z);
426+
427+ ParallaxOcclusionMappingLayer0 (layerTexCoord, numSteps, viewDirTS);
428+ ParallaxOcclusionMappingLayer1 (layerTexCoord, numSteps, viewDirTS);
429+ ParallaxOcclusionMappingLayer2 (layerTexCoord, numSteps, viewDirTS);
430+ ParallaxOcclusionMappingLayer3 (layerTexCoord, numSteps, viewDirTS);
431+ #endif
432+ }
433+
407434void GetSurfaceAndBuiltinData (FragInputs input, float3 V, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
408435{
409436 LayerTexCoord layerTexCoord;
410437 GetLayerTexCoord (input.texCoord0, input.texCoord1, input.texCoord2, input.texCoord3,
411438 input.positionWS, input.tangentToWorld[2 ].xyz, layerTexCoord);
412439
413- // Transform view vector in tangent space
414- float3 viewDirTS = TransformWorldToTangent (V, input.tangentToWorld);
415- float height0 = ApplyDisplacement0 (input, viewDirTS, layerTexCoord);
416- float height1 = ApplyDisplacement1 (input, viewDirTS, layerTexCoord);
417- float height2 = ApplyDisplacement2 (input, viewDirTS, layerTexCoord);
418- float height3 = ApplyDisplacement3 (input, viewDirTS, layerTexCoord);
419- float depthOffset = 0.0 ;
440+ ApplyPerPixelDisplacement (input, V, layerTexCoord);
420441
442+ float height0 = SampleHeightmap0 (layerTexCoord);
443+ float height1 = SampleHeightmap1 (layerTexCoord);
444+ float height2 = SampleHeightmap2 (layerTexCoord);
445+ float height3 = SampleHeightmap3 (layerTexCoord);
446+
447+ float depthOffset = 0.0 ;
421448#ifdef _DEPTHOFFSET_ON
422449 ApplyDepthOffsetPositionInput (V, depthOffset, posInput);
423450#endif
0 commit comments