e4s-game/gamedata/shaders/r2/sload.hlsli
2026-06-18 01:18:29 +03:00

155 lines
4 KiB
HLSL

#ifndef SLOAD_H
#define SLOAD_H
#include "common.hlsli"
static const float fParallaxStartFade = 8.0f;
static const float fParallaxStopFade = 12.0f;
struct XrayMaterial
{
float Metalness;
float Roughness;
float3 Normal;
float3 Point;
float4 Color;
float Hemi;
float Sun;
float SSS;
float AO;
};
#ifdef USE_STEEPPARALLAX
#if defined(ALLOW_STEEPPARALLAX)
void UpdateTC(inout p_bumped_new I)
{
if (I.position.z < fParallaxStopFade)
{
const float maxSamples = 25;
const float minSamples = 5;
const float fParallaxOffset = -0.013f;
float3x3 TBN = float3x3(I.M1, I.M2, I.M3);
float3 viewDir = mul(transpose(TBN), -I.position);
viewDir = normalize(viewDir);
// Calculate number of steps
float nNumSteps = lerp(maxSamples, minSamples, viewDir.z);
float fStepSize = 1.0f / nNumSteps;
float2 vDelta = viewDir.xy * fParallaxOffset * 1.2f;
float2 vTexOffsetPerStep = fStepSize * vDelta;
// Prepare start data for cycle
float2 vTexCurrentOffset = I.tcdh.xy;
float fCurrHeight = 0.0f;
float fCurrentBound = 1.0f;
for (int i = 0; i < nNumSteps; ++i)
{
if (fCurrHeight < fCurrentBound)
{
vTexCurrentOffset += vTexOffsetPerStep;
fCurrHeight = tex2Dlod(s_bumpX, float4(vTexCurrentOffset.xy, 0.0f, 0.0f)).w;
fCurrentBound -= fStepSize;
}
}
// Reconstruct previouse step's data
vTexCurrentOffset -= vTexOffsetPerStep;
float fPrevHeight = tex2D(s_bumpX, vTexCurrentOffset.xy).w;
// Smooth tc position between current and previouse step
float fDelta2 = ((fCurrentBound + fStepSize) - fPrevHeight);
float fDelta1 = (fCurrentBound - fCurrHeight);
float fParallaxAmount = (fCurrentBound * fDelta2 - (fCurrentBound + fStepSize) * fDelta1) / (fDelta2 - fDelta1);
float fParallaxFade = smoothstep(fParallaxStopFade, fParallaxStartFade, I.position.z);
float2 vParallaxOffset = vDelta * fParallaxFade * (1.0f - fParallaxAmount);
float2 vTexCoord = I.tcdh.xy + vParallaxOffset;
// Output the result
I.tcdh.xy = vTexCoord;
}
}
#else
void UpdateTC(inout p_bumped_new I)
{
float3x3 TBN = float3x3(I.M1, I.M2, I.M3);
float3 viewDir = mul(transpose(TBN), -I.position);
viewDir = normalize(viewDir);
float height = tex2D(s_bumpX, I.tcdh.xy).w;
height = height * parallax.x + parallax.y;
// Output the result
I.tcdh.xy += height * viewDir.xy;
}
#endif
#endif
void SloadNew(inout p_bumped_new I, inout XrayMaterial M)
{
// Enable parallax only on near objects
#if defined(USE_STEEPPARALLAX) && defined(USE_HIGH_QUALITY)
UpdateTC(I);
#endif
M.Color = tex2D(s_base, I.tcdh.xy);
#ifdef USE_BUMP
float4 Bump = tex2D(s_bump, I.tcdh.xy);
float4 BumpX = tex2D(s_bumpX, I.tcdh.xy);
// #ifndef USE_PBR
M.Normal = Bump.wzy + BumpX.xyz - 1.0f;
M.Normal.z *= 0.5f;
M.Roughness = Bump.x * Bump.x;
M.Metalness = 0.0f;
M.SSS = 0.0;
M.AO = 1.0;
// #endif
#else
M.Normal = float3(0.0f, 0.0f, 1.0f);
M.Roughness = def_gloss;
M.Metalness = 0.0f;
M.SSS = 0.0f;
M.AO = 1.0f;
#endif
#ifdef USE_TDETAIL
float2 tcdbump = I.tcdh.xy * dt_params.xy;
float4 Detail = tex2D(s_detail, tcdbump);
#ifndef USE_PBR
M.Color.xyz *= Detail.xyz * 2.0f;
#ifdef USE_TDETAIL_BUMP
float4 DetailBump = tex2D(s_detailBump, tcdbump);
float4 DetailBumpX = tex2D(s_detailBumpX, tcdbump);
M.Normal += DetailBump.wzy + DetailBumpX.xyz - 1.0f;
M.Roughness *= DetailBump.x * 2.0f;
#else
M.Roughness *= Detail.w * 2.0f;
#endif
#endif
#endif
#ifndef USE_PBR
M.Metalness = M.Roughness * 0.1f;
M.Roughness = saturate(1.0f - M.Roughness);
#endif
}
#endif