This commit is contained in:
Vasily Petrov 2026-06-18 01:18:29 +03:00
commit 2fe6ca2f65
1473 changed files with 251771 additions and 0 deletions

View file

@ -0,0 +1,52 @@
#include "common.hlsli"
#include "shadow.hlsli"
#include "metalic_roughness_light.hlsli"
#include "ScreenSpaceContactShadows.hlsl"
uniform float4 m_lmap[2];
uniform int Ldynamic_hud;
//LVutner: Force early-z
[earlydepthstencil]
float4 main(p_volume I, float4 pos2d : SV_POSITION) : SV_Target
{
float2 tcProj = I.tc.xy / I.tc.w;
IXrayGbuffer O;
GbufferUnpack(tcProj, pos2d.xy, O);
float4 Point = float4(Ldynamic_hud > 0 ? O.PointHud.xyz : O.Point.xyz, 1.0f);
float3 LightDirection = normalize(O.PointReal.xyz - Ldynamic_pos.xyz);
float3 Light = DirectLight(Ldynamic_color, LightDirection, O.Normal, O.View.xyz, O.Color, O.Metalness, O.Roughness, O.F0);
float3 Lightmap = ComputeLightAttention(Point.xyz - Ldynamic_pos.xyz, Ldynamic_pos.w);
Point.xyz += O.Normal * 0.025f;
float4 PS = mul(m_shadow, Point);
#ifdef USE_SHADOW
Lightmap *= max(Ldynamic_hud, shadow(PS));
#ifdef USE_HUD_SHADOWS
if (O.Depth < 0.02f && dot(Lightmap.xyz, Light.xyz) > 0.0001f)
{
RayTraceContactShadow(tcProj, O.PointHud, LightDirection, Lightmap);
}
#endif
#endif
#ifdef USE_LMAP
#ifdef USE_LMAPXFORM
PS.x = dot(Point, m_lmap[0]);
PS.y = dot(Point, m_lmap[1]);
#endif
Lightmap *= s_lmap.SampleLevel(smp_rtlinear, PS.xy / PS.w, 0.0f).xyz;
#endif
Lightmap = PushGamma(Lightmap);
return float4(Lightmap.xyz * Light.xyz, 0.0f);
}

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
float4 main(p_bumped_new I) : SV_Target
{
return float4(PushGamma(s_base.Sample(smp_base, I.tcdh.xy).xyz) * 16.0f, 0.0f);
}

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
float4 main(p_bumped_new I) : SV_Target
{
return float4(PushGamma(s_base.Sample(smp_base, I.tcdh.xy).xyz), 0.0f);
}

View file

@ -0,0 +1,6 @@
#include "common.hlsli"
float4 main(p_bumped_new I) : SV_Target
{
return float4(s_base.Sample(smp_base, I.tcdh.xy).xyz * 9.0f, 0.0f);
}

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
float4 main() : SV_Target
{
return 0;
}

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
float4 main(float4 P : POSITION) : SV_POSITION
{
return mul(m_WVP, P);
}

View file

@ -0,0 +1,64 @@
#include "common.hlsli"
#if SUN_QUALITY > 2
#define USE_ULTRA_SHADOWS
#endif
#include "shadow.hlsli"
#include "metalic_roughness_light.hlsli"
#include "ScreenSpaceContactShadows.hlsl"
float4 main(v2p_volume I) : SV_Target
{
float2 tcProj = I.tc.xy / I.tc.w;
IXrayGbuffer O;
GbufferUnpack(tcProj, I.hpos.xy, O);
float3 Shift = O.Normal;
if (O.SSS > 0.0f)
{
Shift *= dot(Ldynamic_dir.xyz, Shift) >= 0.0 ? -1.0f : 1.0f;
}
float4 Point = float4(O.Point.xyz, 1.f);
Point.xyz += Shift * 0.025f;
float4 PS = mul(m_shadow, Point);
#ifdef USE_FAR_ATTENTION
float3 Factor = smoothstep(0.5f, 0.45f, abs(PS.xyz / PS.w - 0.5f));
float Fade = Factor.x * Factor.y * Factor.z;
O.SSS *= 0.5f + 0.5f * Fade;
#endif
float3 Light = DirectLight(Ldynamic_color, Ldynamic_dir.xyz, O.Normal, O.View.xyz, O.Color, O.Metalness, O.Roughness, O.F0);
Light += SimpleTranslucency(Ldynamic_color.xyz, Ldynamic_dir.xyz, O.Normal) * O.SSS * O.Color;
#if SUN_QUALITY == 2
float Shadow = shadow_high(PS);
#else
float Shadow = shadow(PS);
#endif
#ifdef USE_FAR_ATTENTION
float FarShadow = dot(Ldynamic_dir.xyz, O.Normal.xyz);
FarShadow = smoothstep(0.75f, 0.6f, FarShadow) * saturate(O.Hemi * 8.0f - 2.0f);
Shadow = lerp(FarShadow, Shadow, Fade);
#elif defined(USE_HUD_SHADOWS)
if (O.Depth < 0.02f && dot(Shadow.xxx, Light.xyz) > 0.0001f)
{
RayTraceContactShadow(tcProj, O.PointHud, Ldynamic_dir.xyz, Light);
}
#endif
Shadow *= sunmask(Point);
Shadow = PushGamma(Shadow);
return float4(Light * Shadow, Shadow);
}

View file

@ -0,0 +1,12 @@
#include "common.hlsli"
uniform float4x4 m_texgen;
// Vertex
v2p_volume main(float4 P : POSITION)
{
v2p_volume O;
O.hpos = mul(m_WVP, P);
O.tc = mul(m_texgen, P);
return O;
}

View file

@ -0,0 +1,18 @@
#include "common.hlsli"
#define EPS (0.9f / 255.f)
#define CLIP_THRESHOLD (1.0f / 255.f)
float4 main(p_TL I, float4 pos2d : SV_POSITION) : SV_Target
{
IXrayGbuffer O;
GbufferUnpack(I.Tex0, pos2d.xy, O);
// float4 NH = float4(O.Normal, O.Hemi);
float L = O.Hemi + O.SSS;
clip(L);
return float4(L, L, L, L);
}

View file

@ -0,0 +1,13 @@
#include "common.hlsli"
uniform float4x4 m_texgen;
// Vertex
v2p_volume main(float4 P : POSITION)
{
v2p_volume O;
O.hpos = mul(m_WVP, P);
O.tc = mul(m_texgen, P);
return O;
}

View file

@ -0,0 +1,68 @@
#include "common.hlsli"
#include "shadow.hlsli"
struct v2p
{
float3 lightToPos : TEXCOORD0; // light center to plane vector
float3 vPos : TEXCOORD1; // position in camera space
float fDensity : TEXCOORD2; // plane density along Z axis
};
uniform float4 m_lmap[2];
Texture2D s_noise;
#define USE_LMAP
#define USE_LMAPXFORM
#define USE_SHADOW
// Pixel
float4 main(v2p I) : SV_Target
{
// ----- shadow
float4 P4 = float4(I.vPos, 1);
float4 PS = mul(m_shadow, P4);
float s = 1.0f;
#ifdef USE_SHADOW
s = shadow(PS);
#endif
// ----- lightmap
float4 lightmap = 1.0f;
#ifdef USE_LMAP
#ifdef USE_LMAPXFORM
PS.x = dot(P4, m_lmap[0]);
PS.y = dot(P4, m_lmap[1]);
#endif
lightmap = s_lmap.Sample(smp_rtlinear, PS.xy / PS.w);
#endif
// ----- attenuate
float rsqr = dot(I.lightToPos, I.lightToPos); // distance 2 light (squared)
float att = saturate(1 - rsqr * Ldynamic_pos.w); // q-linear attenuate
// ----- noise
PS.xy /= PS.w;
PS.xy *= 0.3333;
float time = timers.z * 0.1;
PS.x += time;
float4 t_noise = s_noise.SampleLevel(smp_linear, PS.xy, 0);
PS.x -= time;
PS.y -= time * 0.70091;
t_noise *= s_noise.SampleLevel(smp_linear, PS.xy, 0);
t_noise = t_noise * 0.5 + 0.5;
// out
float maxIntens = I.fDensity;
float3 result = maxIntens * s * att;
result *= lightmap.xyz;
result *= Ldynamic_color.xyz * t_noise.xyz;
return float4(PushGamma(result), 0);
}

View file

@ -0,0 +1,43 @@
#include "common.hlsli"
cbuffer VolumetricLights
{
float3 vMinBounds;
float3 vMaxBounds;
float4 FrustumClipPlane[6];
}
struct v2p
{
float3 lightToPos : TEXCOORD0; // light center to plane vector
float3 vPos : TEXCOORD1; // position in camera space
float fDensity : TEXCOORD2; // plane density alon Z axis
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 hpos : SV_POSITION;
};
v2p main(float3 P : POSITION)
{
v2p o;
float4 vPos = 1.0f;
vPos.xyz = lerp(vMinBounds, vMaxBounds, P);
o.hpos = mul(m_P, vPos);
o.lightToPos = vPos.xyz - Ldynamic_pos.xyz;
o.vPos = vPos.xyz;
o.fDensity = 0.025f;
o.clip0.x = dot(o.hpos, FrustumClipPlane[0]);
o.clip0.y = dot(o.hpos, FrustumClipPlane[1]);
o.clip0.z = dot(o.hpos, FrustumClipPlane[2]);
o.clip1.x = dot(o.hpos, FrustumClipPlane[3]);
o.clip1.y = dot(o.hpos, FrustumClipPlane[4]);
o.clip1.z = dot(o.hpos, FrustumClipPlane[5]);
return o;
}

View file

@ -0,0 +1,14 @@
<w>
<element_0 ps="accum_volumetric" vs="accum_volumetric" fog="0" zread="1" zwrite="0">
<blend status="1" src="one" dest="one" />
<sort status="0" count="2" />
<texture name="s_lmap" rt="t_base" />
<texture name="s_smap" rt="$user$smap_depth" />
<texture name="s_noise" rt="fx\fx_noise" />
<sampler name="smp_rtlinear" />
<sampler name="smp_linear" />
<sampler name="smp_smap" />
</element_0>
</w>

View file

@ -0,0 +1,15 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_notransform_2uv", "accum_volumetric_sun")
:fog(false)
:zb(false, false)
:blend(true, blend.one, blend.one)
:sorting(2, false)
shader:dx10texture("s_smap", "$user$smap_depth")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("jitter0", "$user$jitter_0")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_jitter")
shader:dx10sampler("smp_smap")
end

View file

@ -0,0 +1,92 @@
#include "common.hlsli"
#undef USE_ULTRA_SHADOWS
#define RAY_PATH 2.0h
#define JITTER_TEXTURE_SIZE 64.0f
#define JITTER_SUN_SHAFTS
#ifdef SUN_SHAFTS_QUALITY
#if SUN_SHAFTS_QUALITY == 1
// #define FILTER_LOW
#define RAY_SAMPLES 20
#elif SUN_SHAFTS_QUALITY == 2
// #define FILTER_LOW
#define RAY_SAMPLES 20
#elif SUN_SHAFTS_QUALITY == 3
// #define FILTER_LOW
#define RAY_SAMPLES 40
#endif
#endif
#include "shadow.hlsli"
float4 volume_range; // x - near plane, y - far plane
float4 sun_shafts_intensity;
float4 main(v2p_TL I) : SV_Target
{
#ifndef SUN_SHAFTS_QUALITY
return float4(0, 0, 0, 0);
#else // SUN_SHAFTS_QUALITY
IXrayGbuffer O;
GbufferUnpack(I.Tex0.xy, I.HPos.xy, O);
float3 P = O.Point;
#ifndef JITTER_SUN_SHAFTS
// Fixed ray length, fixed step dencity
// float3 direction = (RAY_PATH/RAY_SAMPLES)*normalize(P);
// Variable ray length, variable step dencity
float3 direction = P / RAY_SAMPLES;
#else // JITTER_SUN_SHAFTS
// Variable ray length, variable step dencity, use jittering
float4 J0 = jitter0.Sample(smp_jitter, I.HPos.xy / JITTER_TEXTURE_SIZE);
float coeff = (RAY_SAMPLES - J0.x) / (RAY_SAMPLES * RAY_SAMPLES);
float3 direction = P * coeff;
#endif // JITTER_SUN_SHAFTS
float depth = P.z;
float deltaDepth = direction.z;
float4 current = mul(m_shadow, float4(P, 1.0f));
float4 delta = mul(m_shadow, float4(direction, 0.0f));
float res = 0.0f;
float max_density = sun_shafts_intensity.x;
float density = max_density / RAY_SAMPLES;
if(O.Depth > 0.9999f) {
depth = 0.0f;
res = max_density;
}
[unroll] for(int i = 0; i < RAY_SAMPLES; ++i)
{
if (depth > 0.3)
{
#ifndef FILTER_LOW
res += density * shadow(current);
#else
res += density * sample_hw_pcf(current, float4(0, 0, 0, 0));
#endif
}
depth -= deltaDepth;
current -= delta;
}
float fSturation = dot(normalize(P), -Ldynamic_dir.xyz);
// Normalize dot product to
fSturation = 0.4f * fSturation + 0.6f;
float fog = saturate(length(P.xyz) * fog_params.w + fog_params.x);
res = lerp(res, max_density, fog);
res *= fSturation;
return PushGamma(res * Ldynamic_color);
#endif // SUN_SHAFTS_QUALITY
}

View file

@ -0,0 +1,15 @@
#include "common.hlsli"
struct v2p
{
float2 tc0 : TEXCOORD0; // base
float4 c0 : COLOR0; // sun
};
// Pixel
float4 main(v2p I) : SV_Target
{
float4 t_base = s_base.Sample(smp_base, I.tc0);
return PushGamma(float4(t_base.xyz, t_base.w * I.c0.w));
}

View file

@ -0,0 +1,27 @@
#include "common.hlsli"
struct vf
{
float2 tc0 : TEXCOORD0; // base
float4 c0 : COLOR0; // color
float4 hpos : SV_POSITION;
};
vf main(v_static v)
{
vf o;
o.hpos = mul(m_WVP, v.P); // xform, input in world coords
o.tc0 = unpack_tc_base(v.tc, v.T.w, v.B.w); // copy tc
// calculate fade
float3 dir_v = normalize(mul(m_WV, v.P));
float3 norm_v = normalize(mul((float3x3)m_WV, unpack_normal(v.Nh.zyx)));
float fade = abs(dot(dir_v, norm_v));
o.c0 = fade;
o.hpos.xy += m_taa_jitter.xy * o.hpos.w;
return o;
}

View file

@ -0,0 +1,31 @@
#include "common.hlsli"
struct v2p
{
float2 tc0: TEXCOORD0; // base
// float2 tc1: TEXCOORD1; // lmap
float4 c0: COLOR0; // sun
};
uniform float4 m_hud_params;
inline bool isCollimatorActive()
{
return (m_hud_params.w == 1.f);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
float4 main( p_bumped_new I ) : SV_Target
{
float4 color = s_base.Sample(smp_base, I.tcdh.xy);
if (isCollimatorActive())
{
return float4(color.xyz * color.w, 0.0f);
}
else
{
return float4(0.0, 0.0, 0.0, 0.0);
}
}

View file

@ -0,0 +1,17 @@
#include "common.hlsli"
uniform float4 b_params;
float4 main(p_build I) : SV_Target
{
float3 s0 = s_image.Sample(smp_rtlinear, I.Tex0.xy).xyz;
float3 s1 = s_image.Sample(smp_rtlinear, I.Tex1.xy).xyz;
float3 s2 = s_image.Sample(smp_rtlinear, I.Tex2.xy).xyz;
float3 s3 = s_image.Sample(smp_rtlinear, I.Tex3.xy).xyz;
float3 avg = PopGamma(s0 + s1 + s2 + s3) / (2.0f * def_hdr);
float hi = dot(avg, 1.h) - b_params.x;
return float4(avg, hi);
}

View file

@ -0,0 +1,33 @@
#include "common.hlsli"
uniform float4 weight[2];
float4 main(p_filter I) : SV_Target
{
float4 accum = weight[1].w * s_bloom.Sample(smp_rtlinear, I.Tex0.xy);
accum += weight[0].x * s_bloom.Sample(smp_rtlinear, I.Tex1.xy);
accum += weight[0].x * s_bloom.Sample(smp_rtlinear, I.Tex1.wz);
accum += weight[0].y * s_bloom.Sample(smp_rtlinear, I.Tex2.xy);
accum += weight[0].y * s_bloom.Sample(smp_rtlinear, I.Tex2.wz);
accum += weight[0].z * s_bloom.Sample(smp_rtlinear, I.Tex3.xy);
accum += weight[0].z * s_bloom.Sample(smp_rtlinear, I.Tex3.wz);
accum += weight[0].w * s_bloom.Sample(smp_rtlinear, I.Tex4.xy);
accum += weight[0].w * s_bloom.Sample(smp_rtlinear, I.Tex4.wz);
accum += weight[1].x * s_bloom.Sample(smp_rtlinear, I.Tex5.xy);
accum += weight[1].x * s_bloom.Sample(smp_rtlinear, I.Tex5.wz);
accum += weight[1].y * s_bloom.Sample(smp_rtlinear, I.Tex6.xy);
accum += weight[1].y * s_bloom.Sample(smp_rtlinear, I.Tex6.wz);
accum += weight[1].z * s_bloom.Sample(smp_rtlinear, I.Tex7.xy);
accum += weight[1].z * s_bloom.Sample(smp_rtlinear, I.Tex7.wz);
// OK
return accum;
}

View file

@ -0,0 +1,28 @@
#include "common.hlsli"
/*
struct v2p
{
float2 tc0: TEXCOORD0; // base
float2 tc1: TEXCOORD1; // base
float2 tc2: TEXCOORD2; // base
float2 tc3: TEXCOORD3; // base
};
*/
// Pixel
float4 main(p_build I) : SV_Target
{
// float4 t_0 = tex2D (s_bloom,I.tc0);
// float4 t_1 = tex2D (s_bloom,I.tc1);
// float4 t_2 = tex2D (s_bloom,I.tc2);
// float4 t_3 = tex2D (s_bloom,I.tc3);
float4 t_0 = s_image.Sample(smp_rtlinear, I.Tex0);
float4 t_1 = s_image.Sample(smp_rtlinear, I.Tex1);
float4 t_2 = s_image.Sample(smp_rtlinear, I.Tex2);
float4 t_3 = s_image.Sample(smp_rtlinear, I.Tex3);
// out
return ((t_0 + t_1) + (t_2 + t_3)) / 2;
}

View file

@ -0,0 +1,21 @@
#include "common.hlsli"
float luminance(float2 tc)
{
float3 source = s_image.Sample(smp_rtlinear, tc).xyz;
return dot(source, LUMINANCE_VECTOR) * def_hdr;
}
float4 main(p_build I) : SV_Target
{
float4 final;
final.x = luminance(I.Tex0);
final.y = luminance(I.Tex1);
final.z = luminance(I.Tex2);
final.w = luminance(I.Tex3);
// OK
return final;
}

View file

@ -0,0 +1,59 @@
#include "common.hlsli"
struct v2p
{
float4 tc0 : TEXCOORD0;
float4 tc1 : TEXCOORD1;
float4 tc2 : TEXCOORD2;
float4 tc3 : TEXCOORD3;
float4 tc4 : TEXCOORD4;
float4 tc5 : TEXCOORD5;
float4 tc6 : TEXCOORD6;
float4 tc7 : TEXCOORD7;
};
float sample(float2 tc)
{
float4 data = s_image.Sample(smp_rtlinear, tc);
return dot(data, 0.25f);
}
float4 main(p_filter I) : SV_Target
{
// sample
float4 accum0;
accum0.x = sample(I.Tex0.xy);
accum0.y = sample(I.Tex1.xy);
accum0.z = sample(I.Tex2.xy);
accum0.w = sample(I.Tex3.xy);
float4 accum1;
accum1.x = sample(I.Tex4.xy);
accum1.y = sample(I.Tex5.xy);
accum1.z = sample(I.Tex6.xy);
accum1.w = sample(I.Tex7.xy);
float4 accum2;
accum2.x = sample(I.Tex0.wz);
accum2.y = sample(I.Tex1.wz);
accum2.z = sample(I.Tex2.wz);
accum2.w = sample(I.Tex3.wz);
float4 accum3;
accum3.x = sample(I.Tex4.wz);
accum3.y = sample(I.Tex5.wz);
accum3.z = sample(I.Tex6.wz);
accum3.w = sample(I.Tex7.wz);
// perform accumulation
float4 final;
final.x = dot(accum0, 0.25f);
final.y = dot(accum1, 0.25f);
final.z = dot(accum2, 0.25f);
final.w = dot(accum3, 0.25f);
// OK
return final;
}

View file

@ -0,0 +1,59 @@
#include "common.hlsli"
uniform float4 MiddleGray;
float sample(float2 tc)
{
float4 data = s_image.Sample(smp_rtlinear, tc);
return dot(data, 0.25f);
}
float4 main(p_filter I) : SV_Target
{
// sample
float4 accum0;
accum0.x = sample(I.Tex0.xy);
accum0.y = sample(I.Tex1.xy);
accum0.z = sample(I.Tex2.xy);
accum0.w = sample(I.Tex3.xy);
float4 accum1;
accum1.x = sample(I.Tex4.xy);
accum1.y = sample(I.Tex5.xy);
accum1.z = sample(I.Tex6.xy);
accum1.w = sample(I.Tex7.xy);
float4 accum2;
accum2.x = sample(I.Tex0.wz);
accum2.y = sample(I.Tex1.wz);
accum2.z = sample(I.Tex2.wz);
accum2.w = sample(I.Tex3.wz);
float4 accum3;
accum3.x = sample(I.Tex4.wz);
accum3.y = sample(I.Tex5.wz);
accum3.z = sample(I.Tex6.wz);
accum3.w = sample(I.Tex7.wz);
// perform accumulation
float4 final;
final.x = dot(accum0, 0.25f);
final.y = dot(accum1, 0.25f);
final.z = dot(accum2, 0.25f);
final.w = dot(accum3, 0.25f);
float result = dot(final, 0.25f);
result = PushGamma(result);
// OK
float scale = MiddleGray.x / (result * MiddleGray.y + MiddleGray.z);
float scale_prev = s_tonemap.Sample(smp_nofilter, I.Tex0.xy).x;
float rvalue = lerp(scale_prev, scale, MiddleGray.w);
clamp(rvalue, 1.f / 128.f, 20.0f);
return rvalue;
}

View file

@ -0,0 +1,65 @@
#ifndef cgim_h_included
#define cgim_h_included
// creates more light by a vector from the sky
#define SMALLSKY_TOP_VECTOR_POWER 0.75f
// Break default bloom to soften the overall picture
#define BROKE_BLOOM_POWER 1.5f
#define CGIM_LUM float3(0.2126f, 0.7152f, 0.0722f)
float Luminance(float3 Color)
{
return dot(Color, CGIM_LUM);
}
float3 TonemapRobo(float3 c)
{
float l = Luminance(c);
return c / sqrt(1.0 + l * l);
}
float TonemapRobo(float c)
{
return c / sqrt(1.0 + c * c);
}
float4 BrokeBloom(float4 c)
{
c *= BROKE_BLOOM_POWER;
c = float4(TonemapRobo(c.rgb), TonemapRobo(c.a));
c /= BROKE_BLOOM_POWER;
return c;
}
float3 Uncharted2ACES(float3 x)
{
static const float A = 0.15f; // Shoulder strength
static const float B = 0.50f; // Linear strength
static const float C = 0.10f; // Linear angle
static const float D = 0.20f; // Toe strength
static const float E = 0.02f; // Toe numerator
static const float F = 0.30f; // Toe denominator
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}
// Uncharted 2 tonemapping
#define UNCHARTED2TONEMAP_WHITEPT 1.35
#define UNCHARTED2TONEMAP_EXPOSURE 1.0
float3 Uncharted2Tonemap(float3 c)
{
c *= UNCHARTED2TONEMAP_EXPOSURE;
float3 tc = Uncharted2ACES(c);
float l = Luminance(c);
c = lerp(c * Uncharted2ACES(l) / l, tc, tc);
c /= Uncharted2ACES(UNCHARTED2TONEMAP_WHITEPT);
return c;
}
#endif

View file

@ -0,0 +1,13 @@
#include "common.hlsli"
uniform float4 screen_res;
float4 main(p_shadow I) : SV_Target
{
float3 col;
float factor = saturate(distance(I.tc0, float2(0.5, 0.5)));
col.r = s_image.Sample(smp_rtlinear, float2(I.tc0 + float2(screen_res.z * factor, 0))).r;
col.g = s_image.Sample(smp_rtlinear, float2(I.tc0 + float2(-0.866, -0.5) * screen_res.zw * factor)).g;
col.b = s_image.Sample(smp_rtlinear, float2(I.tc0 + float2(0.866, -0.5) * screen_res.zw * factor)).b;
return float4(col, 1);
}

View file

@ -0,0 +1,12 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("clouds", "clouds")
:fog(false)
:zb(false, false)
:sorting(3, true)
:blend(true, blend.srcalpha, blend.invsrcalpha)
shader:dx10texture("s_clouds0", "null")
shader:dx10texture("s_clouds1", "null")
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,26 @@
#include "common.hlsli"
struct v2p
{
float4 color : COLOR0;
float2 tc0 : TEXCOORD0;
float2 tc1 : TEXCOORD1;
};
Texture2D s_clouds0 : register(t0);
Texture2D s_clouds1 : register(t1);
// Pixel
float4 main(v2p I) : SV_Target
{
float4 s0 = s_clouds0.Sample(smp_base, I.tc0);
float4 s1 = s_clouds1.Sample(smp_base, I.tc1);
float4 mix = I.color * (s0 + s1);
#ifdef USE_LEGACY_SKY_TONEMAP
return float4(detonemap(mix.xyz), mix.w);
#else
return float4(PushGamma(mix.xyz), mix.w);
#endif
}

View file

@ -0,0 +1,37 @@
#include "common.hlsli"
#include "shared\cloudconfig.hlsli"
struct vi
{
float4 p : POSITION;
float4 dir : COLOR0; // dir0,dir1(w<->z)
float4 color : COLOR1; // rgb. intensity
};
struct vf
{
float4 color : COLOR0; // rgb. intensity, for SM3 - tonemap-prescaled, HI-res
float2 tc0 : TEXCOORD0;
float2 tc1 : TEXCOORD1;
float4 hpos : SV_POSITION;
};
vf main(vi v)
{
vf o;
o.hpos = mul(m_WVP, v.p); // xform, input in world coords
o.hpos.xy += m_taa_jitter.xy * o.hpos.w;
// generate tcs
float2 d0 = v.dir.xy * 2.0f - 1.0f;
float2 d1 = v.dir.wz * 2.0f - 1.0f;
float2 _0 = v.p.xz * CLOUD_TILE0 + d0 * timers.z * CLOUD_SPEED0;
float2 _1 = v.p.xz * CLOUD_TILE1 + d1 * timers.z * CLOUD_SPEED1;
o.tc0 = _0;
o.tc1 = _1;
o.color = v.color;
o.color.w *= pow(v.p.y, 25.0f);
return o;
}

View file

@ -0,0 +1,57 @@
#include "common.hlsli"
#if defined(USE_OFFSCREEN_REFLECTIONS) && !defined(USE_SSLR_REFLECTIONS)
#define USE_VIEW_REFLECTIONS
#endif
#include "metalic_roughness_light.hlsli"
#include "metalic_roughness_ambient.hlsli"
#include "reflections.hlsli"
Texture2D<float> s_occ;
struct _input
{
float4 tc0 : TEXCOORD0;
float2 tcJ : TEXCOORD1;
float4 pos2d : SV_POSITION;
};
float4 main(_input I) : SV_Target
{
IXrayGbuffer O;
GbufferUnpack(I.tc0.xy, I.pos2d.xy, O);
float3 Light = s_accumulator.Load(int3(I.pos2d.xy, 0)).xyz;
#ifdef USE_R2_STATIC_SUN
Light += O.SSS * DirectLight(Ldynamic_color, Ldynamic_dir.xyz, O.Normal, O.View.xyz, O.Color, O.Metalness, O.Roughness, O.F0);
#endif
float Occ = O.AO * s_occ.SampleLevel(smp_rtlinear, I.tc0.xy, 0.0f).x;
#ifndef USE_LEGACY_LIGHT
#ifdef USE_SSLR_REFLECTIONS
float3 SpecularIrradance = s_refl.SampleLevel(smp_rtlinear, I.tc0, 0.0).xyz;
SpecularIrradance *= rcp(1.00001f - SpecularIrradance);
#else
float3 SpecularIrradance = CompureSpecularIrradance(reflect(O.View, O.Normal), O.Hemi, O.Roughness);
#endif
float3 DiffuseIrradance = CompureDiffuseIrradance(O.Normal, O.Hemi) + L_ambient.xyz;
float3 Ambient = AmbientLighting(DiffuseIrradance, SpecularIrradance, max(0.0, dot(O.Normal, -O.View.xyz)), O.Color, O.Metalness, O.Roughness, O.F0);
#else
float3 Ambient = AmbientLighting(O.View, O.Normal, O.Color, O.Metalness, O.Roughness, O.Hemi, O.F0);
#endif
float3 Color = Occ * Ambient + Light;
float Fog = PushGamma(saturate(O.ViewDist * fog_params.w + fog_params.x));
Color = lerp(Color, PushGamma(fog_color.xyz), Fog);
#ifdef USE_LEGACY_LIGHT
Fog *= Fog;
#endif
return float4(Color, Fog);
}

View file

@ -0,0 +1,24 @@
#include "common.hlsli"
struct _in
{
float4 P : POSITIONT; // xy=pos, zw=tc0
float2 tcJ : TEXCOORD0; // jitter coords
};
struct v2p
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
float2 tcJ : TEXCOORD1; // jitter coords
float4 hpos : SV_POSITION;
};
// Vertex
v2p main(_in I)
{
v2p O;
O.hpos = float4(I.P.x, -I.P.y, 0, 1);
O.tc0 = float4(I.P.zw, 1, 1);
O.tcJ = I.tcJ;
return O;
}

View file

@ -0,0 +1,31 @@
#include "common.hlsli"
#include "mblur.hlsli"
#include "dof.hlsli"
Texture3D s_lut;
float3 main(v2p_aa_AA I) : SV_Target
{
float3 Color = max(0.0f, dof(I.Tex0));
float4 Bloom = s_bloom.Sample(smp_rtlinear, I.Tex0);
#ifdef USE_CGIM_BLOOM_TWEAK
Bloom = BrokeBloom(Bloom);
#endif
float Scale = s_tonemap.Sample(smp_nofilter, float2(0.5f, 0.5f)).x;
Color = tonemap(Color, Scale);
Color = combine_bloom(Color, Bloom).xyz;
#ifdef USE_CGIM_COLOR_TWEAK
Color = Uncharted2Tonemap(Color);
#endif
#ifdef USE_LUT_TEXTURE
Color = s_lut.Sample(smp_rtlinear, saturate(Color)).xyz;
#endif
return Color;
}

View file

@ -0,0 +1,21 @@
#include "common.hlsli"
Texture2D s_distort;
float4 main(v2p_TL Input) : SV_Target
{
float4 distort = s_distort.SampleLevel(smp_nofilter, Input.Tex0, 0);
float2 offset = distort.xy - (127.0f / 255.0f);
float2 center = Input.Tex0 + offset * def_distort;
float depth_x = s_position.SampleLevel(smp_nofilter, center, 0).x;
#ifdef SIMPLE_DISTORTION_FIX
float depth = s_position.SampleLevel(smp_nofilter, Input.Tex0, 0).x;
#else
#define depth 0.02f
#endif
center = depth_x < depth ? Input.Tex0 : center;
return s_image.SampleLevel(smp_nofilter, center, 0);
}

View file

@ -0,0 +1,10 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("combine_1", "combine_volumetric")
:fog(false)
:zb(false, false)
:blend(true, blend.one, blend.one)
:sorting(2, false)
shader:dx10texture("s_vollight", "$user$generic2")
shader:dx10sampler("smp_nofilter")
end

View file

@ -0,0 +1,13 @@
#include "common.hlsli"
Texture2D s_vollight;
struct _input
{
float4 tc0 : TEXCOORD0;
};
float4 main(_input I) : SV_Target
{
return s_vollight.Load(int3(I.tc0.xy * pos_decompression_params2.xy, 0));
}

View file

@ -0,0 +1,19 @@
#ifndef COMMON_H
#define COMMON_H
#pragma warning(disable : 4000)
#include "shared\common.hlsli"
#include "common_defines.hlsli"
#include "common_defines.hlsli"
#include "common_policies.hlsli"
#include "common_iostructs.hlsli"
#include "common_samplers.hlsli"
#include "common_cbuffers.hlsli"
#include "common_functions.hlsli"
#include "metalic_roughness_base.hlsli"
#include "cgim.h"
#endif

View file

@ -0,0 +1,21 @@
#ifndef common_cbuffers_h_included
#define common_cbuffers_h_included
// Used by dynamic lights and volumetric effects
cbuffer dynamic_light
{
float4 Ldynamic_color; // dynamic light color (rgb1) - spot/point/sun
float4 Ldynamic_pos; // dynamic light pos+1/range(w) - spot/point
float4 Ldynamic_dir; // dynamic light direction - sun
}
#else
cbuffer dynamic_light
{
float4 Ldynamic_color; // dynamic light color (rgb1) - spot/point/sun
float4 Ldynamic_pos; // dynamic light pos+1/range(w) - spot/point
float4 Ldynamic_dir; // dynamic light direction - sun
}
#endif // common_cbuffers_h_included

View file

@ -0,0 +1,24 @@
#ifndef common_defines_h_included
#define common_defines_h_included
// Defines //
#define def_gloss float(2.f / 255.f)
#define def_dbumph float(0.333f)
#define def_virtualh float(0.05f) // 5cm
#define def_distort float(0.05f) // we get -0.5 .. 0.5 range, this is -512 .. 512 for 1024, so scale it
#define def_hdr float(9.h) // hight luminance range float(3.h)
#define def_hdr_clip float(0.75h) //
#define LUMINANCE_VECTOR float3(0.3f, 0.38f, 0.22f)
#if defined(SM_5) || defined(SM_4_1)
#define TEXTURE2DMS(a, b) Texture2DMS<a>
#else
#define TEXTURE2DMS(a, b) Texture2DMS<a, b>
#endif
#ifndef SMAP_size
#define SMAP_size 1024
#endif
#endif // common_defines_h_included

View file

@ -0,0 +1,290 @@
#ifndef common_functions_h_included
#define common_functions_h_included
// contrast function
float Contrast(float Input, float ContrastPower)
{
// piecewise contrast function
bool IsAbovefloat = Input > 0.5f;
float ToRaise = saturate(2.0f * (IsAbovefloat ? 1.0f - Input : Input));
float Output = 0.5f * pow(ToRaise, ContrastPower);
Output = IsAbovefloat ? 1.0f - Output : Output;
return Output;
}
#ifndef SRGB_GAMMA
#define SRGB_GAMMA 2.2
#endif
#ifndef USE_LEGACY_LIGHT
#define PushGamma(x) pow(abs(x), SRGB_GAMMA)
#define PopGamma(x) pow(abs(x), rcp(SRGB_GAMMA))
#else
#define PushGamma(x) abs(x)
#define PopGamma(x) abs(x)
#endif
#ifndef USE_CGIM_WHITE_TWEAK
#define RCP_WHITE_SQR 0.34602f
#define INV_TONEMAP_COEF_ONE 0.61592f
#define INV_TONEMAP_COEF_TWO 1.44565f
#else
#define RCP_WHITE_SQR 0.416233f
#define INV_TONEMAP_COEF_ONE 0.335068f
#define INV_TONEMAP_COEF_TWO 1.20125f
#endif
float3 tonemap(float3 rgb, float scale)
{
rgb = rgb * scale;
rgb = rgb * (1.0f + rgb * RCP_WHITE_SQR) * rcp(rgb + 1.0f);
return PopGamma(rgb);
}
float3 detonemap(float3 rgb)
{
rgb = PushGamma(rgb);
float3 scale = rgb * rgb - INV_TONEMAP_COEF_ONE * rgb + 1.0f;
rgb = rgb + sqrt(scale) - 1.0f;
return rgb * INV_TONEMAP_COEF_TWO;
}
void RemapVector(inout float3 View)
{
float3 ViewPos = abs(View);
float ViewPosMax = max(ViewPos.x, max(ViewPos.y, ViewPos.z));
View *= rcp(ViewPosMax);
View.y = View.y * 2.0 - 1.0;
}
// Функции генерации случайных чисел [0, 1]
// START
float Hash(float n)
{
return frac(sin(n) * 43758.5453123f);
}
float Hash(float2 n)
{
return Hash(Hash(n.x) + n.y);
}
float Hash(float3 n)
{
return Hash(Hash(dot(n.xy, float2(12.989, 78.233))) + n.z);
}
float2 Hash22(float2 value)
{
return float2(
Hash(dot(value, float2(12.989, 78.233))),
Hash(dot(value, float2(39.346, 11.135))));
}
float3 Hash23(float2 value)
{
return float3(
Hash(dot(value, float2(12.989, 78.233))),
Hash(dot(value, float2(39.346, 11.135))),
Hash(dot(value, float2(73.156, 52.235))));
}
float2 Hash32(float3 value)
{
return float2(
Hash(dot(value, float3(12.989, 78.233, 123.134f))),
Hash(dot(value, float3(39.346, 11.135, 543.142f))));
}
float3 Hash33(float3 value)
{
return float3(
Hash(dot(value, float3(12.989, 78.233, 123.134f))),
Hash(dot(value, float3(39.346, 11.135, 543.142f))),
Hash(dot(value, float3(73.156, 52.235, 143.425f))));
}
// END
float GetBorderAtten(float2 tc, float2 att)
{
att.x *= pos_decompression_params2.y * pos_decompression_params2.z;
float2 factors = saturate(min(1.0f - tc, tc) * rcp(att));
return factors.x * factors.y;
}
bool GetBorderAtten(float2 tc)
{
float2 factors = min(1.0f - tc, tc);
return min(factors.x, factors.y) > 0.0f;
}
float GetMaxDirLength(float3 Point, float3 RDir)
{
float3 FirstPoint = RDir - Point * RDir;
float3 LastPoint = -Point * RDir;
float3 MaxPoint = max(FirstPoint, LastPoint);
return min(MaxPoint.x, min(MaxPoint.y, MaxPoint.z));
}
// Hashed Alpha Testing
// The implementation was taken from https://cwyman.org/papers/i3d17_hashedAlpha.pdf document by Chris Wyman and Morgan McGuire
float hashed_alpha_test(float3 position)
{
if (m_taa_jitter.z < 0.0f)
{
return def_aref;
}
// Find the discretized derivatives of our coordinates
float maxDeriv = max(length(ddx(position.xyz)), length(ddy(position.xyz)));
float pixScale = rcp(def_aref * maxDeriv); // Let's use def_aref as temporary pixel scale
float pixScaleLog2 = log2(pixScale);
// Find two nearest log-discretized noise scales
float2 pixScales = float2(exp2(floor(pixScaleLog2)), exp2(ceil(pixScaleLog2)));
// Compute alpha thresholds at our two noise scales
float2 alpha = float2(Hash(floor(pixScales.x * position.xyz)), Hash(floor(pixScales.y * position.xyz)));
// Factor to interpolate lerp with
float lerpFactor = frac(log2(pixScale));
// Interpolate alpha threshold from noise at two scales
float x = lerp(alpha.x, alpha.y, lerpFactor);
// Pass into CDF to compute uniformly distrib threshold
float a = min(lerpFactor, 1.0 - lerpFactor);
float3 cases;
cases.x = x * x * rcp(2.0 * a * (1.0 - a));
cases.y = (x - 0.5 * a) * rcp(1.0 - a);
cases.z = 1.0 - ((1.0 - x) * (1.0 - x) * rcp(2.0 * a * (1.0 - a)));
// Find our final, uniformly distributed alpha threshold
float thresh = (x < (1.0 - a)) ? ((x < a) ? cases.x : cases.y) : cases.z;
// R1 sequence to animate our noise for TAA/FSR/DLSS
// Todo: Check if player has enabled TAA/upscaling to enable anim
thresh = frac(thresh + m_taa_jitter.z);
// Clamp alpha
return clamp(thresh, 0.063f, 1.0f);
}
#define IMAGE_BITRATE float3(255.f, 255.f, 255.f)
// Deband color function (by Hozar 2002) - may be huita
float3 deband_color(float3 image, float2 uv)
{
float3 dither = Hash23(cos(uv.xy * timers.x) * 1245.0f);
float3 color = saturate(image) * IMAGE_BITRATE;
float3 pq = frac(color);
color -= pq;
pq = step(dither, pq);
color += pq;
color *= rcp(IMAGE_BITRATE);
return color;
}
//Builds a cotangent frame. Source: http://www.thetenthplanet.de/archives/1180
void build_contangent_frame(float3 position, float3 normal, float2 uv, out float3 tangent, out float3 binormal)
{
float4 duv = float4(ddx(uv), ddy(uv));
float3 dp1perp = cross(normal, ddx(position));
float3 dp2perp = cross(ddy(position), normal);
tangent = dp2perp * duv.x + dp1perp * duv.z;
binormal = dp2perp * duv.y + dp1perp * duv.w;
float invmax = rsqrt(max(dot(tangent, tangent), dot(binormal, binormal)));
tangent *= invmax;
binormal *= invmax;
}
float4 combine_bloom(float3 low, float4 high)
{
return float4(low.xyz + high.xyz * high.w, 1.f);
}
float calc_fogging(float3 pos)
{
return saturate(length(pos - eye_position) * fog_params.w + fog_params.x);
}
float2 unpack_tc_base(float2 tc, float du, float dv)
{
return (tc.xy + float2(du, dv)) * (32.f / 32768.f); //! Increase from 32bit to 64bit floating point
}
float3 unpack_normal(float3 v)
{
return 2 * v - 1;
}
float3 unpack_bx2(float3 v)
{
return 2 * v - 1;
}
float3 unpack_bx4(float3 v)
{
return 4 * v - 2;
} //! reduce the amount of stretching from 4*v-2 and increase precision
float2 unpack_tc_lmap(float2 tc)
{
return tc * (1.f / 32768.f);
} // [-1 .. +1 ]
float4 unpack_color(float4 c)
{
return c.bgra;
}
float4 unpack_D3DCOLOR(float4 c)
{
return c.bgra;
}
float3 unpack_D3DCOLOR(float3 c)
{
return c.bgr;
}
float3 p_hemi(float2 tc)
{
float4 t_lmh = s_hemi.Sample(smp_rtlinear, tc);
return t_lmh.w;
}
float get_hemi(float4 lmh)
{
return lmh.w;
}
float get_sun(float4 lmh)
{
return lmh.y;
}
float3 v_sun(float3 N)
{
return L_sun_color.xyz * dot(N, -L_sun_dir_w.xyz);
}
float3 calc_reflection(float3 pos_w, float3 norm_w)
{
return reflect(normalize(pos_w - eye_position), norm_w);
}
#endif // common_functions_h_included

View file

@ -0,0 +1,514 @@
#ifndef common_iostructs_h_included
#define common_iostructs_h_included
////////////////////////////////////////////////////////////////
// This file contains io structs:
// v_name : input for vertex shader.
// v2p_name: output for vertex shader.
// p_name : input for pixel shader.
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
// TL0uv
struct v_TL0uv_positiont
{
float4 P : POSITIONT;
float4 Color : COLOR;
};
struct v_TL0uv
{
float4 P : POSITION;
float4 Color : COLOR;
};
struct v2p_TL0uv
{
float4 Color : COLOR;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_TL0uv
{
float4 Color : COLOR;
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// TL
struct v_TL_positiont
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
};
struct v_TL
{
float4 P : POSITION;
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
};
struct v2p_TL
{
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_TL
{
float2 Tex0 : TEXCOORD0;
float4 Color : COLOR;
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// TL2uv
struct v_TL2uv
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
};
struct v2p_TL2uv
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_TL2uv
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float4 Color : COLOR;
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// postpr
struct v_postpr
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
};
struct v2p_postpr
{
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_postpr
{
float2 Tex0 : TEXCOORD0; // base1 (duality)
float2 Tex1 : TEXCOORD1; // base2 (duality)
float2 Tex2 : TEXCOORD2; // base (noise)
float4 Color : COLOR0; // multiplier, color.w = noise_amount
float4 Gray : COLOR1; // (.3,.3,.3.,amount)
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// build (bloom_build)
struct v_build
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
};
struct v2p_build
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_build
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// filter (bloom_filter)
struct v_filter
{
float4 P : POSITIONT;
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
};
struct v2p_filter
{
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_filter
{
float4 Tex0 : TEXCOORD0;
float4 Tex1 : TEXCOORD1;
float4 Tex2 : TEXCOORD2;
float4 Tex3 : TEXCOORD3;
float4 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 Tex7 : TEXCOORD7;
// float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// aa_AA
struct v_aa_AA
{
float4 P : POSITIONT;
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
float2 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
};
struct v2p_aa_AA
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
float2 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_aa_AA
{
float2 Tex0 : TEXCOORD0;
float2 Tex1 : TEXCOORD1;
float2 Tex2 : TEXCOORD2;
float2 Tex3 : TEXCOORD3;
float2 Tex4 : TEXCOORD4;
float4 Tex5 : TEXCOORD5;
float4 Tex6 : TEXCOORD6;
// float4 HPos :SV_POSITION; // Clip-space position (for rasterization)
};
struct p_aa_AA_sun
{
float2 tc : TEXCOORD0;
float2 unused : TEXCOORD1;
float2 LT : TEXCOORD2;
float2 RT : TEXCOORD3;
float2 LB : TEXCOORD4;
float2 RB : TEXCOORD5;
// float4 HPos :SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// dumb
struct v_dumb
{
float4 P : POSITION; // Clip-space position (for rasterization)
};
struct v2p_dumb
{
float4 HPos : SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// Volume
struct v2p_volume
{
float4 tc : TEXCOORD0;
float4 hpos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_volume
{
float4 tc : TEXCOORD0;
// float4 hpos :SV_POSITION; // Clip-space position (for rasterization)
};
////////////////////////////////////////////////////////////////
// Static
struct v_static
{
float4 Nh : NORMAL; // (nx,ny,nz,hemi occlusion)
float4 T : TANGENT; // tangent
float4 B : BINORMAL; // binormal
int2 tc : TEXCOORD0; // (u,v)
#ifdef USE_LM_HEMI
int2 lmh : TEXCOORD1; // (lmu,lmv)
#endif
float4 P : POSITION; // (float,float,float,1)
};
struct v_static_color
{
float4 P : POSITION; // (float,float,float,1)
float4 Nh : NORMAL; // (nx,ny,nz,hemi occlusion)
float4 T : TANGENT; // tangent
float4 B : BINORMAL; // binormal
float4 color : COLOR0; // (r,g,b,dir-occlusion) // Swizzle before use!!!
int2 tc : TEXCOORD0; // (u,v)
#ifdef USE_LM_HEMI
int2 lmh : TEXCOORD1; // (lmu,lmv)
#endif
};
struct f_deffer
{
float4 Ne : SV_Target0;
float4 C : SV_Target1;
float2 V : SV_Target2;
};
struct f_forward
{
float4 Color : SV_Target0;
float Reactive : SV_Target1;
float2 Velocity : SV_Target2;
};
struct gbuffer_data
{
float3 P;
float3 P_hud;
float3 P_real;
float depth;
float mtl;
float3 N;
float hemi;
float3 C;
float gloss;
float sss;
};
////////////////////////////////////////////////////////////////
// Defer bumped
struct p_bumped_new
{
float4 hpos : SV_POSITION;
float4 tcdh : TEXCOORD0; // Texture coordinates, sun_occlusion || lm-hemi
float4 position : TEXCOORD1; // position + hemi
float3 M1 : TEXCOORD2; // nmap 2 eye - 1
float3 M2 : TEXCOORD3; // nmap 2 eye - 2
float3 M3 : TEXCOORD4; // nmap 2 eye - 3
float4 hpos_curr : TEXCOORD5;
float4 hpos_old : TEXCOORD6;
float snow_mask : TEXCOORD7;
#ifndef USE_LM_HEMI
#ifdef USE_LENGTH_BUFFER
float3 lmap : TEXCOORD8;
#endif
#endif
};
struct p_bilbord
{
float4 hpos : SV_POSITION;
float4 af : COLOR1;
float3 position : TEXCOORD0;
float2 tc0 : TEXCOORD1;
float2 tc1 : TEXCOORD2;
float4 hpos_curr : TEXCOORD3;
float4 hpos_old : TEXCOORD4;
};
struct v2p_bumped
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position : TEXCOORD1; // position + hemi
float3 M1 : TEXCOORD2; // nmap 2 eye - 1
float3 M2 : TEXCOORD3; // nmap 2 eye - 2
float3 M3 : TEXCOORD4; // nmap 2 eye - 3
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD5; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD6; // lm-hemi
#endif
float4 hpos_curr : POSITION0;
float4 hpos_old : POSITION1;
float4 hpos : SV_POSITION;
};
struct p_bumped
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position : TEXCOORD1; // position + hemi
float3 M1 : TEXCOORD2; // nmap 2 eye - 1
float3 M2 : TEXCOORD3; // nmap 2 eye - 2
float3 M3 : TEXCOORD4; // nmap 2 eye - 3
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD5; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD6; // lm-hemi
#endif
float4 hpos_curr : POSITION0;
float4 hpos_old : POSITION1;
};
// Defer flat
struct v2p_flat
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position : TEXCOORD1; // position + hemi
float3 N : TEXCOORD2; // Eye-space normal (for lighting)
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD3; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD4; // lm-hemi
#endif
float4 hpos_curr : POSITION0;
float4 hpos_old : POSITION1;
float4 hpos : SV_POSITION;
};
struct p_flat
{
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float4 tcdh : TEXCOORD0; // Texture coordinates, w=sun_occlusion
#else
float2 tcdh : TEXCOORD0; // Texture coordinates
#endif
float4 position : TEXCOORD1; // position + hemi
float3 N : TEXCOORD2; // Eye-space normal (for lighting)
#ifdef USE_TDETAIL
float2 tcdbump : TEXCOORD3; // d-bump
#endif
#ifdef USE_LM_HEMI
float2 lmh : TEXCOORD4; // lm-hemi
#endif
float4 hpos_curr : POSITION0;
float4 hpos_old : POSITION1;
};
// Shadow
struct v_shadow_direct_aref
{
float4 P : POSITION; // (float,float,float,1)
int4 tc : TEXCOORD0; // (u,v,frac,???)
};
struct v_shadow_direct
{
float4 P : POSITION; // (float,float,float,1)
};
struct v2p_shadow_direct_aref
{
float2 tc0 : TEXCOORD0; // Diffuse map for aref
float4 hpos : SV_POSITION; // Clip-space position (for rasterization)
};
struct v2p_shadow_direct
{
float4 hpos : SV_POSITION; // Clip-space position (for rasterization)
};
struct p_shadow_direct_aref
{
float2 tc0 : TEXCOORD0; // Diffuse map for aref
};
struct p_shadow
{
float2 tc0 : TEXCOORD0;
float4 hpos : SV_POSITION;
};
struct v2p_screen
{
float2 tc0 : TEXCOORD0;
float4 HPos : POSITIONT; // Clip-space position (for rasterization)
};
// Model
struct v_model
{
float4 P : POSITION; // (float,float,float,1)
float3 N : NORMAL; // (nx,ny,nz)
float3 T : TANGENT; // (nx,ny,nz)
float3 B : BINORMAL; // (nx,ny,nz)
float2 tc : TEXCOORD0; // (u,v)
float4 P_old : TEXCOORD1; // (float,float,float,1)
};
// Tree
struct v_tree
{
float4 P : POSITION; // (float,float,float,1)
float4 Nh : NORMAL; // (nx,ny,nz)
float3 T : TANGENT; // tangent
float3 B : BINORMAL; // binormal
int4 tc : TEXCOORD0; // (u,v,frac,???)
};
// Details
struct v_detail
{
float4 pos : POSITION; // position, frac
float2 tc : TEXCOORD0; // texcoord
};
#endif // common_iostructs_h_included

View file

@ -0,0 +1,12 @@
#ifndef common_policies_h_included
#define common_policies_h_included
#ifndef ISAMPLE
#define ISAMPLE 0
#endif // ISAMPLE
/////////////////////////////////////////////////////////////////////////////
#define GLD_P(_tc, _pos2d, _iSample) _tc, _pos2d
#define CS_P(_P, _N, _tc0, _tcJ, _pos2d, _iSample) _P, _N, _tc0, _tcJ, _pos2d
#endif // common_policies_h_included

View file

@ -0,0 +1,67 @@
#ifndef common_samplers_h_included
#define common_samplers_h_included
// Geometry phase / deferring //
sampler smp_nofilter; // Use D3DTADDRESS_CLAMP, D3DTEXF_POINT, D3DTEXF_NONE, D3DTEXF_POINT
sampler smp_rtlinear; // Use D3DTADDRESS_CLAMP, D3DTEXF_LINEAR, D3DTEXF_NONE, D3DTEXF_LINEAR
sampler smp_linear; // Use D3DTADDRESS_WRAP, D3DTEXF_LINEAR, D3DTEXF_LINEAR, D3DTEXF_LINEAR
sampler smp_base; // Use D3DTADDRESS_WRAP, D3DTEXF_ANISOTROPIC, D3DTEXF_LINEAR, D3DTEXF_ANISOTROPIC
Texture2D s_base; // smp_base
Texture2D s_generic;
Texture2D s_bump; //
Texture2D s_bumpX; //
Texture2D s_detail; //
Texture2D s_detailBump; //
Texture2D s_detailBumpX; // Error for bump detail
// Texture2D s_bumpD; //
Texture2D s_hemi; //
Texture2D s_mask; //
Texture2D s_dt_r; //
Texture2D s_dt_g; //
Texture2D s_dt_b; //
Texture2D s_dt_a; //
Texture2D s_dn_r; //
Texture2D s_dn_g; //
Texture2D s_dn_b; //
Texture2D s_dn_a; //
Texture2D s_dn_rX;
Texture2D s_dn_gX;
Texture2D s_dn_bX;
Texture2D s_dn_aX;
Texture2D s_refl;
TextureCube s_env;
TextureCube env_s0;
TextureCube env_s1;
TextureCube sky_s0;
TextureCube sky_s1;
// Lighting/shadowing phase //
sampler smp_material;
// uniform sampler2D s_depth; //
Texture2D s_position; // smp_nofilter or Load
Texture2D s_surface; // smp_nofilter or Load
Texture2D s_normal; // smp_nofilter or Load
Texture2D s_lmap; // 2D/???cube projector lightmap
Texture3D s_material; // smp_material
// uniform sampler1D s_attenuate; //
// Combine phase //
Texture2D s_diffuse; // rgb.a = diffuse.gloss
Texture2D s_accumulator; // rgb.a = diffuse.specular
// uniform sampler2D s_generic; //
Texture2D s_bloom; //
Texture2D s_image; // used in various post-processing
Texture2D s_velocity; // used in various post-processing
Texture2D s_tonemap; // actually MidleGray / exp(Lw + eps)
#endif // #ifndef common_samplers_h_included

View file

@ -0,0 +1,66 @@
// This is really short version of CAS based on AMD presentation (https://gpuopen.com/wp-content/uploads/2019/07/FidelityFX-CAS.pptx)
#include "common.hlsli"
float sharpening_intensity;
float4 main(v2p_TL Input) : SV_Target
{
float2 texcoord = Input.Tex0;
// fetch a 3x3 neighborhood around the pixel 'e',
// a b c
// d(e)f
// g h i
float3 a = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(-1, -1)).xyz; a *= rcp(1.0f + a);
float3 b = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(0, -1)).xyz; b *= rcp(1.0f + b);
float3 c = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(1, -1)).xyz; c *= rcp(1.0f + c);
float3 d = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(-1, 0)).xyz; d *= rcp(1.0f + d);
float3 g = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(-1, 1)).xyz; g *= rcp(1.0f + g);
float3 e = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0).xyz; e *= rcp(1.0f + e);
float3 f = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(1, 0)).xyz; f *= rcp(1.0f + f);
float3 h = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(0, 1)).xyz; h *= rcp(1.0f + h);
float3 i = s_image.SampleLevel(smp_rtlinear, texcoord, 0.0, int2(1, 1)).xyz; i *= rcp(1.0f + i);
// Soft min and max.
// a b c b
// d e f * 0.5 + d e f * 0.5
// g h i h
// These are 2.0x bigger (factored out the extra multiply).
float3 mnRGB = min(min(min(d, e), min(f, b)), h);
float3 mnRGB2 = min(mnRGB, min(min(a, c), min(g, i)));
mnRGB += mnRGB2;
float3 mxRGB = max(max(max(d, e), max(f, b)), h);
float3 mxRGB2 = max(mxRGB, max(max(a, c), max(g, i)));
mxRGB += mxRGB2;
// Smooth minimum distance to signal limit divided by smooth max.
float3 rcpMRGB = rcp(mxRGB);
float3 ampRGB = saturate(min(mnRGB, 2.0 - mxRGB) * rcpMRGB);
// Shaping amount of sharpening.
ampRGB = rsqrt(ampRGB);
float Contrast = 1.0f; //sharpening_intensity; //1.0f;
float Sharpening = sharpening_intensity; //sharpening_intensity;
float peak = -3.0 * Contrast + 8.0;
float3 wRGB = -rcp(ampRGB * peak);
float3 rcpWeightRGB = rcp(4.0 * wRGB + 1.0);
// 0 w 0
// Filter shape: w 1 w
// 0 w 0
float3 window = (b + d) + (f + h);
float3 outColor = saturate((window * wRGB + e) * rcpWeightRGB);
outColor = lerp(e, outColor, Sharpening);
return float4(outColor * rcp(max(0.00001f, 1.0 - outColor)), 1.0f);
}

View file

@ -0,0 +1,12 @@
#include "common.hlsli"
#ifndef ISAMPLE
#define ISAMPLE 0
#endif
// Pixel
// TODO: DX10: move to load instead of sample (will need to provide integer texture coordinates)
float4 main(float2 tc : TEXCOORD0) : SV_Target
{
return s_generic.Sample(smp_nofilter, tc);
}

View file

@ -0,0 +1,6 @@
#include "common.hlsli"
float4 main(float2 tc : TEXCOORD0) : SV_Target
{
return s_image.Sample(FILTER_TYPE, tc);
}

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
float4 main(float4 tc : TEXCOORD0) : SV_Target
{
return s_generic.Sample(smp_nofilter, tc.xy / tc.w);
}

View file

@ -0,0 +1,14 @@
-- without depth test
function l_special(shader, t_base, t_second, t_detail)
shader:begin("debug_draw", "debug_draw")
:zb(false, false)
shader:dx10texture("s_position", "$user$position")
shader:dx10sampler("smp_nofilter")
end
-- depth test
function normal(shader, t_base, t_second, t_detail)
shader:begin("debug_draw", "debug_draw_nodepth")
:zb(true, false)
end

View file

@ -0,0 +1,20 @@
#include "common.hlsli"
uniform float4 screen_res;
// vertex output
struct v2p_L
{
float4 pos : SV_POSITION;
float4 viewpos : TEXCOORD0;
float4 color : COLOR0;
};
float4 main(v2p_L I) : SV_TARGET
{
float depth = s_position.SampleLevel(smp_nofilter, I.pos.xy * screen_res.zw, 0).x;
depth = depth_unpack.x / (depth - depth_unpack.y);
clip(depth - I.viewpos.z);
return I.color;
}

View file

@ -0,0 +1,26 @@
#include "common.hlsli"
// input
struct v_vert
{
float4 pos : POSITION; // (float,float,float,1)
float4 color : COLOR0; // (r,g,b,dir-occlusion)
};
// output
struct v2p_L
{
float4 pos : SV_POSITION;
float4 viewpos : TEXCOORD0;
float4 color : COLOR0;
};
// Vertex
v2p_L main(v_vert I)
{
v2p_L O;
O.pos = mul(m_WVP, I.pos);
O.viewpos = float4(mul(m_WV, I.pos), 1.0f);
O.color = I.color.bgra; // swizzle vertex colour
return O;
}

View file

@ -0,0 +1,14 @@
#include "common.hlsli"
// vertex output
struct v2p_L
{
float4 pos : SV_POSITION;
float4 viewpos : TEXCOORD0;
float4 color : COLOR0;
};
float4 main(v2p_L I) : SV_TARGET
{
return I.color;
}

View file

@ -0,0 +1,72 @@
#include "common.hlsli"
#include "sload.hlsli"
void main(p_bumped_new I, out IXrayGbufferPack O)
{
IXrayMaterial M;
M.Depth = I.position.z;
#ifdef USE_CLIP_NEAR_PLANE
clip(I.hpos_curr.z - I.hpos_curr.w * 0.02f);
#endif
M.Sun = I.tcdh.w;
M.Hemi = I.tcdh.z;
M.Point = I.position.xyz;
SloadNew(I, M);
#ifdef USE_AREF
#if defined(USE_HASHED_AREF) && !defined(DETAIL_SHADOW_PASS)
clip(M.Color.w - hashed_alpha_test(M.Point));
#else
clip(M.Color.w - def_aref);
#endif
#ifdef USE_DXT1_HACK
M.Color.xyz *= rcp(max(0.0001f, M.Color.w));
#endif
#endif
#if defined(USE_BUMP) || defined(USE_TDETAIL_BUMP)
M.Normal = mul(float3x3(I.M1, I.M2, I.M3), M.Normal);
#else
M.Normal = float3(I.M1.z, I.M2.z, I.M3.z);
#endif
M.Normal = normalize(M.Normal);
#ifdef USE_LM_HEMI
float4 lm = s_hemi.Sample(smp_rtlinear, I.tcdh.zw);
M.Sun = get_sun(lm);
M.Hemi = get_hemi(lm);
#endif
#ifdef USE_LEGACY_LIGHT
#ifndef USE_PBR
M.Metalness = L_material.w;
#else
M.Color.xyz *= M.AO;
M.AO = 1.0f;
float Specular = M.Metalness * dot(M.Color.xyz, LUMINANCE_VECTOR);
M.Color.xyz = lerp(M.Color.xyz, 0.04f, M.Metalness);
M.Metalness = 0.5f - M.Roughness * M.Roughness * 0.5f;
M.Roughness = Specular;
#endif
#endif
#ifdef IGNORE_SNOW_MASK
M.SnowMask = 0.0f;
#endif
#ifdef USE_AREF
#ifdef USE_TREEWAVE
M.SSS = 1.0f;
#endif
M.SnowMask = 0.0f;
#endif
O.Velocity = I.hpos_curr.xy / I.hpos_curr.w - I.hpos_old.xy / I.hpos_old.w;
GbufferPack(O, M);
}

View file

@ -0,0 +1,58 @@
#include "common.hlsli"
#ifdef USE_LM_HEMI
#define v_in v_static
#else
#define v_in v_static_color
#endif
void main(in v_in I, out p_bumped_new O)
{
float2 tc = unpack_tc_base(I.tc, I.T.w, I.B.w);
float3 Pe = mul(m_WV, I.P);
O.tcdh = float4(tc.xy, I.Nh.w, I.Nh.w);
O.position = float4(Pe, 1.0f);
float3 N = unpack_bx4(unpack_D3DCOLOR(I.Nh).xyz);
#if defined(USE_BUMP) || defined(USE_TDETAIL_BUMP)
float3 T = unpack_bx4(unpack_D3DCOLOR(I.T).xyz);
float3 B = unpack_bx4(unpack_D3DCOLOR(I.B).xyz);
float3x3 xform = mul((float3x3)m_WV, float3x3(
T.x, B.x, N.x,
T.y, B.y, N.y,
T.z, B.z, N.z)
);
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#else
N = mul((float3x3)m_WV, N);
O.M1 = N.xxx;
O.M2 = N.yyy;
O.M3 = N.zzz;
#endif
O.snow_mask = normalize(mul((float3x3)m_W, N)).y;
#ifdef USE_LM_HEMI
O.tcdh.zw = unpack_tc_lmap(I.lmh);
#else
#ifdef USE_LENGTH_BUFFER
O.lmap = unpack_D3DCOLOR(I.color.xyz);
#endif
O.tcdh.w = I.color.w;
#endif
O.hpos = mul(m_WVP, I.P);
O.hpos_curr = O.hpos;
O.hpos_old = mul(m_WVP_old, I.P);
O.hpos.xy += m_taa_jitter.xy * O.hpos.w;
}

View file

@ -0,0 +1,106 @@
#include "common.hlsli"
cbuffer DetailConstants
{
float4 consts;
float4 wave;
float4 wave_old;
float4 dir2D;
float4 dir2D_old;
};
//LVutner: Has to match the CPU struct
struct InstanceData
{
float3 hpb;
float scale;
float3 pos;
float hemi;
};
//LVutner: Always bound to slot0 (see CPP code)
StructuredBuffer<InstanceData> detail_buffer : register(t0);
float3x3 setMatrix (float3 hpb)
{
float _ch, _cp, _cb, _sh, _sp, _sb, _cc, _cs, _sc, _ss;
sincos(hpb.x, _sh, _ch);
sincos(hpb.y, _sp, _cp);
sincos(hpb.z, _sb, _cb);
_cc = _ch*_cb; _cs = _ch*_sb; _sc = _sh*_cb; _ss = _sh*_sb;
return float3x3(_cc-_sp*_ss, _sp*_sc+_cs, -_cp*_sh,
-_cp*_sb, _cp*_cb, _sp,
_sp*_cs+_sc, _ss-_sp*_cc, _cp*_ch);
};
void main(in v_detail I, out p_bumped_new O, uint instance_id : SV_InstanceID)
{
//LVutner: Read our structured buffer
InstanceData det = detail_buffer[instance_id];
float3x3 mmhpb = setMatrix(det.hpb);
float hemi = abs(det.hemi);
float sun = sign(det.hemi)*0.25f+0.25f;
float4 m0 = float4(mmhpb[0]*det.scale, det.pos.x);
float4 m1 = float4(mmhpb[1]*det.scale, det.pos.y);
float4 m2 = float4(mmhpb[2]*det.scale, det.pos.z);
float4 pos, pos_old;
pos.x = dot(m0, float4(I.pos.xyz, 1.0));
pos.y = dot(m1, float4(I.pos.xyz, 1.0));
pos.z = dot(m2, float4(I.pos.xyz, 1.0));
pos.w = 1.0f;
pos_old = pos;
#ifdef USE_TREEWAVE
float H = I.pos.y * length(m1.xyz);
float dp = calc_cyclic(dot(pos, wave));
float inten = H * dp;
pos.xz += calc_xz_wave(dir2D.xz * inten, I.pos.w);
#ifndef DETAIL_SHADOW_PASS
float dp_old = calc_cyclic(dot(pos_old, wave_old));
float inten_old = H * dp_old;
pos_old.xz += calc_xz_wave(dir2D_old.xz * inten_old, I.pos.w);
#endif
#endif
float3 Pe = mul(m_WV, pos);
float3 N;
N.x = pos.x - m0.w;
N.y = pos.y - m1.w + 0.75f;
N.z = pos.z - m2.w;
O.tcdh = float4(I.tc.xy, hemi, sun);
O.position = float4(Pe, 1.0f);
N.xyz = mul((float3x3)m_WV, N.xyz);
O.M1 = N.xxx;
O.M2 = N.yyy;
O.M3 = N.zzz;
O.hpos = mul(m_WVP, pos);
#ifndef DETAIL_SHADOW_PASS
O.hpos_curr = O.hpos;
O.hpos_old = mul(m_VP_old, pos_old);
O.hpos.xy += m_taa_jitter.xy * O.hpos.w;
#else
O.hpos_curr = O.hpos_old = O.hpos;
#endif
O.snow_mask = 0.0;
}

View file

@ -0,0 +1,162 @@
#include "common.hlsli"
#include "sload.hlsli"
#ifndef USE_LENGTH_BUFFER
#define OutStructure IXrayGbufferPack
#else
#define OutStructure f_forward
#include "metalic_roughness_light.hlsli"
#include "metalic_roughness_ambient.hlsli"
#endif
void main(p_bumped_new I, out OutStructure O)
{
IXrayMaterial M;
M.Depth = I.position.z;
M.Sun = I.tcdh.w;
M.Hemi = I.tcdh.z;
M.Point = I.position.xyz;
M.Color = s_base.Sample(smp_base, I.tcdh.xy);
M.Metalness = 0.0f;
M.SSS = 0.0f;
M.AO = 1.0f;
float4 Lmap = s_lmap.Sample(smp_base, I.tcdh.xy);
float2 tcdbump = I.tcdh.xy * dt_params.xy;
#ifdef USE_PBR
#ifdef USE_4_BUMP
float4 Mask = s_mask.Sample(smp_base, I.tcdh.xy);
Mask /= dot(Mask, 1.0f);
float3 r_base = s_dt_r.Sample(smp_base, tcdbump).xyz * Mask.x;
float3 g_base = s_dt_g.Sample(smp_base, tcdbump).xyz * Mask.y;
float3 b_base = s_dt_b.Sample(smp_base, tcdbump).xyz * Mask.z;
float3 a_base = s_dt_a.Sample(smp_base, tcdbump).xyz * Mask.w;
float4 r_bump = s_dn_r.Sample(smp_base, tcdbump) * Mask.x;
float4 g_bump = s_dn_g.Sample(smp_base, tcdbump) * Mask.y;
float4 b_bump = s_dn_b.Sample(smp_base, tcdbump) * Mask.z;
float4 a_bump = s_dn_a.Sample(smp_base, tcdbump) * Mask.w;
float4 r_bumpX = s_dn_rX.Sample(smp_base, tcdbump) * Mask.x;
float4 g_bumpX = s_dn_gX.Sample(smp_base, tcdbump) * Mask.y;
float4 b_bumpX = s_dn_bX.Sample(smp_base, tcdbump) * Mask.z;
float4 a_bumpX = s_dn_aX.Sample(smp_base, tcdbump) * Mask.w;
//Unpack normals (if something is wrong - unpack and then blend them)
M.Normal.xy = (r_bump.wy + g_bump.wy + b_bump.wy + a_bump.wy) * 2.0 - 1.0;
M.Normal.z = sqrt(1.0f - saturate(dot(M.Normal.xy, M.Normal.xy)));
#ifndef USE_DX_NORMAL_MAP
M.Normal.y *= -1.0f;
#endif
M.Color.xyz *= (r_base + g_base + b_base + a_base) * 2.0f; //LVutner: Change later
M.Metalness = r_bumpX.x + g_bumpX.x + b_bumpX.x + a_bumpX.x;
M.Roughness = r_bumpX.y + g_bumpX.y + b_bumpX.y + a_bumpX.y;
M.SSS = r_bumpX.z + g_bumpX.z + b_bumpX.z + a_bumpX.z;
M.AO = r_bumpX.w + g_bumpX.w + b_bumpX.w + a_bumpX.w;
#else
float4 Detail = s_detail.Sample(smp_base, tcdbump);
float4 DetailBump = s_detailBump.Sample(smp_base, tcdbump);
float4 DetailBumpX = s_detailBumpX.Sample(smp_base, tcdbump);
M.Roughness = DetailBumpX.y;
M.Metalness = DetailBumpX.x;
M.Normal.xy = DetailBump.wy * 2.0 - 1.0;
M.Normal.z = sqrt(1.0f - saturate(dot(M.Normal.xy, M.Normal.xy)));
M.Color.xyz *= Detail * 2.0f;
#endif
#else
#ifdef USE_4_BUMP
float4 Mask = s_mask.Sample(smp_base, I.tcdh.xy);
Mask /= dot(Mask, 1.0f);
float3 Detail_R = s_dt_r.Sample(smp_base, tcdbump).xyz * Mask.x;
float3 Detail_G = s_dt_g.Sample(smp_base, tcdbump).xyz * Mask.y;
float3 Detail_B = s_dt_b.Sample(smp_base, tcdbump).xyz * Mask.z;
float3 Detail_A = s_dt_a.Sample(smp_base, tcdbump).xyz * Mask.w;
float3 Detail = Detail_R + Detail_G + Detail_B + Detail_A;
float4 Normal_R = s_dn_r.Sample(smp_base, tcdbump) * Mask.x;
float4 Normal_G = s_dn_g.Sample(smp_base, tcdbump) * Mask.y;
float4 Normal_B = s_dn_b.Sample(smp_base, tcdbump) * Mask.z;
float4 Normal_A = s_dn_a.Sample(smp_base, tcdbump) * Mask.w;
M.Normal = Normal_R.wzy + Normal_G.wzy + Normal_B.wzy + Normal_A.wzy - 0.5;
M.Roughness = min(1.0f, Normal_R.x + Normal_G.x + Normal_B.x + Normal_A.x);
#else
float4 Detail = s_detail.Sample(smp_base, tcdbump);
float4 DetailBump = s_detailBump.Sample(smp_base, tcdbump);
M.Roughness = DetailBump.x;
M.Normal.xyz = DetailBump.wzy - 0.5f;
#endif
M.Normal.z *= 0.5f;
M.Color.xyz *= Detail * 2.0f;
#endif
M.Normal = mul(float3x3(I.M1, I.M2, I.M3), M.Normal);
M.Normal = normalize(M.Normal);
M.Sun = Lmap.w;
M.Hemi = M.Color.w;
#ifdef USE_LEGACY_LIGHT
M.Metalness = L_material.w;
#else
#ifndef USE_PBR
M.Roughness = 1.0f - M.Roughness * 0.9f;
#endif
#endif
#ifdef IGNORE_SNOW_MASK_ON_TERRAIN
M.SnowMask = 0.0f;
#else
M.SnowMask = 1.0f;
#endif
O.Velocity = I.hpos_curr.xy / I.hpos_curr.w - I.hpos_old.xy / I.hpos_old.w;
#ifndef USE_LENGTH_BUFFER
GbufferPack(O, M);
#else
float4 LightColor = float4(L_sun_color.xyz, 0.5f);
M.Sun = saturate(M.Sun * 2.0f);
M.Color.xyz = PushGamma(saturate(M.Color.xyz));
float ViewLength = length(M.Point);
float3 View = M.Point.xyz * rcp(ViewLength);
#ifndef USE_PBR
float3 F0 = 0.0f;
#else
float3 F0 = 0.04f;
#endif
float3 Light = M.Sun * DirectLight(LightColor, mul((float3x3)m_V, L_sun_dir_w.xyz), M.Normal, View, M.Color.xyz, M.Metalness, M.Roughness, F0);
float3 Ambient = PushGamma(M.AO) * AmbientLighting(View, M.Normal, M.Color.xyz, M.Metalness, M.Roughness, M.Hemi, F0);
Light += DirectLight(float4(Lmap.xyz, 0.5f), View, M.Normal, View, M.Color.xyz, M.Metalness, M.Roughness, F0);
O.Color.xyz = Ambient + Light;
O.Color.w = 1.0f;
float Fog = PushGamma(saturate(ViewLength * fog_params.w + fog_params.x));
O.Color = lerp(O.Color, PushGamma(fog_color), Fog);
O.Velocity = I.hpos_curr.xy / I.hpos_curr.w - I.hpos_old.xy / I.hpos_old.w;
O.Reactive = O.Color.w * 0.9f;
O.Color.w = ViewLength;
O.Color.xyz *= rcp(1.0f + O.Color.xyz);
#endif
}

View file

@ -0,0 +1,88 @@
#include "common.hlsli"
cbuffer LodConstants
{
float3x4 m_xform;
float3x4 m_xform_v;
float4 consts;
float4 wind;
float4 wave;
float4 consts_old;
float4 wave_old;
float4 wind_old;
float4 c_scale;
float4 c_bias;
float2 c_sun;
}
void main(in v_tree I, out p_bumped_new O)
{
float4 pos = float4(mul(m_xform, I.P).xyz, 1.0);
float4 pos_old = pos;
float2 tc = I.tc.xy * consts.xy;
float sun = I.Nh.w * c_sun.x + c_sun.y;
float hemi = I.Nh.w * c_scale.w + c_bias.w;
#ifdef USE_LENGTH_BUFFER
O.lmap = I.Nh.w * c_scale.xyz + c_bias.xyz;
#endif
#ifdef USE_TREEWAVE
float base = m_xform._24;
float H = pos.y - base;
float dp = calc_cyclic(wave.w + dot(pos.xyz, wave.xyz));
float frac = I.tc.z * consts.x;
float inten = H * dp;
pos.xz += calc_xz_wave(wind.xz * inten, frac);
float dp_old = calc_cyclic(wave_old.w + dot(pos_old.xyz, wave_old.xyz));
float frac_old = I.tc.z * consts_old.x;
float inten_old = H * dp_old;
pos_old.xz += calc_xz_wave(wind_old.xz * inten_old, frac_old);
#endif
float3 Pe = mul(m_V, pos);
O.tcdh = float4(tc.xy, hemi, sun);
O.position = float4(Pe, 1.0f);
float3 N = unpack_bx4(unpack_D3DCOLOR(I.Nh).xyz);
#if defined(USE_BUMP) || defined(USE_TDETAIL_BUMP)
float3 T = unpack_bx4(unpack_D3DCOLOR(I.T).xyz);
float3 B = unpack_bx4(unpack_D3DCOLOR(I.B).xyz);
float3x3 xform = mul((float3x3)m_xform_v, float3x3(
T.x, B.x, N.x,
T.y, B.y, N.y,
T.z, B.z, N.z));
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#else
N = mul((float3x3)m_xform_v, N);
O.M1 = N.xxx;
O.M2 = N.yyy;
O.M3 = N.zzz;
#endif
O.hpos = mul(m_VP, pos);
O.hpos_curr = O.hpos;
O.hpos_old = mul(m_VP_old, pos_old);
O.hpos.xy += m_taa_jitter.xy * O.hpos.w;
O.snow_mask = normalize(mul(m_xform, N)).y;
}

View file

@ -0,0 +1,81 @@
#include "common.hlsli"
#include "skin.hlsli"
void skinned_main(in v_model I, out p_bumped_new O)
{
float3 Nw = mul((float3x3)m_W, (float3)I.N);
float3 hc_pos = (float3)hemi_cube_pos_faces;
float3 hc_neg = (float3)hemi_cube_neg_faces;
float3 hc_mixed = (Nw < 0.0f) ? -hc_neg : hc_pos;
float hemi_val = saturate(dot(hc_mixed, Nw));
float3 Pe = mul(m_WV, I.P);
O.tcdh = float4(I.tc.xy, hemi_val, L_material.y);
O.position = float4(Pe, 1.0f);
float3 N = I.N * 2.0f;
#if defined(USE_BUMP) || defined(USE_TDETAIL_BUMP)
float3 T = I.T * 2.0f;
float3 B = I.B * 2.0f;
float3x3 xform = mul((float3x3)m_WV, float3x3(
T.x, B.x, N.x,
T.y, B.y, N.y,
T.z, B.z, N.z));
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#else
N = mul((float3x3)m_WV, N);
O.M1 = N.xxx;
O.M2 = N.yyy;
O.M3 = N.zzz;
#endif
O.hpos = mul(m_WVP, I.P);
O.hpos_curr = O.hpos;
O.hpos_old = mul(m_WVP_old, I.P_old);
O.hpos.xy += m_taa_jitter.xy * O.hpos.w;
// Для НПС раскомментировать (не рекомендую)
// O.snow_mask = normalize(mul((float3x3)m_W, N)).y;
O.snow_mask = 0.0f;
}
#if defined(SKIN_0)
void main(in v_model_skinned_0 I, out p_bumped_new O)
{
skinned_main(skinning_0(I), O);
}
#elif defined(SKIN_1)
void main(in v_model_skinned_1 I, out p_bumped_new O)
{
skinned_main(skinning_1(I), O);
}
#elif defined(SKIN_2)
void main(in v_model_skinned_2 I, out p_bumped_new O)
{
skinned_main(skinning_2(I), O);
}
#elif defined(SKIN_3)
void main(in v_model_skinned_3 I, out p_bumped_new O)
{
skinned_main(skinning_3(I), O);
}
#elif defined(SKIN_4)
void main(in v_model_skinned_4 I, out p_bumped_new O)
{
skinned_main(skinning_4(I), O);
}
#else
void main(in v_model I, out p_bumped_new O)
{
skinned_main(I, O);
}
#endif

View file

@ -0,0 +1,15 @@
#include "common.hlsli"
#include "sload.hlsli"
struct p_particle
{
float4 color : COLOR0;
};
float4 main(p_particle II) : SV_Target0
{
discard;
return II.color;
}
// THIS SHADER SHOD BE DELEATED OR FIXED

View file

@ -0,0 +1,24 @@
#include "common.hlsli"
struct vv
{
float4 P : POSITION;
float2 tc : TEXCOORD0;
float4 c : COLOR0;
};
struct v2p_particle
{
float4 color : COLOR0;
float4 hpos : SV_POSITION;
};
void main(in vv I, out v2p_particle pp)
{
pp.color = I.c;
pp.hpos = mul(m_WVP, I.P);
pp.hpos.xy += m_taa_jitter.xy * pp.hpos.w;
}
// THIS SHADER SHOD BE DELEATED OR FIXED

View file

@ -0,0 +1,28 @@
#include "common.hlsli"
struct _input
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
float2 tcJ : TEXCOORD1; // jitter coords
float4 pos2d : SV_POSITION;
};
uniform float4 scaled_screen_res;
float4 main(_input I) : SV_Target0
{
float4 Depth;
#ifndef SM_5
Depth.x = s_position.SampleLevel(smp_nofilter, I.tc0.xy, int2(1, 0), 0).x;
Depth.y = s_position.SampleLevel(smp_nofilter, I.tc0.xy, int2(1, 1), 0).x;
Depth.z = s_position.SampleLevel(smp_nofilter, I.tc0.xy, int2(0, 1), 0).x;
Depth.w = s_position.SampleLevel(smp_nofilter, I.tc0.xy, int2(0, 0), 0).x;
#else // !SM_5
Depth = s_position.GatherRed(smp_nofilter, I.tc0.xy + 0.5f * scaled_screen_res.zw);
#endif // SM_5
Depth = depth_unpack.x * rcp(Depth - depth_unpack.y);
return min(min(Depth.x, Depth.y), min(Depth.z, Depth.w));
}

View file

@ -0,0 +1,21 @@
function pass_setup_common(shader, t_base, t_second, t_detail)
shader:blend(false, blend.one, blend.zero)
:zb(true, true)
:fog(false)
:dx10stencil(true, cmp_func.always,
255, 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
:dx10stencil_ref(1)
shader:dx10texture("s_base", t_base)
shader:dx10texture("s_hemi", t_base .. "_nm")
shader:dx10sampler("smp_base");
shader:dx10sampler("smp_linear");
end
function l_special(shader, t_base, t_second, t_detail)
shader:begin("lod", "lod")
details_lod.pass_setup_common(shader, t_base, t_second, t_detail)
end

View file

@ -0,0 +1,10 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_notransform_t", "distort")
:fog(false)
:zb(false, false)
shader:dx10texture("s_base", "$user$generic")
shader:dx10texture("s_distort", "$user$generic1")
shader:dx10sampler("smp_rtlinear");
end

View file

@ -0,0 +1,19 @@
#include "common.hlsli"
struct v2p
{
float2 tc : TEXCOORD0; // base & distort
};
Texture2D s_distort;
// Pixel
float4 main(v2p I) : SV_Target
{
float2 distort = s_distort.Sample(smp_rtlinear, I.tc).xy;
float2 offset = (distort - 127.0f / 255.0f) * def_distort;
float3 image = s_base.Sample(smp_rtlinear, I.tc + offset).xyz;
return float4(image, 1);
}

View file

@ -0,0 +1,80 @@
#ifndef DOF_H_INCLUDED
#define DOF_H_INCLUDED
uniform float4 screen_res;
#ifndef USE_DOF
float3 dof(float2 center)
{
float3 img = s_image.Sample(smp_rtlinear, center).xyz;
return img;
}
#else // USE_DOF
// x - near y - focus z - far w - sky distance
float4 dof_params;
float3 dof_kernel; // x,y - resolution pre-scaled z - just kernel size
float DOFFactor(float depth)
{
float dist_to_focus = depth - dof_params.y;
float blur_far = saturate(dist_to_focus * rcp(dof_params.z - dof_params.y));
float blur_near = saturate(dist_to_focus * rcp(dof_params.x - dof_params.y));
float blur = blur_near + blur_far;
blur *= blur;
return blur;
}
float sampleDepth(float2 center)
{
float P = s_position.SampleLevel(smp_nofilter, center, 0).x;
return P > 0.9999f ? dof_params.w : (depth_unpack.x * rcp(P - depth_unpack.y));
}
#define MAXCOF 7.h
#define EPSDEPTH 0.0001h
float3 dof(float2 center)
{
// Scale tap offsets based on render target size
float depth = sampleDepth(center);
float blur = DOFFactor(depth);
float2 scale = 0.5f * screen_res.zw * dof_kernel.z * blur;
// poisson
float2 o[12];
o[0] = float2(-0.326212f, -0.405810f) * scale;
o[1] = float2(-0.840144f, -0.073580f) * scale;
o[2] = float2(-0.695914f, 0.457137f) * scale;
o[3] = float2(-0.203345f, 0.620716f) * scale;
o[4] = float2(0.962340f, -0.194983f) * scale;
o[5] = float2(0.473434f, -0.480026f) * scale;
o[6] = float2(0.519456f, 0.767022f) * scale;
o[7] = float2(0.185461f, -0.893124f) * scale;
o[8] = float2(0.507431f, 0.064425f) * scale;
o[9] = float2(0.896420f, 0.412458f) * scale;
o[10] = float2(-0.321940f, -0.932615f) * scale;
o[11] = float2(-0.791559f, -0.597710f) * scale;
float3 sum = s_image.Sample(smp_nofilter, center).xyz;
float contrib = 1.h;
[unroll]
for (int i = 0; i < 12; i++)
{
float2 tap = center + o[i];
float3 tap_color = s_image.Sample(smp_nofilter, tap).xyz;
float tap_depth = sampleDepth(tap);
float tap_contrib = DOFFactor(tap_depth);
sum += tap_color * tap_contrib;
contrib += tap_contrib;
}
return float3(sum / contrib);
}
#endif // USE_DOF
#endif // DOF_H_INCLUDED

View file

@ -0,0 +1,7 @@
#include "common.hlsli"
// Pixel
float4 main() : SV_Target
{
return 0;
}

View file

@ -0,0 +1,11 @@
#include "common.hlsli"
// Vertex
v2p_dumb main(v_dumb I)
{
v2p_dumb O;
O.HPos = mul(m_WVP, I.P);
return O;
}

View file

@ -0,0 +1,24 @@
#include "common.hlsli"
struct vf
{
float4 C : COLOR0;
float4 P : POSITION;
};
struct v2p
{
float4 C : COLOR0;
float4 P : SV_POSITION;
};
uniform float4 tfactor;
v2p main(vf i)
{
v2p o;
o.P = mul(m_WVP, i.P); // xform, input in world coords
o.C = tfactor * i.C;
return o;
}

View file

@ -0,0 +1,7 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_default", "stub_srgb")
:zb(true, false)
:blend(true, blend.one, blend.one)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,7 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("effects_sun", "stub_default")
:blend(true, blend.srcalpha, blend.one)
:zb(false, false)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,10 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_default", "stub_srgb")
:zb(true, false)
:blend(true, blend.srcalpha, blend.one)
:aref(true, 2)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,12 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("base_lplanes", "base_lplanes")
:fog(false)
:zb(true, false)
:blend(true, blend.srcalpha, blend.one)
:aref(true, 0)
:sorting(2, false)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,10 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_default", "stub_srgb")
:zb(true, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:aref(true, 0)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,9 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("effects_sun", "stub_srgb")
:blend(true, blend.srcalpha, blend.one)
:zb(true, false)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,15 @@
#include "common.hlsli"
// Vertex
v2p_TL main(v_TL I)
{
v2p_TL O;
// O.HPos = I.P;
O.HPos = mul(m_VP, I.P); // xform, input in world coords
O.HPos.z = O.HPos.w;
O.Tex0 = I.Tex0;
O.Color = I.Color.bgra; // swizzle vertex colour
return O;
}

View file

@ -0,0 +1,8 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("effects_wallmark", "stub_default_ma")
:blend(true, blend.destcolor, blend.srccolor)
:zb(true, false)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_rtlinear")
shader:dx10color_write_enable(true, true, true, false)
end

View file

@ -0,0 +1,15 @@
#include "common.hlsli"
// Vertex
v2p_TL main(v_TL I)
{
v2p_TL O;
O.HPos = mul(m_VP, I.P);
O.Tex0 = I.Tex0;
O.Color = I.Color.bgra; // swizzle vertex colour
O.HPos.xy += m_taa_jitter.xy * O.HPos.w;
return O;
}

View file

@ -0,0 +1,13 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("wmark", "simple")
:sorting(1, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:aref(true, 0)
:zb(true, false)
:fog(false)
:wmark(true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_rtlinear")
shader:dx10color_write_enable(true, true, true, false)
end

View file

@ -0,0 +1,13 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("wmark", "simple")
:sorting(1, false)
:blend(true, blend.destcolor, blend.srccolor)
:aref(true, 0)
:zb(true, false)
:fog(false)
:wmark(true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_rtlinear")
shader:dx10color_write_enable(true, true, true, false)
end

View file

@ -0,0 +1,12 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("wmark", "simple")
:sorting(1, false)
:aref(false, 0)
:zb(true, true)
:fog(false)
:wmark(true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture("s_base", t_base)
shader:dx10sampler("smp_rtlinear")
shader:dx10color_write_enable(true, true, true, false)
end

View file

@ -0,0 +1,62 @@
local tex_base = "water\\water_water"
local tex_nmap = "water\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_caustic = "water\\water_caustic"
local tex_env0 = "$user$sky0"
local tex_env1 = "$user$sky1"
local tex_leaves = "water\\water_foam"
function normal(shader, t_base, t_second, t_detail)
shader:begin("water", "water")
:sorting(2, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:distort(true)
:fog(true)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_nmap", tex_nmap)
shader:dx10texture("s_env0", tex_env0)
shader:dx10texture("s_env1", tex_env1)
shader:dx10texture("s_env", "$user$sky")
shader:dx10texture("env_s0", "$user$env_s0")
shader:dx10texture("env_s1", "$user$env_s1")
shader:dx10texture("s_accumulator", "$user$accum")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_velocity", "$user$velocity")
shader:dx10texture("s_image", "$user$generic")
shader:dx10texture("s_material", "$user$material")
shader:dx10texture("s_leaves", tex_leaves)
shader:dx10texture("s_caustic", tex_caustic)
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
end
function l_special(shader, t_base, t_second, t_detail)
shader:begin("water", "waterd")
:sorting(2, true)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:fog(false)
:distort(true)
shader:dx10color_write_enable(true, true, true, false)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_distort", tex_dist)
shader:dx10texture("s_position", "$user$position")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
end

View file

@ -0,0 +1,36 @@
local tex_base = "water\\water_water"
local tex_nmap = "water\\water_normal"
local tex_env0 = "$user$sky0"
local tex_env1 = "$user$sky1"
function normal(shader, t_base, t_second, t_detail)
shader:begin("water_puddles", "water_puddles")
:sorting(2, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:fog(true)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_nmap", tex_nmap)
shader:dx10texture("s_env0", tex_env0)
shader:dx10texture("s_env1", tex_env1)
shader:dx10texture("s_env", "$user$sky")
shader:dx10texture("env_s0", "$user$env_s0")
shader:dx10texture("env_s1", "$user$env_s1")
shader:dx10texture("s_accumulator", "$user$accum")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_velocity", "$user$velocity")
shader:dx10texture("s_image", "$user$generic")
shader:dx10texture("s_material", "$user$material")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
end

View file

@ -0,0 +1,62 @@
local tex_base = "water\\water_ryaska1"
local tex_nmap = "water\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_caustic = "water\\water_caustic"
local tex_env0 = "$user$sky0"
local tex_env1 = "$user$sky1"
local tex_leaves = "water\\water_foam"
function normal(shader, t_base, t_second, t_detail)
shader:begin("water", "water")
:sorting(2, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:distort(true)
:fog(true)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_nmap", tex_nmap)
shader:dx10texture("s_env0", tex_env0)
shader:dx10texture("s_env1", tex_env1)
shader:dx10texture("s_env", "$user$sky")
shader:dx10texture("env_s0", "$user$env_s0")
shader:dx10texture("env_s1", "$user$env_s1")
shader:dx10texture("s_accumulator", "$user$accum")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_velocity", "$user$velocity")
shader:dx10texture("s_image", "$user$generic")
shader:dx10texture("s_material", "$user$material")
shader:dx10texture("s_leaves", tex_leaves)
shader:dx10texture("s_caustic", tex_caustic)
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
end
function l_special(shader, t_base, t_second, t_detail)
shader:begin("water", "waterd")
:sorting(2, true)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:fog(false)
:distort(true)
shader:dx10color_write_enable(true, true, true, false)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_distort", tex_dist)
shader:dx10texture("s_position", "$user$position")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
end

View file

@ -0,0 +1,62 @@
local tex_base = "water\\water_studen"
local tex_nmap = "water\\water_normal"
local tex_dist = "water\\water_dudv"
local tex_caustic = "water\\water_caustic"
local tex_env0 = "$user$sky0"
local tex_env1 = "$user$sky1"
local tex_leaves = "water\\water_foam"
function normal(shader, t_base, t_second, t_detail)
shader:begin("water", "water")
:sorting(2, false)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:distort(true)
:fog(true)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_nmap", tex_nmap)
shader:dx10texture("s_env0", tex_env0)
shader:dx10texture("s_env1", tex_env1)
shader:dx10texture("s_env", "$user$sky")
shader:dx10texture("env_s0", "$user$env_s0")
shader:dx10texture("env_s1", "$user$env_s1")
shader:dx10texture("s_accumulator", "$user$accum")
shader:dx10texture("s_position", "$user$position")
shader:dx10texture("s_velocity", "$user$velocity")
shader:dx10texture("s_image", "$user$generic")
shader:dx10texture("s_material", "$user$material")
shader:dx10texture("s_leaves", tex_leaves)
shader:dx10texture("s_caustic", tex_caustic)
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
shader:dx10sampler("smp_rtlinear")
end
function l_special(shader, t_base, t_second, t_detail)
shader:begin("water", "waterd")
:sorting(2, true)
:blend(true, blend.srcalpha, blend.invsrcalpha)
:zb(true, false)
:fog(false)
:distort(true)
shader:dx10color_write_enable(true, true, true, false)
shader:dx10texture("s_base", tex_base)
shader:dx10texture("s_distort", tex_dist)
shader:dx10texture("s_position", "$user$position")
shader:dx10sampler("smp_base")
shader:dx10sampler("smp_nofilter")
end

View file

@ -0,0 +1,10 @@
function normal(shader, t_base, t_second, t_detail)
shader:begin("stub_default", "stub_default")
-- shader:begin ("stub_default","test","stub_default")
:zb(true, false)
:blend(true, blend.one, blend.one)
:sorting(2, true)
shader:dx10texture("s_base", "water\\water_ryaska1")
shader:dx10sampler("smp_base")
end

View file

@ -0,0 +1,14 @@
#include "fluid_common.hlsli"
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
if (IsNonEmptyCell(input.texcoords.xyz))
{
return 0;
}
float3 npos = GetAdvectedPosTexCoords(input);
return Texture_color.SampleLevel(samLinear, npos, 0) * modulate;
}

View file

@ -0,0 +1,32 @@
#include "fluid_common.hlsli"
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
if (IsNonEmptyCell(input.texcoords.xyz))
{
return 0;
}
float3 npos = GetAdvectedPosTexCoords(input);
float4 r;
float3 diff = abs(floatVolumeDim.xyz - input.cell0.xyz);
// Must use regular semi-Lagrangian advection instead of BFECC at the volume boundaries
if ((diff.x > (floatVolumeDim.x - 4)) || (diff.y > (floatVolumeDim.y - 4)) || (diff.z > (floatVolumeDim.z - 4)))
{
r = Texture_color.SampleLevel(samLinear, npos, 0);
}
else
{
// Texture_color contains \phi^n; Texture_tempscalar contains \bar{\phi}
// (i.e.: the result of 1 forward advection step, followed by a backwards advection step)
r = 1.5f * Texture_color.SampleLevel(samLinear, npos, 0) -
0.5f * Texture_tempscalar.SampleLevel(samLinear, npos, 0);
}
r = saturate(r);
return r * modulate;
}

View file

@ -0,0 +1,63 @@
#include "fluid_common.hlsli"
#define Texture_phi_n Texture_color
#define Texture_phi_n_hat Texture_tempscalar
// Advect MCCormack
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
if (IsNonEmptyCell(input.texcoords.xyz))
{
return 0;
}
// get advected new position
float3 npos = input.cell0 - timestep * forward *
Texture_velocity0.SampleLevel(samPointClamp, input.texcoords, 0).xyz;
// convert new position to texture coordinates
float3 nposTC = float3(npos.x / textureWidth, npos.y / textureHeight, (npos.z + 0.5) / textureDepth);
// find the texel corner closest to the semi-Lagrangian "particle"
float3 nposTexel = floor(npos + float3(0.5f, 0.5f, 0.5f));
float3 nposTexelTC = float3(nposTexel.x / textureWidth, nposTexel.y / textureHeight, (nposTexel.z + 0.5) / textureDepth);
// ht (float-texel)
float3 ht = float3(0.5f / textureWidth, 0.5f / textureHeight, 0.5f / textureDepth);
// get the values of nodes that contribute to the interpolated value
// (texel centers are at float-integer locations)
float4 nodeValues[8];
nodeValues[0] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, -ht.y, -ht.z), 0);
nodeValues[1] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, -ht.y, ht.z), 0);
nodeValues[2] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, ht.y, -ht.z), 0);
nodeValues[3] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(-ht.x, ht.y, ht.z), 0);
nodeValues[4] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, -ht.y, -ht.z), 0);
nodeValues[5] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, -ht.y, ht.z), 0);
nodeValues[6] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, ht.y, -ht.z), 0);
nodeValues[7] = Texture_phi_n.SampleLevel(samPointClamp, nposTexelTC + float3(ht.x, ht.y, ht.z), 0);
// determine a valid range for the result
float4 phiMin = min(min(min(nodeValues[0], nodeValues[1]), nodeValues[2]), nodeValues[3]);
phiMin = min(min(min(min(phiMin, nodeValues[4]), nodeValues[5]), nodeValues[6]), nodeValues[7]);
float4 phiMax = max(max(max(nodeValues[0], nodeValues[1]), nodeValues[2]), nodeValues[3]);
phiMax = max(max(max(max(phiMax, nodeValues[4]), nodeValues[5]), nodeValues[6]), nodeValues[7]);
float4 r;
// Perform final MACCORMACK advection step:
// You can use point sampling and keep Texture_phi_n_1_hat
// r = Texture_phi_n_1_hat.SampleLevel( samPointClamp, input.texcoords, 0 )
// OR use bilerp to avoid the need to keep a separate texture for phi_n_1_hat
r = Texture_phi_n.SampleLevel(samLinear, nposTC, 0) + 0.5 * (Texture_phi_n.SampleLevel(samPointClamp, input.texcoords, 0) -
Texture_phi_n_hat.SampleLevel(samPointClamp, input.texcoords, 0));
// clamp result to the desired range
r = max(min(r, phiMax), phiMin);
float4 ret = r * modulate - k;
ret = clamp(ret, float4(0, 0, 0, 0), float4(5, 5, 5, 5));
return ret;
}

View file

@ -0,0 +1,15 @@
#include "fluid_common.hlsli"
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
if (IsNonEmptyCell(input.texcoords.xyz))
{
return 0;
}
float3 npos = GetAdvectedPosTexCoords(input);
float4 ret = Texture_color.SampleLevel(samLinear, npos, 0) * modulate - k;
ret = clamp(ret, float4(0, 0, 0, 0), float4(5, 5, 5, 5));
return ret;
}

View file

@ -0,0 +1,21 @@
#include "fluid_common.hlsli"
float GravityBuoyancy;
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
float3 npos = GetAdvectedPosTexCoords(input);
float4 Velocity = Texture_velocity0.SampleLevel(samLinear, npos, 0) * modulate;
#ifdef USE_GRAVITY
float Dencity = Texture_color.SampleLevel(samLinear, npos, 0).x;
Velocity.y += Dencity * GravityBuoyancy;
#endif // USE_GRAVITY
return Velocity;
}

View file

@ -0,0 +1,3 @@
#define USE_GRAVITY
#include "fluid_advect_vel.ps.hlsl"
// main

View file

@ -0,0 +1,21 @@
#include "fluid_common.hlsli"
// Geometry
[maxvertexcount(3)]
void main(triangle v2g_fluidsim In[3], inout TriangleStream<g2p_fluidsim> triStream)
{
g2p_fluidsim Out;
// cell0.z of the first vertex in the triangle determines the destination slice index
Out.RTIndex = In[0].cell0.z;
for (int v = 0; v < 3; v++)
{
Out.pos = In[v].pos;
Out.cell0 = In[v].cell0;
Out.texcoords = In[v].texcoords;
Out.LR = In[v].LR;
Out.BT = In[v].BT;
Out.DU = In[v].DU;
triStream.Append(Out);
}
triStream.RestartStrip();
}

View file

@ -0,0 +1,20 @@
#include "fluid_common.hlsli"
// Geometry
[maxvertexcount(3)]
void main(triangle v2g_fluidsim_dyn_aabb In[3], inout TriangleStream<g2p_fluidsim_dyn_aabb> triStream)
{
g2p_fluidsim_dyn_aabb Out;
// cell0.z of the first vertex in the triangle determines the destination slice index
Out.RTIndex = In[0].cell0.z;
for (int v = 0; v < 3; v++)
{
Out.pos = In[v].pos;
Out.cell0 = In[v].cell0;
Out.velocity = In[v].velocity;
Out.clip0 = In[v].clip0;
Out.clip1 = In[v].clip1;
triStream.Append(Out);
}
triStream.RestartStrip();
}

View file

@ -0,0 +1,23 @@
#include "fluid_common.hlsli"
// Geometry
[maxvertexcount(3)]
void main(triangle v2g_fluidsim_clip In[3], inout TriangleStream<g2p_fluidsim_clip> triStream)
{
g2p_fluidsim_clip Out;
// cell0.z of the first vertex in the triangle determines the destination slice index
Out.RTIndex = In[0].cell0.z;
for (int v = 0; v < 3; v++)
{
Out.pos = In[v].pos;
Out.cell0 = In[v].cell0;
Out.texcoords = In[v].texcoords;
Out.LR = In[v].LR;
Out.BT = In[v].BT;
Out.DU = In[v].DU;
Out.clip0 = In[v].clip0;
Out.clip1 = In[v].clip1;
triStream.Append(Out);
}
triStream.RestartStrip();
}

View file

@ -0,0 +1,214 @@
//--------------------------------------------------------------------------------------
// Defines
//--------------------------------------------------------------------------------------
#define LEFTCELL float3(input.LR.x, input.texcoords.y, input.texcoords.z)
#define RIGHTCELL float3(input.LR.y, input.texcoords.y, input.texcoords.z)
#define BOTTOMCELL float3(input.texcoords.x, input.BT.x, input.texcoords.z)
#define TOPCELL float3(input.texcoords.x, input.BT.y, input.texcoords.z)
#define DOWNCELL float3(input.texcoords.x, input.texcoords.y, input.DU.x)
#define UPCELL float3(input.texcoords.x, input.texcoords.y, input.DU.y)
// 1.73 - voxel diagonal length
#define BOX_EXPANSION 1.73
//--------------------------------------------------------------------------------------
// Textures
//--------------------------------------------------------------------------------------
Texture3D Texture_velocity0;
Texture3D Texture_velocity1;
Texture3D Texture_color;
Texture3D Texture_obstacles;
Texture3D Texture_obstvelocity;
Texture3D Texture_pressure;
Texture3D Texture_tempscalar;
Texture3D Texture_tempvector;
//--------------------------------------------------------------------------------------
// Samplers
//--------------------------------------------------------------------------------------
sampler samPointClamp;
sampler samLinear;
//--------------------------------------------------------------------------------------
// Variables
//--------------------------------------------------------------------------------------
cbuffer FluidSimConfig
{
float textureHeight;
float textureWidth;
float textureDepth;
float modulate = 1.0;
float epsilon;
float timestep;
float forward = 1.0;
float4 floatVolumeDim; // Actually float3. We don't support float3 and float2
}
cbuffer AABBBounds
{
float4 boxLBDcorner; // float3
float4 boxRTUcorner; // float3
}
cbuffer EmitterParams
{
float size;
float4 center; // Actually float3. We don't support float3 and float2
float4 splatColor;
}
cbuffer OOBBClipPlanes
{
float4 OOBBClipPlane[6];
// 0 - Top
// 1 - Bottom
}
// For fire simulation. Fuel extinction speed.
static const float k = 0.006;
/////////////////////////////////////////////////////////////////
// Structs
/////////////////////////////////////////////////////////////////
// fluidsim
struct v_fluidsim
{
float3 position : POSITION; // 2D slice vertex coordinates in clip space
float3 textureCoords0 : TEXCOORD; // 3D cell coordinates (x,y,z in 0-dimension range)
};
struct v2g_fluidsim
{
float3 cell0 : TEXCOORD0;
float3 texcoords : TEXCOORD1;
float2 LR : TEXCOORD2;
float2 BT : TEXCOORD3;
float2 DU : TEXCOORD4;
float4 pos : SV_POSITION;
};
struct g2p_fluidsim
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 texcoords : TEXCOORD1; // 3D cell texcoords (x,y,z in 0-1 range)
float2 LR : TEXCOORD2; // 3D cell texcoords for the Left and Right neighbors
float2 BT : TEXCOORD3; // 3D cell texcoords for the Bottom and Top neighbors
float2 DU : TEXCOORD4; // 3D cell texcoords for the Down and Up neighbors
float4 pos : SV_POSITION; // 2D slice vertex coordinates in homogenous clip space
uint RTIndex : SV_RenderTargetArrayIndex; // used to choose the destination slice
};
struct p_fluidsim
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 texcoords : TEXCOORD1; // 3D cell texcoords (x,y,z in 0-1 range)
float2 LR : TEXCOORD2; // 3D cell texcoords for the Left and Right neighbors
float2 BT : TEXCOORD3; // 3D cell texcoords for the Bottom and Top neighbors
float2 DU : TEXCOORD4; // 3D cell texcoords for the Down and Up neighbors
};
/////////////////////////////////////////////////////////////////
// fluidsim_clip
// TODO: DX10: These structures are used for obstacle rendering. Remove unused fields.
struct v2g_fluidsim_clip
{
float3 cell0 : TEXCOORD0;
float3 texcoords : TEXCOORD1;
float2 LR : TEXCOORD2;
float2 BT : TEXCOORD3;
float2 DU : TEXCOORD4;
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 pos : SV_POSITION;
};
struct g2p_fluidsim_clip
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 texcoords : TEXCOORD1; // 3D cell texcoords (x,y,z in 0-1 range)
float2 LR : TEXCOORD2; // 3D cell texcoords for the Left and Right neighbors
float2 BT : TEXCOORD3; // 3D cell texcoords for the Bottom and Top neighbors
float2 DU : TEXCOORD4; // 3D cell texcoords for the Down and Up neighbors
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 pos : SV_POSITION; // 2D slice vertex coordinates in homogenous clip space
uint RTIndex : SV_RenderTargetArrayIndex; // used to choose the destination slice
};
struct p_fluidsim_clip
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 texcoords : TEXCOORD1; // 3D cell texcoords (x,y,z in 0-1 range)
float2 LR : TEXCOORD2; // 3D cell texcoords for the Left and Right neighbors
float2 BT : TEXCOORD3; // 3D cell texcoords for the Bottom and Top neighbors
float2 DU : TEXCOORD4; // 3D cell texcoords for the Down and Up neighbors
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
};
/////////////////////////////////////////////////////////////////
// fluidsim_clip
// TODO: DX10: These structures are used for obstacle rendering. Remove unused fields.
struct v2g_fluidsim_dyn_aabb
{
float3 cell0 : TEXCOORD0;
float3 velocity : TEXCOORD1;
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 pos : SV_POSITION;
};
struct g2p_fluidsim_dyn_aabb
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 velocity : TEXCOORD1; // speed of the point in local space
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
float4 pos : SV_POSITION; // 2D slice vertex coordinates in homogenous clip space
uint RTIndex : SV_RenderTargetArrayIndex; // used to choose the destination slice
};
struct p_fluidsim_dyn_aabb
{
float3 cell0 : TEXCOORD0; // 3D cell coordinates (x,y,z in 0-dimension range)
float3 velocity : TEXCOORD1;
float3 clip0 : SV_ClipDistance0;
float3 clip1 : SV_ClipDistance1;
};
//--------------------------------------------------------------------------------------
// Helper functions
//--------------------------------------------------------------------------------------
float4 GetObstVelocity(float3 cellTexCoords)
{
return Texture_obstvelocity.SampleLevel(samPointClamp, cellTexCoords, 0);
}
bool IsNonEmptyCell(float3 cellTexCoords)
{
return (Texture_obstacles.SampleLevel(samPointClamp, cellTexCoords, 0).r > 0.0);
}
bool IsBoundaryCell(float3 cellTexCoords)
{
return (Texture_obstacles.SampleLevel(samPointClamp, cellTexCoords, 0).r > 0.9);
}
float3 GetAdvectedPosTexCoords(p_fluidsim input)
{
float3 pos = input.cell0;
pos -= timestep * forward *
Texture_velocity0.SampleLevel(samPointClamp, input.texcoords, 0).xyz;
return float3(pos.x / textureWidth, pos.y / textureHeight, (pos.z + 0.5) / textureDepth);
}

View file

@ -0,0 +1,344 @@
//--------------------------------------------------------------------------------------
// Defines
//--------------------------------------------------------------------------------------
// #define OCCLUDED_PIXEL_RAYVALUE float4(1, 0, 0, 0)
// Use very large value for aplha to help edge detection
#define OCCLUDED_PIXEL_RAYVALUE float4(1, 0, 0, 100000)
#define NEARCLIPPED_PIXEL_RAYPOS float3(0, -1, 0)
// Z for skybox is zero, so patch this in shader
#define Z_EPSILON 0.00001
// Value for skybox depth
#define Z_MAX 100000
#pragma warning(disable : 4000)
//--------------------------------------------------------------------------------------
// Textures
//--------------------------------------------------------------------------------------
Texture2D sceneDepthTex;
Texture3D colorTex;
Texture2D rayDataTex;
Texture2D rayDataTexSmall;
Texture2D rayCastTex;
Texture2D edgeTex;
Texture2D jitterTex;
Texture2D fireTransferFunction;
//--------------------------------------------------------------------------------------
// Samplers
//--------------------------------------------------------------------------------------
sampler samPointClamp;
sampler samLinearClamp;
sampler samRepeat;
//--------------------------------------------------------------------------------------
// Variables
//--------------------------------------------------------------------------------------
// Set once per volume
// Use for all rendering passes
cbuffer FluidRenderConfig
{
float RTWidth;
float RTHeight;
float4 DiffuseLight;
float4 DepthUnpack;
float4x4 WorldViewProjection;
float4x4 InvWorldViewProjection;
float ZNear;
float ZFar;
float4 gridDim; // float3
float4 recGridDim; // float3
float maxGridDim;
float gridScaleFactor = 1.0;
float4 eyeOnGrid; // float3
}
// static float edgeThreshold = 0.2;
// static float edgeThreshold = 0.1;
static float edgeThreshold = 0.01;
static const bool g_bRaycastFilterTricubic = false; // true: tricubic; false: trilinear
// static const bool g_bRaycastFilterTricubic = true; // true: tricubic; false: trilinear
#include "fluid_common_tricubic.hlsli"
// Fire setup
static const float RednessFactor = 5.0f;
static const float fireAlphaMultiplier = 0.95f;
// static const float smokeAlphaMultiplier = 0.05f;
static const float smokeAlphaMultiplier = 0.5f;
// static const float smokeColorMultiplier = 2.00f;
static const float smokeColorMultiplier = 0.02f;
//--------------------------------------------------------------------------------------
// Structs
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float3 pos : POSITION;
};
struct PS_INPUT_RAYDATA_BACK
{
float4 pos : SV_POSITION;
float depth : TEXCOORD0;
};
struct PS_INPUT_RAYDATA_FRONT
{
float4 pos : SV_POSITION;
float3 posInGrid : POSITION;
float depth : TEXCOORD0;
};
struct PS_INPUT_RAYCAST
{
float4 pos : SV_POSITION;
float3 posInGrid : POSITION;
};
struct VS_OUTPUT_EDGE
{
// There's no textureUV11 because its weight is zero.
float4 position : SV_POSITION; // vertex position
float2 textureUV00 : TEXCOORD0; // kernel tap texture coords
float2 textureUV01 : TEXCOORD1; // kernel tap texture coords
float2 textureUV02 : TEXCOORD2; // kernel tap texture coords
float2 textureUV10 : TEXCOORD3; // kernel tap texture coords
float2 textureUV12 : TEXCOORD4; // kernel tap texture coords
float2 textureUV20 : TEXCOORD5; // kernel tap texture coords
float2 textureUV21 : TEXCOORD6; // kernel tap texture coords
float2 textureUV22 : TEXCOORD7; // kernel tap texture coords
};
//--------------------------------------------------------------------------------------
// Functions
//--------------------------------------------------------------------------------------
float EdgeDetectScalar(float sx, float sy, float threshold)
{
float dist = (sx * sx + sy * sy);
float e = (dist > threshold * ZFar) ? 1 : 0;
return e;
}
/*
// We can select either back=to-front or front-to-back raycasting and blending.
// front-to-back may be slightly more expensive, but if the smoke is dense it allows
// early-out when the opacity gets saturated (close to 1.0), making it a bit cheaper
//
// Define BACK_TO_FRONT to use back-to-front raycasting
//#define BACK_TO_FRONT 1
void DoSample(float weight, float3 O, inout float4 color )
{
// This value can be tuned to produce denser or thinner looking smoke
// Alternatively a transfer function could be used
#define OPACITY_MODULATOR 0.1
float3 texcoords;
float4 sample;
float t;
texcoords = float3( O.x, 1 - O.y, O.z) ;
// sample = weight * colorTex.SampleLevel(samLinearClamp, texcoords, 0);
// sample = weight * abs(SampleTricubic(colorTex, texcoords));
// sample = weight * abs(SampleTrilinear(colorTex, texcoords));
sample = weight * abs(Sample(colorTex, texcoords));
sample.a = (sample.r) * OPACITY_MODULATOR;
#ifdef BACK_TO_FRONT // back-to-front blending
color.rgb = (1 - sample.a) * color.r + sample.a * sample.r;
color.a = (1 - sample.a) * color.a + sample.a;
#else // front-to-back blending
t = sample.a * (1.0-color.a);
color.rgb += t * sample.r;
color.a += t;
#endif
}
float4 Raycast( PS_INPUT_RAYCAST input )
{
float4 color = 0;
float4 rayData = rayDataTex.Sample(samLinearClamp, float2(input.pos.x/RTWidth,input.pos.y/RTHeight));
// Don't raycast if the starting position is negative
// (see use of OCCLUDED_PIXEL_RAYVALUE in PS_RAYDATA_FRONT)
if(rayData.x < 0)
return color;
// If the front face of the box was clipped here by the near plane of the camera
// (see use of NEARCLIPPED_PIXEL_RAYPOS in PS_RAYDATA_BACK)
if(rayData.y < 0)
{
// Initialize the position of the fragment and adjust the depth
rayData.xyz = input.posInGrid;
rayData.w = rayData.w - ZNear;
// return float4 (1,0,0,saturate(rayData.w/5));
}
float3 rayOrigin = rayData.xyz;
float Offset = jitterTex.Sample( samRepeat, input.pos.xy / 256.0 ).r;
float rayLength = rayData.w;
// Sample twice per voxel
float fSamples = ( rayLength / gridScaleFactor * maxGridDim ) * 2.0;
int nSamples = floor(fSamples);
float3 stepVec = normalize( (rayOrigin - eyeOnGrid) * gridDim ) * recGridDim * 0.5;
float3 O = rayOrigin + stepVec*Offset;
#ifdef BACK_TO_FRONT
// In back-to-front blending we start raycasting from the surface point and step towards the eye
O += fSamples * stepVec;
stepVec = -stepVec;
#endif
for( int i=0; i<nSamples ; i++ )
{
DoSample(1, O, color);
O += stepVec;
#ifndef BACK_TO_FRONT
// If doing front-to-back blending we can do early exit when opacity saturates
if( color.a > 0.99 )
break;
#endif
}
// The last sample is weighted by the fractional part of the ray length in voxel
// space (fSamples), thus avoiding banding artifacts when the smoke is blended against the scene
if( i == nSamples )
{
DoSample(frac(fSamples), O, color);
}
return color;
}
*/
// #define RENDER_FIRE
void DoSample(float weight, float3 O, inout float4 color)
{
// This value can be tuned to produce denser or thinner looking smoke
// Alternatively a transfer function could be used
#define OPACITY_MODULATOR 0.1
float3 texcoords;
texcoords = float3(O.x, 1 - O.y, O.z);
#ifndef RENDER_FIRE
// render smoke with front to back blending
float t;
float4 sample = weight * abs(Sample(colorTex, texcoords));
sample.a = (sample.r) * 0.1;
t = sample.a * (1.0 - color.a);
color.rgb += t * sample.r;
color.a += t;
#else // RENDER_FIRE
// render fire and smoke with back to front blending
// dont render the area below where the fire originates
// if(O.z < OBSTACLE_MAX_HEIGHT/gridDim.z)
// return;
// this is the threshold at which we decide whether to render fire or smoke
float threshold = 1.4;
float maxValue = 3;
float s = colorTex.SampleLevel(samLinearClamp, texcoords, 0).x;
s = clamp(s, 0, maxValue);
if (s > threshold)
{
// render fire
float lookUpVal = ((s - threshold) / (maxValue - threshold));
lookUpVal = 1.0 - pow(lookUpVal, RednessFactor);
lookUpVal = clamp(lookUpVal, 0, 1);
float3 interpColor = fireTransferFunction.SampleLevel(samLinearClamp, float2(lookUpVal, 0), 0).xyz;
float mult = (s - threshold);
color += float4(weight * interpColor.rgb, weight * mult * mult * fireAlphaMultiplier);
}
else
{
// render smoke
float4 sample = weight * s;
sample.a = sample.r * 0.1 * smokeAlphaMultiplier;
float3 smokeColor = float3(0.9, 0.35, 0.055);
color.rgb = (1 - sample.a) * color.rgb + sample.a * sample.rrr * smokeColor * smokeColorMultiplier * 5.0;
color.a = (1 - sample.a) * color.a + sample.a;
}
#endif // RENDER_FIRE
}
float4 Raycast(PS_INPUT_RAYCAST input)
{
float4 color = 0;
float4 rayData = rayDataTex.Sample(samLinearClamp, float2(input.pos.x / RTWidth, input.pos.y / RTHeight));
// Don't raycast if the starting position is negative
// (see use of OCCLUDED_PIXEL_RAYVALUE in PS_RAYDATA_FRONT)
if (rayData.x < 0)
{
return color;
}
// If the front face of the box was clipped here by the near plane of the camera
// (see use of NEARCLIPPED_PIXEL_RAYPOS in PS_RAYDATA_BACK)
if (rayData.y < 0)
{
// Initialize the position of the fragment and adjust the depth
rayData.xyz = input.posInGrid;
rayData.w = rayData.w - ZNear;
// return float4 (1,0,0,saturate(rayData.w/5));
}
float3 rayOrigin = rayData.xyz;
float Offset = jitterTex.Sample(samRepeat, input.pos.xy / 256.0).r;
float rayLength = rayData.w;
// Sample twice per voxel
float fSamples = (rayLength / gridScaleFactor * maxGridDim) * 2.0;
int nSamples = floor(fSamples);
float3 stepVec = normalize((rayOrigin - eyeOnGrid.xyz) * gridDim.xyz) * recGridDim.xyz * 0.5;
float3 O = rayOrigin + stepVec * Offset;
#ifdef RENDER_FIRE
// In back-to-front blending we start raycasting from the surface point and step towards the eye
O += fSamples * stepVec;
stepVec = -stepVec;
#endif // RENDER_FIRE
for (int i = 0; i < nSamples; i++)
{
DoSample(1, O, color);
O += stepVec;
#ifndef RENDER_FIRE
// If doing front-to-back blending we can do early exit when opacity saturates
if (color.a > 0.99)
{
break;
}
#endif // RENDER_FIRE
}
// The last sample is weighted by the fractional part of the ray length in voxel
// space (fSamples), thus avoiding banding artifacts when the smoke is blended against the scene
if (i == nSamples)
{
DoSample(frac(fSamples), O, color);
}
return color;
}

View file

@ -0,0 +1,233 @@
/////////////////////////////////
// BEGIN Custom Sampling Functions
Texture1D HHGGTex;
// cubic b-spline
float bsW0(float a)
{
return (1.0 / 6.0 * (-(a * a * a) + (3.0 * a * a) - (3.0 * a) + 1.0));
}
float bsW1(float a)
{
return (1.0 / 6.0 * ((3.0 * a * a * a) - (6.0 * a * a) + 4.0));
}
float bsW2(float a)
{
return (1.0 / 6.0 * (-(3.0 * a * a * a) + (3.0 * a * a) + (3.0 * a) + 1.0));
}
float bsW3(float a)
{
return (1.0 / 6.0 * a * a * a);
}
float g0(float a)
{
return (bsW0(a) + bsW1(a));
}
float g1(float a)
{
return (bsW2(a) + bsW3(a));
}
float h0texels(float a)
{
return (1.0 + a - (bsW1(a) / (bsW0(a) + bsW1(a))));
}
float h1texels(float a)
{
return (1.0 - a + (bsW3(a) / (bsW2(a) + bsW3(a))));
}
/// end cubic-bspline
// first derivative of cubic b-spline
float bsfdW0(float a)
{
return (1.0 / 6.0 * (-(3.0 * a * a) + (6.0 * a) - 3.0));
}
float bsfdW1(float a)
{
return (1.0 / 6.0 * ((9.0 * a * a) - (12.0 * a)));
}
float bsfdW2(float a)
{
return (1.0 / 6.0 * (-(9.0 * a * a) + (6.0 * a) + 3.0));
}
float bsfdW3(float a)
{
return (1.0 / 6.0 * 3.0 * a * a);
}
float gfd0(float a)
{
return (bsfdW0(a) + bsfdW1(a));
}
float gfd1(float a)
{
return (bsfdW2(a) + bsfdW3(a));
}
float hfd0texels(float a)
{
return (1.0 + a - (bsfdW1(a) / (bsfdW0(a) + bsfdW1(a))));
}
float hfd1texels(float a)
{
return (1.0 - a + (bsfdW3(a) / (bsfdW2(a) + bsfdW3(a))));
}
/// end first derivative of cubic b-spline
float4 getHHGG(float xTexels)
{
// float a = frac(xTexels);
// return float4( -h0texels(a), h1texels(a), 1.0-g0(a), g0(a) );
return HHGGTex.SampleLevel(samRepeat, xTexels, 0);
}
float4 getfdHHGG(float xTexels)
{
float a = frac(xTexels);
return float4(-hfd0texels(a), hfd1texels(a), gfd1(a), -gfd1(a));
}
float4 SampleTricubicGeneric(Texture3D tex, float3 tc, float4 hg_x, float4 hg_y, float4 hg_z)
{
float3 tc100, tc000, tc110, tc010,
tc101, tc001, tc111, tc011;
tc100 = tc;
tc000 = tc;
tc100.x += (hg_x.x * recGridDim.x);
tc000.x += (hg_x.y * recGridDim.x);
tc110 = tc100;
tc010 = tc000;
tc110.y += (hg_y.x * recGridDim.y);
tc010.y += (hg_y.x * recGridDim.y);
tc100.y += (hg_y.y * recGridDim.y);
tc000.y += (hg_y.y * recGridDim.y);
tc111 = tc110;
tc011 = tc010;
tc101 = tc100;
tc001 = tc000;
tc111.z += (hg_z.x * recGridDim.z);
tc011.z += (hg_z.x * recGridDim.z);
tc101.z += (hg_z.x * recGridDim.z);
tc001.z += (hg_z.x * recGridDim.z);
float4 v001 = tex.SampleLevel(samLinearClamp, tc001, 0);
float4 v011 = tex.SampleLevel(samLinearClamp, tc011, 0);
float4 v101 = tex.SampleLevel(samLinearClamp, tc101, 0);
float4 v111 = tex.SampleLevel(samLinearClamp, tc111, 0);
float4 v0Y1 = (v001 * hg_y.z) + (v011 * hg_y.w);
float4 v1Y1 = (v101 * hg_y.z) + (v111 * hg_y.w);
float4 vXY1 = (v0Y1 * hg_x.z) + (v1Y1 * hg_x.w);
tc110.z += (hg_z.y * recGridDim.z);
tc010.z += (hg_z.y * recGridDim.z);
tc100.z += (hg_z.y * recGridDim.z);
tc000.z += (hg_z.y * recGridDim.z);
float4 v000 = tex.SampleLevel(samLinearClamp, tc000, 0);
float4 v010 = tex.SampleLevel(samLinearClamp, tc010, 0);
float4 v100 = tex.SampleLevel(samLinearClamp, tc100, 0);
float4 v110 = tex.SampleLevel(samLinearClamp, tc110, 0);
float4 v0Y0 = (v000 * hg_y.z) + (v010 * hg_y.w);
float4 v1Y0 = (v100 * hg_y.z) + (v110 * hg_y.w);
float4 vXY0 = (v0Y0 * hg_x.z) + (v1Y0 * hg_x.w);
float4 vXYZ = (vXY0 * hg_z.z) + (vXY1 * hg_z.w);
return vXYZ;
}
float4 SampleTricubic(Texture3D tex, float3 tc)
{
float3 tcTexels = (tc * gridDim.xyz) - 0.49;
float4 hg_x = getHHGG(tcTexels.x);
float4 hg_y = getHHGG(tcTexels.y);
float4 hg_z = getHHGG(tcTexels.z);
return SampleTricubicGeneric(tex, tc, hg_x, hg_y, hg_z);
}
float4 SampleGradientTricubic(Texture3D tex, float3 tc)
{
float3 tcTexels = (tc * gridDim.xyz) - 0.49;
float4 hg_x = getHHGG(tcTexels.x);
float4 hg_y = getHHGG(tcTexels.y);
float4 hg_z = getHHGG(tcTexels.z);
float4 hgfd_x = getfdHHGG(tcTexels.x);
float4 hgfd_y = getfdHHGG(tcTexels.y);
float4 hgfd_z = getfdHHGG(tcTexels.z);
return float4(SampleTricubicGeneric(tex, tc, hgfd_x, hg_y, hg_z).r,
SampleTricubicGeneric(tex, tc, hg_x, hgfd_y, hg_z).r,
SampleTricubicGeneric(tex, tc, hg_x, hg_y, hgfd_z).r, 1.0);
}
float4 SampleTrilinear(Texture3D tex, float3 tc)
{
return tex.SampleLevel(samLinearClamp, tc, 0);
}
float4 SampleGradientTrilinear(Texture3D tex, float3 tc)
{
#define LEFTCELL float3(tc.x - (1.0 / gridDim.x), tc.y, tc.z)
#define RIGHTCELL float3(tc.x + (1.0 / gridDim.x), tc.y, tc.z)
#define BOTTOMCELL float3(tc.x, (tc.y - (1.0 / gridDim.y)), tc.z)
#define TOPCELL float3(tc.x, (tc.y + (1.0 / gridDim.y)), tc.z)
#define DOWNCELL float3(tc.x, tc.y, tc.z - (1.0 / gridDim.z))
#define UPCELL float3(tc.x, tc.y, tc.z + (1.0 / gridDim.z))
float4 texL = tex.SampleLevel(samLinearClamp, LEFTCELL, 0);
float4 texR = tex.SampleLevel(samLinearClamp, RIGHTCELL, 0);
float4 texB = tex.SampleLevel(samLinearClamp, BOTTOMCELL, 0);
float4 texT = tex.SampleLevel(samLinearClamp, TOPCELL, 0);
float4 texU = tex.SampleLevel(samLinearClamp, UPCELL, 0);
float4 texD = tex.SampleLevel(samLinearClamp, DOWNCELL, 0);
return float4(texR.r - texL.r, texT.r - texB.r, texU.r - texD.r, 1);
}
float4 Sample(Texture3D tex, float3 tc)
{
if (g_bRaycastFilterTricubic)
{
return SampleTricubic(tex, tc);
}
else
{
return SampleTrilinear(tex, tc);
}
}
float4 SampleGradient(Texture3D tex, float3 tc)
{
if (g_bRaycastFilterTricubic)
{
return SampleGradientTricubic(tex, tc);
}
else
{
return SampleGradientTrilinear(tex, tc);
}
}
// END Custom Sampling Functions
/////////////////////////////////

View file

@ -0,0 +1,30 @@
#include "fluid_common.hlsli"
// Pixel
float3 main(p_fluidsim input) : SV_Target
{
// Texture_tempvector contains the vorticity computed by PS_VORTICITY
float4 omega = Texture_tempvector.SampleLevel(samPointClamp, input.texcoords, 0);
// Potential optimization: don't find length multiple times - do once for the entire texture
float omegaL = length(Texture_tempvector.SampleLevel(samPointClamp, LEFTCELL, 0));
float omegaR = length(Texture_tempvector.SampleLevel(samPointClamp, RIGHTCELL, 0));
float omegaB = length(Texture_tempvector.SampleLevel(samPointClamp, BOTTOMCELL, 0));
float omegaT = length(Texture_tempvector.SampleLevel(samPointClamp, TOPCELL, 0));
float omegaD = length(Texture_tempvector.SampleLevel(samPointClamp, DOWNCELL, 0));
float omegaU = length(Texture_tempvector.SampleLevel(samPointClamp, UPCELL, 0));
float3 eta = 0.5 * float3(omegaR - omegaL,
omegaT - omegaB,
omegaU - omegaD);
eta = normalize(eta + float3(0.001, 0.001, 0.001));
float3 force = timestep * epsilon * float3(eta.y * omega.z - eta.z * omega.y,
eta.z * omega.x - eta.x * omega.z,
eta.x * omega.y - eta.y * omega.x);
// Note: the result is added to the current velocity at each cell using "additive blending"
return force;
}

View file

@ -0,0 +1,42 @@
#include "fluid_common.hlsli"
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
float4 fieldL = Texture_velocity1.SampleLevel(samPointClamp, LEFTCELL, 0);
float4 fieldR = Texture_velocity1.SampleLevel(samPointClamp, RIGHTCELL, 0);
float4 fieldB = Texture_velocity1.SampleLevel(samPointClamp, BOTTOMCELL, 0);
float4 fieldT = Texture_velocity1.SampleLevel(samPointClamp, TOPCELL, 0);
float4 fieldD = Texture_velocity1.SampleLevel(samPointClamp, DOWNCELL, 0);
float4 fieldU = Texture_velocity1.SampleLevel(samPointClamp, UPCELL, 0);
if (IsBoundaryCell(LEFTCELL))
{
fieldL = GetObstVelocity(LEFTCELL);
}
if (IsBoundaryCell(RIGHTCELL))
{
fieldR = GetObstVelocity(RIGHTCELL);
}
if (IsBoundaryCell(BOTTOMCELL))
{
fieldB = GetObstVelocity(BOTTOMCELL);
}
if (IsBoundaryCell(TOPCELL))
{
fieldT = GetObstVelocity(TOPCELL);
}
if (IsBoundaryCell(DOWNCELL))
{
fieldD = GetObstVelocity(DOWNCELL);
}
if (IsBoundaryCell(UPCELL))
{
fieldU = GetObstVelocity(UPCELL);
}
float divergence = 0.5 *
((fieldR.x - fieldL.x) + (fieldT.y - fieldB.y) + (fieldU.z - fieldD.z));
return divergence;
}

View file

@ -0,0 +1,19 @@
#include "fluid_common.hlsli"
// Pixel
float4 main(p_fluidsim input) : SV_Target
{
if (textureNumber == 1)
{
return abs(Texture_color.SampleLevel(samLinear, input.texcoords, 0)).xxxx;
}
else if (textureNumber == 2)
{
return abs(Texture_velocity0.SampleLevel(samLinear, input.texcoords, 0));
}
else
{
return float4(abs(Texture_obstvelocity.SampleLevel(samLinear, input.texcoords, 0).xy),
abs(Texture_obstacles.SampleLevel(samLinear, input.texcoords, 0).r), 1);
}
}

View file

@ -0,0 +1,83 @@
#include "fluid_common_render.hlsli"
// Pixel
// A full-screen edge detection pass to locate artifacts
// these artifacts are located on a downsized version of the rayDataTexture
// We use a smaller texture both to accurately find all the depth artifacts
// when raycasting to this smaller size and to save on the cost of this pass
// Use col.a to find depth edges of objects occluding the smoke
// Use col.g to find the edges where the camera near plane cuts the smoke volume
//
float4 main(VS_OUTPUT_EDGE vIn) : SV_Target
{
// We need eight samples (the centre has zero weight in both kernels).
float4 col;
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV00);
float g00 = col.a;
if (col.g < 0)
{
g00 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV01);
float g01 = col.a;
if (col.g < 0)
{
g01 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV02);
float g02 = col.a;
if (col.g < 0)
{
g02 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV10);
float g10 = col.a;
if (col.g < 0)
{
g10 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV12);
float g12 = col.a;
if (col.g < 0)
{
g12 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV20);
float g20 = col.a;
if (col.g < 0)
{
g20 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV21);
float g21 = col.a;
if (col.g < 0)
{
g21 *= -1;
}
col = rayDataTexSmall.Sample(samPointClamp, vIn.textureUV22);
float g22 = col.a;
if (col.g < 0)
{
g22 *= -1;
}
// Sobel in horizontal dir.
float sx = 0;
sx -= g00;
sx -= g01 * 2;
sx -= g02;
sx += g20;
sx += g21 * 2;
sx += g22;
// Sobel in vertical dir - weights are just rotated 90 degrees.
float sy = 0;
sy -= g00;
sy += g02;
sy -= g10 * 2;
sy += g12 * 2;
sy -= g20;
sy += g22;
float e = EdgeDetectScalar(sx, sy, edgeThreshold);
return float4(e, e, e, 1);
}

View file

@ -0,0 +1,26 @@
#include "fluid_common_render.hlsli"
// Vertex
// A full-screen edge detection pass to locate artifacts
VS_OUTPUT_EDGE main(VS_INPUT input)
{
VS_OUTPUT_EDGE output = (VS_OUTPUT_EDGE)0;
output.position = float4(input.pos, 1);
float2 texelSize = 1.0 / float2(RTWidth, RTHeight);
float2 center = float2((input.pos.x + 1) / 2.0, 1.0 - (input.pos.y + 1) / 2.0);
// Eight nearest neighbours needed for Sobel.
output.textureUV00 = center + float2(-texelSize.x, -texelSize.y);
output.textureUV01 = center + float2(-texelSize.x, 0);
output.textureUV02 = center + float2(-texelSize.x, texelSize.y);
output.textureUV10 = center + float2(0, -texelSize.y);
output.textureUV12 = center + float2(0, texelSize.y);
output.textureUV20 = center + float2(texelSize.x, -texelSize.y);
output.textureUV21 = center + float2(texelSize.x, 0);
output.textureUV22 = center + float2(texelSize.x, texelSize.y);
return output;
}

Some files were not shown because too many files have changed in this diff Show more