diff options
| -rwxr-xr-x | pbr.cginc | 81 |
1 files changed, 32 insertions, 49 deletions
@@ -45,72 +45,55 @@ float2 parallax_offset(float2 uv, float3 view_dir_world, float3x3 tbn) { float angle = saturate(view_z); float base_steps = _Parallax_Heightmap_Ray_Marching_Steps; float step_count = lerp(base_steps * 1.5, base_steps * 0.75, angle); - step_count = clamp(step_count, 2.0, max(base_steps, 2.0)); - - float2 delta_uv = uv_step / step_count; - float delta_depth = 1.0 / step_count; - - float2 cur_uv = uv; - float2 prev_uv = uv; - float cur_depth = 0.0; - float cur_height = 1.0 - heightmap_sample(cur_uv); - cur_height = (cur_height - (1.0 - _Parallax_Heightmap_Bias)); - - // If starting inside geometry, march backwards - bool inside = cur_depth < cur_height; - if (!inside) { - delta_uv = -delta_uv; - delta_depth = -delta_depth; - } + int step_count_i = (int)ceil(clamp(step_count, 2.0, max(base_steps, 2.0))); + float inv_step_count = rcp((float)step_count_i); + + float2 delta_uv = uv_step * inv_step_count; + float delta_layer = inv_step_count; + + float2 cur_uv = uv - uv_step * _Parallax_Heightmap_Bias; + float2 prev_uv = cur_uv; + float cur_layer = 0.0; + float sampled_height = heightmap_sample(cur_uv); - float prev_depth = cur_depth; - float prev_height = cur_height; + float prev_layer = cur_layer; [loop] - for (int i = 0; i < (int)step_count; i++) { - bool was_inside = cur_depth < cur_height; - if (was_inside != inside) break; + for (int i = 0; i < step_count_i; i++) { + if (cur_layer >= sampled_height) break; - prev_depth = cur_depth; - prev_height = cur_height; + prev_layer = cur_layer; prev_uv = cur_uv; cur_uv += delta_uv; - cur_depth += delta_depth; - cur_height = 1.0 - heightmap_sample(cur_uv); - cur_height = (cur_height - (1.0 - _Parallax_Heightmap_Bias)); + cur_layer += delta_layer; + sampled_height = heightmap_sample(cur_uv); } // Short binary refine between last two samples to tighten the hit - float before = prev_height - prev_depth; float2 low_uv = prev_uv; - float low_depth = prev_depth; - float low_sign = before; + float low_layer = prev_layer; float2 high_uv = cur_uv; - float high_depth = cur_depth; + float high_layer = cur_layer; [unroll(2)] for (int j = 0; j < 2; j++) { - float mid_height = 1.0 - heightmap_sample(0.5 * (low_uv + high_uv)); - mid_height = (mid_height - (1.0 - _Parallax_Heightmap_Bias)); - float mid_depth = 0.5 * (low_depth + high_depth); - float mid_sign = mid_height - mid_depth; - if (mid_sign == 0.0 || sign(mid_sign) == sign(low_sign)) { - low_uv = 0.5 * (low_uv + high_uv); - low_depth = mid_depth; - low_sign = mid_sign; + float2 mid_uv = 0.5 * (low_uv + high_uv); + float mid_layer = 0.5 * (low_layer + high_layer); + float mid_height = heightmap_sample(mid_uv); + if (mid_layer < mid_height) { + low_uv = mid_uv; + low_layer = mid_layer; } else { - high_uv = 0.5 * (low_uv + high_uv); - high_depth = mid_depth; + high_uv = mid_uv; + high_layer = mid_layer; } } float2 refine_uv = 0.5 * (low_uv + high_uv); return refine_uv - uv; #else - float height = heightmap_sample(uv); - height = saturate(height - _Parallax_Heightmap_Bias); - + float height = heightmap_sample(uv) - _Parallax_Heightmap_Bias; return uv_step * height; #endif } @@ -258,19 +241,19 @@ Pbr getPbr(v2f i) { #endif #if defined(_PARALLAX_HEIGHTMAP) - float2 uv_parallax = i.uv01.xy + parallax_offset(i.uv01.xy, normalize(i.eyeVec.xyz), pbr.tbn); + float2 uv_parallax = i.uv01.xy + parallax_offset(i.uv01.xy, normalize(-i.eyeVec.xyz), pbr.tbn); #else float2 uv_parallax = i.uv01.xy; #endif // _PARALLAX_HEIGHTMAP -#if defined(_PARALLAX_HEIGHTMAP) || defined(_BURLEY_TILING_HEIGHTMAP) - pbr.height = heightmap_sample(i.uv01.xy); -#endif - #if defined(_BURLEY_TILING) burley_tiling_setup(uv_parallax); #endif +#if defined(_PARALLAX_HEIGHTMAP) || defined(_BURLEY_TILING_HEIGHTMAP) + pbr.height = heightmap_sample(uv_parallax); +#endif + #if defined(OUTLINES_PASS) && defined(_OUTLINES) pbr.albedo = _Outlines_Color; #else |
