Perekyp/Assets/Shaders/RepairSurface.hlsl

90 lines
3.5 KiB
HLSL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef REPAIR_SURFACE_INCLUDED
#define REPAIR_SURFACE_INCLUDED
// Исправленная послойная модель реставрации кузова без артефактов на границах
void RepairSurface_float(
float N,
float3 BaseColor,
float3 RustColor,
float RustInitial,
float RustAmount,
float PuttyProgress,
float SandProgress,
float PaintProgress,
float PaintSmoothness,
out float3 Albedo,
out float Metallic,
out float Smoothness)
{
const float e = 0.04; // мягкость перехода
const float3 bareMetal = float3(0.55, 0.56, 0.58);
const float3 puttyRaw = float3(0.62, 0.58, 0.50);
const float3 puttySanded = float3(0.72, 0.70, 0.66);
float sand = saturate(SandProgress);
// 1. Исходная зона повреждения детали (0..1)
float zone = smoothstep(1.0 - RustInitial, 1.0 - RustInitial + e, N) * step(0.001, RustInitial);
// 2. Маска шпаклёвки (наносится поверх голого металла)
float fillEdge = 1.0 - PuttyProgress * (RustInitial + e);
float puttyMask = smoothstep(fillEdge + e, fillEdge, N) * step(0.001, PuttyProgress);
if (PuttyProgress >= 0.99) puttyMask = 1.0;
// Свойства подложки (голый металл или шпаклёвка)
float3 underColor = lerp(bareMetal, lerp(puttyRaw, puttySanded, sand), puttyMask);
float underSmooth = lerp(0.45, lerp(0.05, 0.35, sand), puttyMask);
float underMetal = lerp(0.8, 0.0, puttyMask);
// 3. Маска нанесения новой краски (растёт от краёв зоны внутрь)
float paintEdge = (1.0 - RustInitial) + PaintProgress * (RustInitial + e);
float paintMask = (1.0 - smoothstep(paintEdge, paintEdge + e, N)) * step(0.001, PaintProgress);
if (PaintProgress >= 0.99) paintMask = 1.0;
// ВАЖНО: Доля повреждения, которая ЕЩЁ видна (не перекрыта краской).
// При завершении покраски (paintMask = 1) это значение строго равно 0 даже на полутонах!
float damageVisible = zone * (1.0 - paintMask);
// 4. Очаги ржавчины (лежат поверх всего, пока не счищены)
float rust = smoothstep(1.0 - RustAmount, 1.0 - RustAmount + e, N) * step(0.001, RustAmount);
// Смешиваем заводскую краску с повреждением
float3 col = lerp(BaseColor, underColor, damageVisible);
float sm = lerp(PaintSmoothness, underSmooth, damageVisible);
float met = lerp(0.0, underMetal, damageVisible);
// Поверх накладываем оставшуюся ржавчину
col = lerp(col, RustColor, rust);
sm = lerp(sm, 0.1, rust);
met = lerp(met, 0.0, rust);
Albedo = col;
Metallic = met;
Smoothness = sm;
}
void RepairSurface_half(
half N,
half3 BaseColor,
half3 RustColor,
half RustInitial,
half RustAmount,
half PuttyProgress,
half SandProgress,
half PaintProgress,
half PaintSmoothness,
out half3 Albedo,
out half Metallic,
out half Smoothness)
{
float3 a;
float m;
float s;
RepairSurface_float(N, BaseColor, RustColor, RustInitial, RustAmount,
PuttyProgress, SandProgress, PaintProgress, PaintSmoothness, a, m, s);
Albedo = a;
Metallic = m;
Smoothness = s;
}
#endif