So, I am working on a parallax occlusion shader in shader graph. I can’t use the in-built one, because I need to pass a different view direction in. It is supposed to work by sampling a halfway point on the view direction, and if it is in the heightmap, then it samples a smaller ray, otherwise a larger one. A few iterations of that and after some interpolating, I should have results, but it is rather broken. In the last image only top top half is shown (screen has a rather low resolution).

You need tied it up your nodes and organize them.

No one will be bother to look in such mess.

I organized the nodes, and fixed some mistakes, but it is still broken.

Unity’s node (on a test object)

My node

I tried making a similar algorithm in hlsl (used in a custom function node), but it still fails.

The code:```

#ifndef CUSTOM_PARALLAX

#define CUSTOM_PARALLAX

#endif

float4 sampleray(float3 dir, float length, float2 start, UnityTexture2D tex, UnitySamplerState ss)

{

return SAMPLE_TEXTURE2D(tex, ss, start + dir.xy * length);

}

void Parallax_float(float1 heightScale, float3 viewDir, UnityTexture2D HeightTex, float2 uv, UnitySamplerState sampleState, float steps, out float2 Out, out float height)

{

float length = 0;

float4 v = 0;

float h = 0.5;

float lastprec = 0.25f;

for (int i = 0; i < steps; i++)

{

length = (h*heightScale) / viewDir.z;

v = sampleray(viewDir,length,uv,HeightTex,sampleState);

if (v.r>h)

{

h -= lastprec;

lastprec /= 2;

}

else

{

h += lastprec;

lastprec /= 2;

}

}

length = (h * heightScale) / viewDir.z;

v = sampleray(viewDir, length, uv, HeightTex, sampleState);

height = v.r;

Out = viewDir.xy * length;

}

Update: my coded solution somewhat works, but there is some weird offset, and I don’t know how to implement the smoothing between layers.

Progress: I kinda fixed the code, but I still don’t know how implement the interpolation.

Code changes:

`if ( v.r>1-h) ...`

`Out = uv + viewDir.xy * length;`

I feel like I’m really close… (I also updated the code to have a lower chance of skipping through small details at grazing angles)

```
#ifndef CUSTOM_PARALLAX
#define CUSTOM_PARALLAX
#endif
float4 sampleray(float3 dir, float length, float2 start, UnityTexture2D tex, UnitySamplerState ss)
{
return SAMPLE_TEXTURE2D(tex, ss, start + dir.xy * length);
}
void Parallax_float(float1 heightScale, float3 viewDir, UnityTexture2D HeightTex, float2 uv, UnitySamplerState sampleState, float steps, out float2 Out, out float height)
{
bool hit = false;
float length = 0;
float4 v = 0;
float h = 0;
float lastprec = 0.2f;
float lasth = h;
float lastv = 0;
for (int i = 0; i < steps; i++)
{
length = (h*heightScale) / viewDir.z;
lastv = v.r;
v = sampleray(viewDir,length,uv,HeightTex,sampleState);
if ( v.r-1>h)
{
hit = true;
lasth = h;
if (hit)
{
lastprec /= 2;
}
h += lastprec;
}
else
{
lasth = h;
if (hit)
{
lastprec /= 2;
}
h -= lastprec;
}
}
lastv = v.r;
length = (h * heightScale) / viewDir.z;
v = sampleray(viewDir, length, uv, HeightTex, sampleState);
//float lastlength = (lasth * heightScale) / viewDir.z;
float interpamount = (h - lastv) / (v.r - lastv);
h = lerp(h,lasth,1-interpamount);
length = (h * heightScale) / viewDir.z;
//length -= 1;
//v = sampleray(viewDir, length, uv, HeightTex, sampleState);
height = v.r;
Out = uv + viewDir.xy * length ;
}
```