Added New Mods and Profiles Folders

This is a complete rebuild of the modpack, with all new mods and updates for 1.5.3 of Anomaly.
This commit is contained in:
2025-01-14 05:07:53 -05:00
parent 85c665b107
commit 376b4b9689
21217 changed files with 546254 additions and 0 deletions
@@ -0,0 +1,61 @@
#include "common.h"
#include "lmodel.h"
#include "shadow.h"
//////////////////////////////////////////////////////////////////////////////////////////
// This is the basic primitive used by convex, volumetric lights
// for example spot-lights, one face of the omni lights, etc.
//////////////////////////////////////////////////////////////////////////////////////////
// following options are available to configure compilation:
// USE_LMAP
// USE_LMAPXFORM
// USE_SHADOW
//////////////////////////////////////////////////////////////////////////////////////////
float4 m_lmap[2];
#ifdef MSAA_OPTIMIZATION
float4 main(p_volume I, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main(p_volume I, float4 pos2d : SV_Position ) : SV_Target
#endif
{
float2 tcProj = I.tc.xy / I.tc.w;
gbuffer_data gbd = gbuffer_load_data(GLD_P(tcProj, pos2d, ISAMPLE) );
float4 _P = float4(gbd.P, gbd.mtl );
float4 _N = float4(gbd.N, gbd.hemi );
float4 _C = float4(gbd.C, gbd.gloss );
float m = xmaterial ;
#ifndef USE_R2_STATIC_SUN
m = _P.w ;
#endif
// ----- light-model
float rsqr;
float4 light = plight_local(m, _P, _N, _C, Ldynamic_pos, Ldynamic_pos.w, rsqr );
// ----- shadow
float4 P4 = float4(_P.x, _P.y, _P.z, 1);
float4 PS = mul(m_shadow, P4 );
float s = 1.h;
#ifdef USE_SHADOW
s = shadow(PS );
#endif
// ----- lightmap
float4 lightmap= 1.h;
#ifdef USE_LMAP
#ifdef USE_LMAPXFORM
PS.x = dot(P4, m_lmap[0] );
PS.y = dot(P4, m_lmap[1] );
#endif
// Can use linear with mip point
lightmap = s_lmap.Sample(smp_rtlinear, PS.xy / PS.w ); //
#endif
float3 result = SRGBToLinear(lightmap.rgb) * SRGBToLinear(s);
result *= light * SRGBToLinear(Ldynamic_color.rgb);
return float4(result.rgb, 0);
}
@@ -0,0 +1,19 @@
#include "common.h"
#include "sload.h"
float4 main( p_flat I ) : SV_Target
{
//f_deffer O;
// diffuse
float3 D = tbase (I.tcdh); // IN: rgb.a
D = SRGBToLinear(D);
float brightness = 16;
float4 color = float4(D.rgb,1);
//color *= float4(brightness,brightness,brightness,brightness);
color.w *= brightness;
return color;
}
@@ -0,0 +1,19 @@
#include "common.h"
#include "sload.h"
float4 pda_params;
float4 main( p_flat I ) : SV_Target
{
//f_deffer O;
// diffuse
float3 D = tbase (I.tcdh); // IN: rgb.a
D = SRGBToLinear(D);
float brightness = pda_params.x;
float4 color = float4(D.rgb,1);
//color *= float4(brightness,brightness,brightness,brightness);
color.w *= brightness;
return color;
}
@@ -0,0 +1,34 @@
#include "common.h"
#include "lmodel.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
// Note: this is a float-sphere
float3 direction;
#ifdef MSAA_OPTIMIZATION
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position ) : SV_Target
#endif
{
float2 tcProj = tc.xy / tc.w;
gbuffer_data gbd = gbuffer_load_data( GLD_P(tcProj, pos2d, ISAMPLE) );
float4 _P = float4( gbd.P, gbd.mtl );
float4 _N = float4( gbd.N, gbd.hemi );
float4 _C = float4(gbd.C, gbd.gloss );
float3 L2P = _P.xyz - Ldynamic_pos.xyz; // light2point
float3 L2P_N = normalize ( L2P ); // light2point
float rsqr = dot ( L2P, L2P ); // distance 2 light (squared)
float att = saturate ( 1 - rsqr*Ldynamic_pos.w );// q-linear attenuate
float light = saturate ( dot( -L2P_N, _N.xyz ) );
float hemi = saturate ( dot( L2P_N, direction ) );
// Final color
float3 result = SRGBToLinear(att) * hemi;
result *= SRGBToLinear(_C.rgb) * SRGBToLinear(Ldynamic_color.rgb) * light;
return float4(result, 0);
}
@@ -0,0 +1,30 @@
#include "common.h"
#include "lmodel.h"
// TODO: DX10: Move to Load
#ifdef MSAA_OPTIMIZATION
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( float4 tc:TEXCOORD0, float4 pos2d : SV_Position ) : SV_Target
#endif
{
const float bias_mul = 0.999f;
// Sample the fat framebuffer:
float2 tcProj = tc.xy / tc.w;
gbuffer_data gbd = gbuffer_load_data( GLD_P(tcProj, pos2d, ISAMPLE) );
float4 _P = float4( gbd.P,gbd.mtl );
float4 _N = float4( gbd.N,gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
float m = xmaterial ;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float rsqr;
float4 light = plight_local( m, _P, _N, _C, Ldynamic_pos, Ldynamic_pos.w, rsqr );
return float4( SRGBToLinear(Ldynamic_color.rgb), 0) * light;
}
@@ -0,0 +1,37 @@
#include "common.h"
#include "lmodel.h"
#include "shadow.h"
#ifdef MSAA_OPTIMIZATION
float4 main(p_aa_AA_sun I, float4 pos2d : SV_Position, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main(p_aa_AA_sun I, float4 pos2d : SV_Position ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data(GLD_P(I.tc, pos2d, ISAMPLE) );
float4 _P = float4(gbd.P, gbd.mtl );
float4 _N = float4(gbd.N, gbd.hemi );
float4 _C = float4(gbd.C, gbd.gloss );
// ----- light-model
float m = xmaterial;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float4 light = plight_infinity(m, _P, _N, _C, Ldynamic_dir );
// ----- shadow
float4 s_sum;
s_sum.x = s_smap.Sample(smp_nofilter, I.LT).x;
s_sum.y = s_smap.Sample(smp_nofilter, I.RT).y;
s_sum.z = s_smap.Sample(smp_nofilter, I.LB).z;
s_sum.w = s_smap.Sample(smp_nofilter, I.RB).w;
float s = ((s_sum.x+s_sum.y)+(s_sum.z+s_sum.w))*(1.h/4.h);
float3 result = SRGBToLinear(s);
result *= light * SRGBToLinear(Ldynamic_color.rgb);
return float4(result, 0);
}
@@ -0,0 +1,81 @@
#include "common.h"
#include "lmodel.h"
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#if SUN_QUALITY>2
#define ULTRA_SHADOWS_ON
#endif // SUN_QUALITY>2
#ifdef ULTRA_SHADOWS_ON
#define USE_ULTRA_SHADOWS
#endif
#include "shadow.h"
uniform float3 view_shadow_proj;
#ifdef USE_SUNFILTER
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, 1.0);
float4 PS = mul( m_shadow, _P );
float s = shadowtest_sun( PS, I.tcJ ) * sunmask( _P );
return s;
}
#else
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc.xy/I.tc.w, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, gbd.mtl );
float4 _N = float4( gbd.N, gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
// ----- light-model
float m = xmaterial;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float4 light = plight_infinity ( m, _P, _N, _C, Ldynamic_dir );
// ----- shadow
float4 P4 = float4( _P.x, _P.y, _P.z, 1.0);
float4 PS = mul( m_shadow, P4 );
float s = sunmask( P4 );
s *= shadow( PS );
// Far edge fading code
float2 tc_f = (PS.xy/PS.w)-float2(0.5,0.5);
// Fade only fron edges
tc_f *= step( -dot( tc_f, view_shadow_proj.xy ), 0 );
tc_f = abs( tc_f );
float border = 0.4;
float fac_x = 1.0-saturate( ( tc_f.x - border )/(0.5-border));
float fac_y = 1.0-saturate( ( tc_f.y - border )/(0.5-border));
s += ((1.0-s)*(1.0-fac_x*fac_y));
//\ Far edge fading code
float3 result = SRGBToLinear(s);
result *= light * SRGBToLinear(Ldynamic_color.rgb);
return blend( float4(result, 0), I.tc );
}
#endif
@@ -0,0 +1,66 @@
#include "common.h"
#include "lmodel.h"
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#if SUN_QUALITY>2
#define ULTRA_SHADOWS_ON
#endif // SUN_QUALITY>2
#ifdef ULTRA_SHADOWS_ON
#define USE_ULTRA_SHADOWS
#endif
#include "shadow.h"
#ifdef USE_SUNFILTER
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, 1.0);
float4 PS = mul( m_shadow, _P );
float s = shadowtest_sun( PS, I.tcJ ) * sunmask( _P );
return s;
}
#else
#ifdef MSAA_OPTIMIZATION
float4 main ( v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main ( v2p_volume I ) : SV_Target
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc.xy/I.tc.w, I.hpos, ISAMPLE) );
float4 _P = float4( gbd.P, gbd.mtl );
float4 _N = float4( gbd.N, gbd.hemi );
float4 _C = float4( gbd.C, gbd.gloss );
// ----- light-model
float m = xmaterial;
#ifndef USE_R2_STATIC_SUN
m = _P.w;
#endif
float4 light = plight_infinity ( m, _P, _N, _C, Ldynamic_dir );
// ----- shadow
float4 P4 = float4( _P.x, _P.y, _P.z, 1.0);
float4 PS = mul( m_shadow, P4 );
float s = sunmask( P4 );
s *= shadow( PS );
float3 result = SRGBToLinear(s);
result.rgb *= light * SRGBToLinear(Ldynamic_color.rgb);
return float4(result.rgb, 0);
}
#endif
@@ -0,0 +1,77 @@
#include "common.h"
#include "shadow.h"
#ifndef ISAMPLE
#define ISAMPLE 0
#endif
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
};
float4 m_lmap[2];
Texture2D s_noise;
#define USE_LMAP
#define USE_LMAPXFORM
#define USE_SHADOW
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
#ifndef MSAA_OPTIMIZATION
float4 main ( v2p I ) : SV_Target
#else
float4 main ( v2p I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#endif
{
// ----- shadow
float4 P4 = float4(I.vPos, 1);
float4 PS = mul( m_shadow, P4);
float s = 1.h;
#ifdef USE_SHADOW
s = shadow_hw(PS);
#endif
// ----- lightmap
float4 lightmap = 1.h;
#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;
float time = timers.z*0.1;
PS.xy /= 3;
PS.x += time;
// TODO: DX10: Can use sampler with point mip filter
float4 t_noise = s_noise.Sample( smp_linear, PS );
PS.x -= time;
PS.y -= time*0.70091;
// TODO: DX10: Can use sampler with point mip filter
t_noise *= s_noise.Sample( smp_linear, PS );
t_noise = t_noise*0.5+0.5;
s = max(0, s);
att = max(0, att);
lightmap = max(0, lightmap);
t_noise = max(0, t_noise);
// matches vanilla?
float maxIntens = I.fDensity;
float3 result = maxIntens * s * att;
result *= lightmap;
result *= Ldynamic_color * t_noise;
return float4( result, 0); //srgb
//return float4( SRGBToLinear(result), 0);
}
@@ -0,0 +1,96 @@
#include "common.h"
#undef ULTRA_SHADOWS_ON
#undef USE_ULTRA_SHADOWS
#define RAY_PATH 2.0h
#define JITTER_TEXTURE_SIZE 64.0f
#ifdef SUN_SHAFTS_QUALITY
#if SUN_SHAFTS_QUALITY==1
#define FILTER_LOW
#define RAY_SAMPLES 15
#elif SUN_SHAFTS_QUALITY==2
#define RAY_SAMPLES 25
#elif SUN_SHAFTS_QUALITY==3
#define RAY_SAMPLES 30
#endif
#endif
#ifndef FILTER_LOW
#ifdef USE_MINMAX_SM
#define SM_MINMAX
#endif
#endif
#include "shadow.h"
float4 volume_range; // x - near plane, y - far plane
float4 sun_shafts_intensity;
#ifdef MSAA_OPTIMIZATION
float4 main (v2p_volume I, uint iSample : SV_SAMPLEINDEX ) : SV_Target
#else
float4 main (v2p_volume I) : SV_Target
#endif
{
#ifndef SUN_SHAFTS_QUALITY
return float4(0,0,0,0);
#else // SUN_SHAFTS_QUALITY
float2 tc = I.tc.xy/I.tc.w;
float4 pos2d = I.hpos;
gbuffer_data gbd = gbuffer_load_data( GLD_P(tc, pos2d, ISAMPLE) );
float3 P = gbd.P;
// Variable ray length, variable step dencity, use jittering
float4 J0 = jitter0.Sample( smp_jitter, tc*screen_res.x*1.0/JITTER_TEXTURE_SIZE );
float coeff = (RAY_SAMPLES - 1*J0.x)/(RAY_SAMPLES*RAY_SAMPLES);
float3 direction = P*coeff;
float depth = P.z;
float deltaDepth = direction.z;
float4 current = mul (m_shadow,float4(P,1.0));
float4 delta = mul (m_shadow, float4(direction,0.0));
float res = 0.0;
float max_density = sun_shafts_intensity;
float density = max_density/RAY_SAMPLES;
if (depth<0.0001)
res = max_density;
[unroll (RAY_SAMPLES)]
for ( int i=0; i<RAY_SAMPLES; ++i )
{
if (depth>0.3)
res += density*sample_hw_pcf(current, float4(0.0,0.0,0.0,0.0));
depth -= deltaDepth;
current -= delta;
}
float fSturation = -Ldynamic_dir.z;
// Normalize dot product to
fSturation = 0.5*fSturation+0.5;
// Map saturation to 0.2..1
fSturation = 0.80*fSturation+0.20;
res *= fSturation;
#ifdef USE_STRICT_GAMMA_CORRECTION
res = SRGBToLinear(res);
return res * float4(SRGBToLinear(Ldynamic_color.rgb), 1);
#else
return float4(res.rrr * Ldynamic_color.rgb, 0); //srgb
//return res * Ldynamic_color; //srgb
//return float4(SRGBToLinear(res.rrr * Ldynamic_color.rgb), 0);
#endif
#endif // SUN_SHAFTS_QUALITY
}
@@ -0,0 +1,42 @@
#include "common.h"
float4 b_params;
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
float4 main ( p_build I ) : SV_Target
{
float2 ratio = float2( 1/screen_res.x,1/screen_res.y).xy;
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
float2 UVavg = I.Tex0.xy;
//adjust for aspect ratio
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
// hi-rgb.base-lum
float3 s0 = s_image.Sample( smp_rtlinear, I.Tex0);
float3 s1 = s_image.Sample( smp_rtlinear, I.Tex1);
float3 s2 = s_image.Sample( smp_rtlinear, I.Tex2);
float3 s3 = s_image.Sample( smp_rtlinear, I.Tex3);
float3 avg = ( (s0+s1) + (s2+s3) )/4;
/*
float sum = saturate(dot( avg, 1.h ));
avg /= sum;
float hi = sum-b_params.x ; // assume def_hdr equal to 3.0
*/
float hi = 1-b_params.x;
//float hi = 1;
return float4( avg, hi );
}
@@ -0,0 +1,63 @@
#include "common.h"
//////////////////////////////////////////////////////////////////////////////////////////
float4 weight[2];
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
// Separable gauss filter: 2*7 + 1 + 7*2 = 29 samples
// Samples: 0-central, -1, -2,..., -7, 1, 2,... 7
// Approximated i-count: 15t + 15a + 7a(d) + 1(out) = 38, HLSL compiled to 38 :)
float4 main ( p_filter I ) : SV_Target
{
float4 ratio = float2( 1/screen_res.x,1/screen_res.y).xyxy;
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
//ratio.xyzw = ratio.xyxy;
ratio.xyzw = ratio.xyyx;
float4 UVavg = I.Tex0.xyyx;
//adjust for aspect ratio
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
I.Tex4 = UVavg + ((I.Tex4 - UVavg) * ratio);
I.Tex5 = UVavg + ((I.Tex5 - UVavg) * ratio);
I.Tex6 = UVavg + ((I.Tex6 - UVavg) * ratio);
I.Tex7 = UVavg + ((I.Tex7 - UVavg) * ratio);
// central
float4 accum = weight[1].w * s_bloom.Sample(smp_rtlinear, I.Tex0);
// left (7)
// right (7) - no swizles on 'texld', so this is dep-read infact
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;
}
@@ -0,0 +1,30 @@
#include "common.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
float4 main( p_build I ) : SV_Target
{
float2 ratio = float2( 1/screen_res.x,1/screen_res.y).xy;
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
float2 UVavg = (I.Tex0+I.Tex1+I.Tex2+I.Tex3)/4;
//adjust for aspect ratio
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
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) ) / 4;
}
@@ -0,0 +1,44 @@
#include "common.h"
//////////////////////////////////////////////////////////////////////////////////////////
#define LUMINANCE_BASE 0.0001h
float luminance (float2 tc)
{
float3 source = s_image.Sample( smp_rtlinear, tc );
return dot( source, LUMINANCE_VECTOR*def_hdr );
}
//////////////////////////////////////////////////////////////////////////////////////////
// perform 2x2=4s convolution, working on 4x4=16p area
// that means 256x256 source will be scaled to (256/4)x(256/4) = 64x64p
// a): 256x256 => 64x64p with log
// b): 64x64p => 8x8p
// c): 8x8p => 1x1p with exp
float4 main( p_build I ) : SV_Target
{
float2 ratio = float2( 1/screen_res.x,1/screen_res.y);
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
float2 UVavg = (I.Tex0+I.Tex1+I.Tex2+I.Tex3)/4;
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
// first 8 bilinear samples (8x4 = 32 pixels)
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;
}
@@ -0,0 +1,79 @@
#include "common.h"
struct v2p
{
float4 tc0: TEXCOORD0; // Central
float4 tc1: TEXCOORD1; // -1,+1
float4 tc2: TEXCOORD2; // -2,+2
float4 tc3: TEXCOORD3; // -3,+3
float4 tc4: TEXCOORD4; // -4,+4
float4 tc5: TEXCOORD5; // -5,+5
float4 tc6: TEXCOORD6; // -6,+6
float4 tc7: TEXCOORD7; // -7,+7
};
//////////////////////////////////////////////////////////////////////////////////////////
// perform 4x4 bilinear, 8x8p, the step (B)
// b): 64x64p => 8x8p
float sample (float2 tc)
{
float4 data = s_image.Sample( smp_rtlinear, tc );
return dot( data, 1.h/4.h ); // sum components
}
float4 main( p_filter I ) : SV_Target
{
float4 ratio = float2( 1/screen_res.x,1/screen_res.y).xyxy;
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
//ratio.xyzw = ratio.xyxy;
ratio.xyzw = ratio.xyyx;
float4 UVavg = (I.Tex0+I.Tex1+I.Tex2+I.Tex3+I.Tex4+I.Tex5+I.Tex6+I.Tex7)/8;
//adjust for aspect ratio
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
I.Tex4 = UVavg + ((I.Tex4 - UVavg) * ratio);
I.Tex5 = UVavg + ((I.Tex5 - UVavg) * ratio);
I.Tex6 = UVavg + ((I.Tex6 - UVavg) * ratio);
I.Tex7 = UVavg + ((I.Tex7 - UVavg) * ratio);
// sample
float4 accum0;
accum0.x = sample(I.Tex0);
accum0.y = sample(I.Tex1);
accum0.z = sample(I.Tex2);
accum0.w = sample(I.Tex3);
float4 accum1;
accum1.x = sample(I.Tex4);
accum1.y = sample(I.Tex5);
accum1.z = sample(I.Tex6);
accum1.w = sample(I.Tex7);
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,1.h/4.h);
final.y = dot(accum1,1.h/4.h);
final.z = dot(accum2,1.h/4.h);
final.w = dot(accum3,1.h/4.h);
// OK
return final;
}
@@ -0,0 +1,80 @@
#include "common.h"
//////////////////////////////////////////////////////////////////////////////////////////
float4 MiddleGray;
//////////////////////////////////////////////////////////////////////////////////////////
// perform 4x4 bilinear, 8x8p, the step (C)
// c): 8x8p => 1x1p with exp
// native bilinear
float sample( float2 tc )
{
float4 data = s_image.Sample( smp_rtlinear, tc );
return dot( data, 1.0/4.0 ); // sum components
}
float4 main ( p_filter I ) : SV_Target
{
float4 ratio = float2( 1/screen_res.x,1/screen_res.y).xyxy;
ratio.x = 1;
//ratio.y = 1.77;
//ratio.y = 0.5625;
ratio.y = screen_res.x/screen_res.y;
//ratio.xyzw = ratio.xyxy;
ratio.xyzw = ratio.xyyx;
float4 UVavg = (I.Tex0+I.Tex1+I.Tex2+I.Tex3+I.Tex4+I.Tex5+I.Tex6+I.Tex7)/8;
//adjust for aspect ratio
I.Tex0 = UVavg + ((I.Tex0 - UVavg) * ratio);
I.Tex1 = UVavg + ((I.Tex1 - UVavg) * ratio);
I.Tex2 = UVavg + ((I.Tex2 - UVavg) * ratio);
I.Tex3 = UVavg + ((I.Tex3 - UVavg) * ratio);
I.Tex4 = UVavg + ((I.Tex4 - UVavg) * ratio);
I.Tex5 = UVavg + ((I.Tex5 - UVavg) * ratio);
I.Tex6 = UVavg + ((I.Tex6 - UVavg) * ratio);
I.Tex7 = UVavg + ((I.Tex7 - UVavg) * ratio);
// sample
float4 accum0;
accum0.x = sample(I.Tex0);
accum0.y = sample(I.Tex1);
accum0.z = sample(I.Tex2);
accum0.w = sample(I.Tex3);
float4 accum1;
accum1.x = sample(I.Tex4);
accum1.y = sample(I.Tex5);
accum1.z = sample(I.Tex6);
accum1.w = sample(I.Tex7);
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,1.0/4.0);
final.y = dot(accum1,1.0/4.0);
final.z = dot(accum2,1.0/4.0);
final.w = dot(accum3,1.0/4.0);
float result = dot(final, 1.0/4.0);
// OK
float scale = MiddleGray.x / (result*MiddleGray.y + MiddleGray.z); // final
float scale_prev = s_tonemap.Sample( smp_nofilter, I.Tex0 ).x;
float rvalue = lerp(scale_prev,scale,MiddleGray.w);
clamp(rvalue, 1.0/128.0, 20.0);
return rvalue;
}
@@ -0,0 +1,36 @@
#include "common.h"
struct v2p
{
float4 color : COLOR0; // rgb. intensity, for SM3 - tonemap prescaled
float2 tc0 : TEXCOORD0;
float2 tc1 : TEXCOORD1;
};
//uniform sampler2D s_clouds0 : register(s0);
//uniform sampler2D s_clouds1 : register(s1);
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) ;
float4 rgb , hi;
#ifdef USE_VTF
float scale = 1;
#else
//float scale = tex2D(s_tonemap,float2(.5h,.5h)).x;
float scale = s_tonemap.Sample(smp_base, float2(.5h,.5h)).x;
#endif
tonemap(rgb, hi, mix, scale );
return float4(rgb.rgb, rgb.a);
}
@@ -0,0 +1,162 @@
#include "anomaly_shaders.h"
#include "common.h"
#include "lmodel.h"
#include "hmodel.h"
#include "mip_fog.h"
Texture2D s_half_depth;
#include "ssao.ps"
#ifdef HDAO
#define USE_HDAO 1
#endif
#ifdef SM_5
Texture2D<float> s_occ;
#endif // SM_5
#if SSAO_QUALITY <=3
#include "ssdo.ps"
#else
#ifndef USE_HDAO
#define USE_HDAO
#endif
#endif
#ifdef USE_HDAO
#if SSAO_QUALITY > 3
#include "ssao_hdao_new.ps"
#endif
#define USE_HDAO_CODE
#if SSAO_QUALITY <=3
#define g_f2RTSize ( screen_res.xy )
#define g_txDepth s_position
#define g_txNormal s_position
#include "ssao_hdao.ps"
#endif
#else // USE_HDAO
#ifdef USE_HBAO
#include "ssao_hbao.ps"
#endif // USE_HBAO
#endif // USE_HDAO
struct _input
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
float2 tcJ : TEXCOORD1; // jitter coords
float4 pos2d : SV_Position;
};
struct _out
{
float4 low : SV_Target0;
float4 high : SV_Target1;
};
// TODO: DX10: Replace Sample with Load
#ifndef MSAA_OPTIMIZATION
_out main ( _input I )
#else
_out main ( _input I, uint iSample : SV_SAMPLEINDEX )
#endif
{
gbuffer_data gbd = gbuffer_load_data( GLD_P(I.tc0, I.pos2d, ISAMPLE) );
// Sample the buffers:
float4 P = float4( gbd.P, gbd.mtl ); // position.(mtl or sun)
float4 N = float4( gbd.N, gbd.hemi ); // normal.hemi
float4 D = float4( gbd.C, gbd.gloss ); // rgb.gloss
#ifndef USE_MSAA
float4 L = s_accumulator.Sample( smp_nofilter, I.tc0); // diffuse.specular
#else
float4 L = s_accumulator.Load( int3( I.tc0 * screen_res.xy, 0 ), ISAMPLE );
#endif
// static sun
float mtl = P.w;
#ifdef USE_R2_STATIC_SUN
float sun_occ = P.w*2;
mtl = xmaterial;
L += SRGBToLinear(D.rgb * Ldynamic_color.rgb * sun_occ) * plight_infinity (mtl, P.xyz, N.xyz, D.xyzw, Ldynamic_dir);
#endif
// Calculate SSAO
#ifdef USE_MSAA
int2 texCoord = I.pos2d;
#endif
float3 occ = float3(1.0,1.0,1.0);
#ifdef USE_HDAO
#ifdef SM_5
#if SSAO_QUALITY > 3
occ = s_occ.Sample( smp_nofilter, I.tc0);
#else // SSAO_QUALITY > 3
occ = calc_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#endif // SSAO_QUALITY > 3
#else // SM_5
#if SSAO_QUALITY > 3
occ = calc_new_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#else // SSAO_QUALITY > 3
occ = calc_hdao( CS_P(P, N, I.tc0, I.tcJ, I.pos2d, ISAMPLE ) );
#endif // SSAO_QUALITY > 3
#endif // SM_5
#else // USE_HDAO
#ifdef USE_HBAO
occ = calc_hbao( P.z, N, I.tc0, I.pos2d );
#else // USE_HBAO
occ = calc_ssdo(P, N, I.tc0, I.pos2d, ISAMPLE).xxx;
#endif
#endif // USE_HDAO
#ifdef SSAO_QUALITY
occ = compute_colored_ao(occ.x, D.xyz);
#endif
occ = SRGBToLinear(occ); //gamma correct
L.rgb += L.a * SRGBToLinear(D.rgb); //illum in alpha
// hemisphere
float3 hdiffuse, hspecular;
hmodel (hdiffuse, hspecular, mtl, N.w, D, P.xyz, N.xyz);
hdiffuse *= occ;
//hspecular *= occ;
float3 color = L.rgb + hdiffuse.rgb;
color = LinearTosRGB(color); //gamma correct
////////////////////////////////////////////////////////////////////////////////
// here should be distance fog
float3 pos = P.xyz;
float distance = length (pos);
float fog = saturate (distance*fog_params.w + fog_params.x); //
color = Calc_Fog(P.xyz, color);
//color = lerp (color,fog_color,fog); //
//float skyblend = saturate(fog);
float skyblend = 0.5;
skyblend = saturate((fog-skyblend)/(1-skyblend));
skyblend = (skyblend*skyblend);
float tm_scale = I.tc0.w; // interpolated from VS
_out o;
tonemap (o.low, o.high, color, tm_scale ) ;
o.low.a = skyblend ;
o.high.a = skyblend ;
return o;
}
@@ -0,0 +1,55 @@
#include "common.h"
// Igor: used for volumetric light
#ifndef USE_MSAA
Texture2D s_vollight;
#else
#ifndef SM_5
Texture2DMS<float4,MSAA_SAMPLES> s_vollight;
#else
Texture2DMS<float4> s_vollight;
#endif
#endif
struct _input
{
float4 tc0 : TEXCOORD0; // tc.xy, tc.w = tonemap scale
};
struct _out
{
float4 low : SV_Target0;
float4 high : SV_Target1;
};
// TODO: DX10: Use load instead of sample
_out main( _input I )
{
// final tone-mapping
float tm_scale = I.tc0.w; // interpolated from VS
_out o;
float4 color;
#ifndef USE_MSAA
color = s_vollight.Load(int3(I.tc0.xy*screen_res.xy, 0));
#else // USE_MSAA
color = s_vollight.Load(int3(I.tc0.xy*screen_res.xy, 0), 0);
[unroll] for(int iSample = 1; iSample < MSAA_SAMPLES; ++iSample)
{
color += s_vollight.Load(int3(I.tc0*screen_res.xy, 0), iSample);
}
color /= MSAA_SAMPLES;
#endif // USE_MSAA
//color.rgb = LinearTosRGB(color.rgb); //gamma correct
//color.a = LinearTosRGB(color.a); //gamma correct
tonemap(o.low, o.high, color, tm_scale );
//o.low.a = 1;
//o.low.a = dot(o.low.rgb, LUMINANCE_VECTOR); //screen blend
//o.high.a = dot(o.high.rgb, LUMINANCE_VECTOR); //screen blend
return o;
}
@@ -0,0 +1,13 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("combine_1", "combine_volumetric")
: fog (false)
: zb (false,false)
: blend (true,blend.invdestcolor,blend.one)
-- : aref (true,0) -- enable to save bandwith?
: sorting (2, false)
shader:dx10texture ("s_vollight", "$user$generic2")
shader:dx10texture ("s_tonemap", "$user$tonemap")
shader:dx10sampler ("smp_nofilter")
end
@@ -0,0 +1,37 @@
/*
Common functions used by lighting
Material table
/////////////////
Anomaly Team 2020
/////////////////
*/
#include "common.h"
////////////////////////
//Material table
//#define MAT_FLORA 6.0
#define MAT_FLORA 0.47451
#define MAT_FLORA_ELIPSON 0.002
////////////////////////
//Simple subsurface scattering
//Author: LVutner
//Do not copy or redistribute without permission.
float SSS(float3 N, float3 V, float3 L)
{
const float SSS_DIST = 0.125; //Scattering distortion
const float SSS_POW = 4; //Scattering power
const float SSS_SCALE = 0.8; //Scattering scale
const float SSS_AMB = 0.05; //Scattering ambient
float3 SSS_vector = normalize(L + N * SSS_DIST);
float SSS_light = pow(saturate(dot(V, -SSS_vector)),SSS_POW); //DICE translucency
SSS_light *= (SSS_POW+2)/(2); //blinn normalize
SSS_light = SSS_light * SSS_SCALE;
//SSS_light += saturate(1-SSS_light) * SSS_AMB;
SSS_light += (1-saturate(dot(N,L))) * SSS_AMB;
return SSS_light;
}
@@ -0,0 +1,368 @@
#ifndef common_functions_h_included
#define common_functions_h_included
#include "srgb.h"
// contrast function
float Contrast(float Input, float ContrastPower)
{
//piecewise contrast function
bool IsAboveHalf = Input > 0.5 ;
float ToRaise = saturate(2*(IsAboveHalf ? 1-Input : Input));
float Output = 0.5*pow(ToRaise, ContrastPower);
Output = IsAboveHalf ? 1-Output : Output;
return Output;
}
float3 vibrance(float3 img, float val )
{
float luminance = dot(float3(img.rgb ), LUMINANCE_VECTOR );
return float3(lerp(luminance, float3(img.rgb ), val ));
}
void tonemap (out float4 low, out float4 high, float3 rgb, float scale)
{
rgb = SRGBToLinear(rgb);
scale = SRGBToLinear(scale);
rgb = rgb*scale;
rgb = LinearTosRGB(rgb);
const float fWhiteIntensity = 11.2;
low = float4(tonemap_sRGB(rgb, fWhiteIntensity ), 0);
high = float4(rgb/def_hdr, 0);
}
void tonemap_hipri (out float4 low, out float4 high, float3 rgb, float scale)
{
tonemap (low, high, rgb, scale);
}
float3 compute_colored_ao(float ao, float3 albedo)
{ //https://www.activision.com/cdn/research/s2016_pbs_activision_occlusion.pptx
float3 a = 2.0404 * albedo - 0.3324;
float3 b = -4.7951 * albedo + 0.6417;
float3 c = 2.7552 * albedo + 0.6903;
return max(ao, ((ao * a + b) * ao + c) * ao);
}
//CUSTOM
float3 blend_soft(float3 a, float3 b)
{
//return 1.0 - (1.0 - a) * (1.0 - b);
//gamma correct and inverse tonemap to add bloom
a = SRGBToLinear(a); //post tonemap render
a = a / max(0.004, 1-a); //inverse tonemap
//a = a / max(0.001, 1-a); //inverse tonemap
b = SRGBToLinear(b); //bloom
a += b; //bloom add
a = a / (1+a) ; //tonemap
a = LinearTosRGB(a);
return a;
}
float4 combine_bloom(float3 low, float4 high)
{
//return float4(low + high*high.a, 1); //add
high.rgb *= high.a;
return float4(blend_soft(low.rgb, high.rgb),1); //screen
}
float calc_fogging(float4 w_pos )
{
return dot(w_pos,fog_plane);
}
float2 unpack_tc_base(float2 tc, float du, float dv )
{
return (tc.xy + float2(du,dv))*(32.0/32768.0); //!Increase from 32bit to 64bit floating point
}
float3 calc_sun_r1(float3 norm_w )
{
return L_sun_color*saturate(dot((norm_w),-L_sun_dir_w));
}
float3 calc_model_hemi_r1(float3 norm_w )
{
return max(0,norm_w.y)*L_hemi_color;
}
float3 calc_model_lq_lighting(float3 norm_w )
{
return L_material.x*calc_model_hemi_r1(norm_w) + L_ambient + L_material.y*calc_sun_r1(norm_w);
}
float3 unpack_normal(float3 v ) { return 2.0*v-1.0; }
float3 unpack_bx2(float3 v ) { return 2.0*v-1.0; }
float3 unpack_bx4(float3 v ) { return 4.0*v-2.0; } //!reduce the amount of stretching from 4*v-2 and increase precision
float2 unpack_tc_lmap(float2 tc ) { return tc*(1.0/32768.0); } // [-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 )
{
// float3 t_lmh = tex2D (s_hemi, tc);
// float3 t_lmh = s_hemi.Sample(smp_rtlinear, tc);
// return dot(t_lmh,1.h/4.h);
float4 t_lmh = s_hemi.Sample(smp_rtlinear, tc);
return t_lmh.a;
}
float get_hemi(float4 lmh)
{
return lmh.a;
}
float get_sun(float4 lmh)
{
return lmh.g;
}
float3 v_hemi(float3 n)
{
return L_hemi_color*(.5f + .5f*n.y);
}
float3 v_sun(float3 n)
{
return L_sun_color*dot(n,-L_sun_dir_w);
}
float3 calc_reflection(float3 pos_w, float3 norm_w )
{
return reflect(normalize(pos_w-eye_position), norm_w);
}
float4 screen_to_proj(float2 screen, float z)
{
float4 proj;
proj.w = 1.0;
proj.z = z;
proj.x = screen.x*2 - proj.w;
proj.y = -screen.y*2 + proj.w;
return proj;
}
float4 convert_to_screen_space(float4 proj)
{
float4 screen;
screen.x = (proj.x + proj.w)*0.5;
screen.y = (proj.w - proj.y)*0.5;
screen.z = proj.z;
screen.w = proj.w;
return screen;
}
float4 proj_to_screen(float4 proj)
{
float4 screen = proj;
screen.x = (proj.x + proj.w);
screen.y = (proj.w - proj.y);
screen.xy *= 0.5;
return screen;
}
float normalize_depth(float depth)
{
return (saturate(depth/100));
}
#ifndef SKY_WITH_DEPTH
float is_sky(float depth)
{
return step(depth, SKY_EPS);
}
float is_not_sky(float depth)
{
return step(SKY_EPS, depth);
}
#else
float is_sky(float depth)
{
return step(abs(depth - SKY_DEPTH), SKY_EPS);
}
float is_not_sky(float depth)
{
return step(SKY_EPS, abs(depth - SKY_DEPTH));
}
#endif
float hash(float2 intro)
{
return frac(1.0e4 * sin(17.0*intro.x + 0.1*intro.y) * (0.1 + abs(sin(13.0*intro.y + intro.x))));
}
float hash3D(float3 intro)
{
return hash(float2(hash(intro.xy),intro.z));
}
float hash12(float2 p)
{
float3 p3 = frac(float3(p.xyx) * .1031);
p3 += dot(p3, p3.yzx + 19.19);
return frac((p3.x + p3.y) * p3.z);
}
float2 hash22(float2 p)
{
float3 p3 = frac(float3(p.xyx) * float3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx+19.19);
return frac((p3.xx+p3.yz)*p3.zy);
}
float rand(float n)
{
return frac(cos(n)*343.42);
}
float noise(float2 tc)
{
return frac(sin(dot(tc, float2(12.0, 78.0) + (timers.x) )) * 43758.0)*0.25f;
}
//////////////////////////////////////////////////////////////////////////
// Aplha to coverage code
#if (defined(MSAA_ALPHATEST_DX10_1_ATOC ) || defined(MSAA_ALPHATEST_DX10_1 ) )
#if MSAA_SAMPLES == 2
uint alpha_to_coverage (float alpha, float2 pos2d )
{
uint mask;
uint pos = uint(pos2d.x) | uint(pos2d.y);
if(alpha < 0.3333 )
mask = 0;
else if(alpha < 0.6666 )
mask = 1 << (pos & 1 );
else
mask = 3;
return mask;
}
#endif
#if MSAA_SAMPLES == 4
uint alpha_to_coverage (float alpha, float2 pos2d )
{
uint mask;
float off = float((uint(pos2d.x) | uint(pos2d.y) ) & 3 );
alpha = saturate(alpha - off * ((0.2 / 4.0 ) / 3.0 ) );
if(alpha < 0.40 )
{
if(alpha < 0.20 )
mask = 0;
else if(alpha < 0.40 ) // only one bit set
mask = 1;
}
else
{
if(alpha < 0.60 ) // 2 bits set => 1100 0110 0011 1001 1010 0101
{
mask = 3;
}
else if(alpha < 0.8 ) // 3 bits set => 1110 0111 1011 1101
mask = 7;
else
mask = 0xf;
}
return mask;
}
#endif
#if MSAA_SAMPLES == 8
uint alpha_to_coverage (float alpha, float2 pos2d )
{
uint mask;
float off = float((uint(pos2d.x) | uint(pos2d.y) ) & 3 );
alpha = saturate(alpha - off * ((0.1111 / 8.0 ) / 3.0 ) );
if(alpha < 0.4444 )
{
if(alpha < 0.2222 )
{
if(alpha < 0.1111 )
mask = 0;
else // only one bit set 0.2222
mask = 1;
}
else
{
if(alpha < 0.3333 ) // 2 bits set0=> 10000001 + 11000000 .. 00000011 : 8 // 0.2222
// set1=> 10100000 .. 00000101 + 10000010 + 01000001 : 8
// set2=> 10010000 .. 00001001 + 10000100 + 01000010 + 00100001 : 8
// set3=> 10001000 .. 00010001 + 10001000 + 01000100 + 00100010 + 00010001 : 8
{
mask = 3;
}
else // 3 bits set0 => 11100000 .. 00000111 + 10000011 + 11000001 : 8 ? 0.4444 // 0.3333
// set1 => 10110000 .. 00001011 + 10000101 + 11000010 + 01100001: 8
// set2 => 11010000 .. 00001101 + 10000110 + 01000011 + 10100001: 8
// set3 => 10011000 .. 00010011 + 10001001 + 11000100 + 01100010 + 00110001 : 8
// set4 => 11001000 .. 00011001 + 10001100 + 01000110 + 00100011 + 10010001 : 8
{
mask = 0x7;
}
}
}
else
{
if(alpha < 0.6666 )
{
if(alpha < 0.5555 ) // 4 bits set0 => 11110000 .. 00001111 + 10000111 + 11000011 + 11100001 : 8 // 0.5555
// set1 => 11011000 .. 00011011 + 10001101 + 11000110 + 01100011 + 10110001 : 8
// set2 => 11001100 .. 00110011 + 10011001 : 4 make 8
// set3 => 11000110 + 01100011 + 10110001 + 11011000 + 01101100 + 00110110 + 00011011 + 10001101 : 8
// set4 => 10111000 .. 00010111 + 10001011 + 11000101 + 11100010 + 01110001 : 8
// set5 => 10011100 .. 00100111 + 10010011 + 11001001 + 11100100 + 01110010 + 00111001 : 8
// set6 => 10101010 .. 01010101 : 2 make 8
// set7 => 10110100 + 01011010 + 00101101 + 10010110 + 01001011 + 10100101 + 11010010 + 01101001 : 8
// set8 => 10011010 + 01001101 + 10100110 + 01010011 + 10101001 + 11010100 + 01101010 + 00110101 : 8
{
mask = 0xf;
}
else // 5 bits set0 => 11111000 01111100 00111110 00011111 10001111 11000111 11100011 11110001 : 8 // 0.6666
// set1 => 10111100 : 8
// set2 => 10011110 : 8
// set3 => 11011100 : 8
// set4 => 11001110 : 8
// set5 => 11011010 : 8
// set6 => 10110110 : 8
{
mask = 0x1F;
}
}
else
{
if(alpha < 0.7777 ) // 6 bits set0 => 11111100 01111110 00111111 10011111 11001111 11100111 11110011 11111001 : 8
// set1 => 10111110 : 8
// set2 => 11011110 : 8
{
mask = 0x3F;
}
else if(alpha < 0.8888 ) // 7 bits set0 => 11111110 :8
{
mask = 0x7F;
}
else // all 8 bits set
mask = 0xFF;
}
}
return mask;
}
#endif
#endif
#endif // common_functions_h_included
@@ -0,0 +1,50 @@
#include "common.h"
#include "sload.h"
f_deffer main ( p_bumped I )
{
f_deffer O;
surface_bumped S = sload (I);
// Sample normal, rotate it by matrix, encode position
float3 Ne = mul (float3x3(I.M1, I.M2, I.M3), S.normal);
Ne = normalize (Ne);
// hemi,sun,material
float ms = xmaterial ;
#ifdef USE_LM_HEMI
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
ms = get_sun(lm);
# endif
#else
/*
//#if defined(SKIN_0) || defined(SKIN_1)|| defined(SKIN_2)|| defined(SKIN_3)|| defined(SKIN_4) //&& !defined(SKIN_NONE)
#ifdef SKIN_4
//#if defined(SKIN_3) || defined(SKIN_4)
//#ifndef SKIN_NONE
// Hemi cube lighting
float3 Nw = mul(m_inv_V, Ne);
float3 hc_pos = hemi_cube_pos_faces.xyz;
float3 hc_neg = hemi_cube_neg_faces.xyz;
float3 hc_mixed = (Nw < 0) ? hc_neg : hc_pos;
float hemi_val = saturate(dot(hc_mixed, abs(Nw)));
float h = hemi_val ;
#else*/
float h = I.position.w ;
//#endif
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
O = pack_gbuffer(
float4 (Ne, h ),
float4 (I.position.xyz + Ne*S.height*def_virtualh, ms ),
// float4 (I.position.xyz, ms),
float4 (S.base.xyz, S.gloss ) );
return O;
}
@@ -0,0 +1,52 @@
#include "common.h"
#include "sload.h"
f_deffer main( p_flat I )
{
f_deffer O;
// diffuse
float3 D = tbase (I.tcdh); // IN: rgb.a
float3 Ne = normalize((float3)I.N.xyz);
#ifdef USE_TDETAIL
// D.rgb = 2*D.rgb*tex2D (s_detail, I.tcdbump).rgb;
D.rgb = 2*D.rgb * s_detail.Sample( smp_base, I.tcdbump ).rgb;
#endif
// hemi,sun,material
float ms = xmaterial ;
#ifdef USE_LM_HEMI
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh );
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
ms = get_sun(lm);
# endif
#else
/*
//#if defined(SKIN_0) || defined(SKIN_1) || defined(SKIN_2) || defined(SKIN_3) || defined(SKIN_4) //SKIN_NONE
#ifdef SKIN_4
// Hemi cube lighting
float3 Nw = mul(m_inv_V, Ne);
float3 hc_pos = hemi_cube_pos_faces.xyz;
float3 hc_neg = hemi_cube_neg_faces.xyz;
float3 hc_mixed = (Nw < 0) ? hc_neg : hc_pos;
float hemi_val = dot( hc_mixed, abs(Nw) );
hemi_val = saturate(hemi_val);
float h = hemi_val ;
#else*/
float h = I.position.w ;
//#endif
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
// 2. Standart output
O = pack_gbuffer(
float4 (Ne , h ),
float4( I.position.xyz + Ne.xyz*def_virtualh/2.h, ms ),
float4( D.rgb, def_gloss ) ); // OUT: rgb.gloss
return O;
}
@@ -0,0 +1,112 @@
#if ( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1) )
#define EXTEND_F_DEFFER
#endif
//add subsurface model for ibl
#include "common.h"
#include "sload.h"
#ifdef ATOC
float4 main ( p_bumped I ) : SV_Target
{
surface_bumped S = sload (I);
S.base.w = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
return S.base;
}
#else // ATOC
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I, float4 pos2d : SV_Position )
#else // MSAA_ALPHATEST_DX10_1_ATOC
f_deffer main ( p_bumped I, float4 pos2d : SV_Position )
#endif // MSAA_ALPHATEST_DX10_1_ATOC
{
f_deffer O;
#if !defined(MSAA_ALPHATEST_DX10_1)
surface_bumped S = sload (I);
#if !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_0_ATOC) )
//float noise = alphatesting(pos2d.xy);
clip(S.base.w-(def_aref));
#endif // !( defined(MSAA_ALPHATEST_DX10_1_ATOC) || defined(MSAA_ALPHATEST_DX10_1_ATOC) )
#ifdef MSAA_ALPHATEST_DX10_1_ATOC
float alpha = (S.base.w-def_aref*0.5f)/(1-def_aref*0.5f);
uint mask = alpha_to_coverage ( alpha, pos2d );
#endif // MSAA_ALPHATEST_DX10_1_ATOC
#else // !defined(MSAA_ALPHATEST_DX10_1)
uint mask = 0x0;
surface_bumped S = sload (I,MSAAOffsets[0]*(1.0/16.0));
if( S.base.w-def_aref >= 0 ) mask |= 0x1;
[unroll] for( int i = 1; i < MSAA_SAMPLES; ++i )
{
surface_bumped SI = sload (I,MSAAOffsets[i]*(1.0/16.0));
if( SI.base.w-def_aref >= 0 ) mask |= ( uint(0x1) << i );
}
if( mask == 0x0 )
discard;
#endif // !defined(MSAA_ALPHATEST_DX10_1)
// Sample normal, rotate it by matrix, encode position
S.normal = float3(0,0,1);
float3 Ne = mul (float3x3(I.M1, I.M2, I.M3), S.normal);
Ne = normalize (Ne);
// hemi,sun,material
float ms = xmaterial ;
//For foliage SSS
//ms = MAT_FLORA;
ms = 0.5;
//green = fresh grass / red = dead grass / make red rougher
S.gloss = 4 * saturate(S.base.g - S.base.r);
S.gloss *= S.gloss;
#ifdef USE_LM_HEMI
// float4 lm = tex2D (s_hemi, I.lmh);
float4 lm = s_hemi.Sample( smp_rtlinear, I.lmh);
//float h = dot (lm.rgb,1.h/3.h);
float h = get_hemi(lm);
# ifdef USE_R2_STATIC_SUN
// ms = lm.w;
ms = get_sun(lm);
# endif
#else
float h = I.position.w ;
# ifdef USE_R2_STATIC_SUN
ms = I.tcdh.w ;
# endif
#endif
#ifndef EXTEND_F_DEFFER
O = pack_gbuffer(
float4(Ne, h),
float4(I.position.xyz, ms),
float4(S.base.xyz, S.gloss)//,
//float4(0,0,0,0)
);
#else
O = pack_gbuffer(
float4(Ne, h),
float4(I.position.xyz, ms),
float4(S.base.xyz, S.gloss),
//float4(0,0,0,0),
mask );
#endif
return O ;
}
#endif // ATOC
@@ -0,0 +1,108 @@
#include "common.h"
float4 consts; // {1/quant,1/quant,diffusescale,ambient}
float4 wave; // cx,cy,cz,tm
float4 dir2D;
float4 array[61*4];
/*
Updated grass shader
-Supports normal mapping
-Simple SSS approx. (Spherical normals)
Credits:
-Zagolski - Faster normal mapping code
Keep this header in, and put credits onto your mod page.
Thanks.
*/
v2p_bumped main (v_detail v)
{
v2p_bumped O;
// index
int i = v.misc.w;
float4 m0 = array[i+0];
float4 m1 = array[i+1];
float4 m2 = array[i+2];
float4 c0 = array[i+3];
// Transform pos to world coords
float4 pos;
pos.x = dot(m0, v.pos);
pos.y = dot(m1, v.pos);
pos.z = dot(m2, v.pos);
pos.w = 1;
//Wave effect
float base = m1.w;
float dp = calc_cyclic (dot(pos,wave));
float H = pos.y - base; // height of vertex (scaled)
float frac = v.misc.z*consts.x; // fractional
float inten = H * dp;
float2 result = calc_xz_wave(dir2D.xz*inten,frac);
pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
float3 flatN = float3(0,1,0); //vertical normal
//
float3 VertPosN1 = float3(0,H,0); //vertical pos
float3 VertPosN2 = float3(result.x,0,result.y); //offset pos
float3 VertPosN3 = normalize(VertPosN1 + VertPosN2); //normal from offset from base
float3 baseP = float3(m0.w,m1.w,m2.w); //base world space position
float3 VertPosN4 = normalize(pos - baseP); //normal from offset from base
//
float3 sphereOffset = float3(0.00, 1.00, 0.00);
sphereOffset += 10 * float3(-result.x, 0.0, -result.y);
float3 sphereScale = float3(1.0, 2.0, 1.0);
float3 sphereN = normalize(sphereScale * v.pos.xyz + sphereOffset); //Spherical normals trick
float3 camFacingN = normalize((mul(m_W, pos) - eye_position.xyz) * float3(-1,0,-1));
float3 folaigeN = lerp(camFacingN, VertPosN4, saturate(H)); //roots face the camera, the tips face the sky
//float3 folaigeN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
folaigeN.xz *= 0.5;;
folaigeN.y = sqrt(1 - saturate(dot(folaigeN.xz, folaigeN.xz)));
folaigeN = normalize(folaigeN);
//tangent basis
float3 N = folaigeN;
float3 B = float3(0,0,1);
if (abs(dot(N, B)) > 0.99f) B = float3(0,1,0);
float3 T = normalize(cross(N, B));
//TBN matrix
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];
// Final out
float4 Pp = mul(m_WVP, pos);
O.hpos = Pp;
float3 Pe = mul(m_WV, pos);
O.tcdh = float4((v.misc * consts).xyyy);
#if defined(USE_R2_STATIC_SUN)
O.tcdh.w = c0.x; // (,,,dir-occlusion)
#endif
O.position = float4(Pe, c0.w);
return O;
}
FXVS;
@@ -0,0 +1,154 @@
#define USE_TDETAIL
#include "common.h"
#define PARALLAX_NEAR_PLANE 0.01
#define PARALLAX_FAR_PLANE 35
#define PARALLAX_DEPTH 0.02
//Height maps
Texture2D s_dnE_r;
Texture2D s_dnE_g;
Texture2D s_dnE_b;
Texture2D s_dnE_a;
struct surface {
float4 base;
float3 normal;
float gloss;
};
void perform_tc_offset(inout p_bumped p, in Texture2D s_bumpX_new)
{
if ((p.position.z > PARALLAX_NEAR_PLANE) && (p.position.z < PARALLAX_FAR_PLANE))
{
float3 eye = normalize(mul(float3x3(p.M1.x, p.M2.x, p.M3.x,
p.M1.y, p.M2.y, p.M3.y,
p.M1.z, p.M2.z, p.M3.z), -p.position));
// steps minmax and refines minmax
int4 steps = int4(8, 24, 4, 8); // 3..10, 7..16
bool need_disp_lerp = true;
bool need_refine = true;
float view_angle = abs(dot(float3(0.0, 0.0, 1.0), eye));
float layer_step = rcp(lerp(steps.y, steps.x, view_angle));
//float2 tc_step = layer_step * eye.xy * PARALLAX_DEPTH;
float2 tc_step = layer_step * eye.xy * (parallax.x);
float2 displaced_tc = p.tcdbump;
float curr_disp, curr_layer = 0.0;
do
{
displaced_tc -= tc_step;
curr_disp = 1 - s_bumpX_new.SampleLevel(smp_base, displaced_tc, 0).w;
curr_layer += layer_step;
} while (curr_layer < curr_disp);
if (need_refine)
{
displaced_tc += tc_step;
curr_layer -= layer_step;
float refine_steps = lerp(steps.w, steps.z, view_angle);
tc_step /= refine_steps;
layer_step /= refine_steps;
do
{
displaced_tc -= tc_step;
curr_disp = 1.0 - s_bumpX_new.SampleLevel(smp_base, displaced_tc, 0).w;
curr_layer += layer_step;
} while (curr_layer < curr_disp);
}
if (need_disp_lerp)
{
float2 displaced_tc_prev = displaced_tc + tc_step;
float after_depth = curr_disp - curr_layer;
float before_depth = 1.0 - s_bumpX_new.SampleLevel(smp_base, displaced_tc_prev, 0).w - curr_layer + layer_step;
float weight = after_depth / (after_depth - before_depth);
displaced_tc = lerp(displaced_tc, displaced_tc_prev, weight);
}
p.tcdbump = displaced_tc;
}
}
surface fill(p_bumped p, Texture2D s_base_det, Texture2D s_bump_det, Texture2D s_bumpX_det, uint need_mask, float mask)
{
surface S;
mask = need_mask ? mask : 1;
if (mask <= 0)
{
S.base = (0.0, 0.0, 0.0, 0.0);
S.gloss = 0.0;
S.normal = (0.0, 0.0, 0.0);
return S;
}
perform_tc_offset(p, s_base_det);
S.base = s_base_det.Sample(smp_base, p.tcdbump) * mask;
float4 Nu = s_bump_det.Sample(smp_base, p.tcdbump);
float4 NuX = s_bumpX_det.Sample(smp_base, p.tcdbump);
S.gloss = Nu.x * mask;
float3 Norm = 2 * Nu.wzy - 1;
//float3 Error = 2 * NuX.xyz - 1;
//S.normal = (Norm + Error) * mask; //no error correction on terrain?
S.normal = Norm * mask;
return S;
}
f_deffer main(p_bumped I)
{
float4 C = s_base.Sample(smp_base, I.tcdh.xy);
float4 mask = s_mask.Sample(smp_base, I.tcdh.xy);
mask /= dot(mask, 1.0);
surface Sr = fill(I, s_dt_r, s_dn_r, s_dnE_r, 1, mask.r);
surface Sg = fill(I, s_dt_g, s_dn_g, s_dnE_g, 1, mask.g);
surface Sb = fill(I, s_dt_b, s_dn_b, s_dnE_b, 1, mask.b);
surface Sa = fill(I, s_dt_a, s_dn_a, s_dnE_a, 1, mask.a);
float3 mixedN = Sr.normal + Sg.normal + Sb.normal + Sa.normal;
//mixedN.x *= -1;
//mixedN.y *= -1;
mixedN.z = sqrt(1 - saturate(dot(mixedN.xy, mixedN.xy)));
mixedN = normalize(mixedN);
float4 Ne = float4(mul(float3x3(I.M1, I.M2, I.M3), mixedN), C.w);
Ne.xyz = normalize(Ne.xyz);
C.xyz *= (Sr.base.xyz + Sg.base.xyz + Sb.base.xyz + Sa.base.xyz) * 2.0;
float G = Sr.gloss + Sg.gloss + Sb.gloss + Sa.gloss;
#ifdef USE_R2_STATIC_SUN
float ms = s_lmap.Sample(smp_base, I.tcdh.xy).w;
#else
float ms = xmaterial;
#endif
return pack_gbuffer(
Ne, // normal.hemi
float4(I.position.xyz, ms), // depth.( mtl or sun )
float4(C.rgb, G) // color.gloss
);
}
@@ -0,0 +1,104 @@
#include "common.h"
uniform float3x4 m_xform ;
uniform float3x4 m_xform_v ;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
v2p_bumped main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
// Transform to world coords
float3 pos = mul (m_xform, I.P);
//
float base = m_xform._24 ; // take base height from matrix
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float H = pos.y - base ; // height of vertex (scaled, rotated, etc.)
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 result = calc_xz_wave (wind.xz*inten, frac);
#ifdef USE_TREEWAVE
result = 0;
#endif
float4 w_pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
float2 tc = (I.tc * consts).xy;
float hemi = I.Nh.w * c_scale.w + c_bias.w;
// float hemi = I.Nh.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_V, w_pos );
//float3 Pe = mul(m_V, float4(pos.xyz,1));
O.tcdh = float4 (tc.xyyy );
O.hpos = mul (m_VP, w_pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
O.tcdh.w = suno; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
//Normal mapping
float3 N = unpack_bx2(I.Nh); // just scale (assume normal in the -.5f, .5f)
float3 sphereOffset = float3(0.1, 1.0, 0.2);
float3 sphereScale = float3(1.0, 2.0, 1.0);
float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); //Spherical normals trick
float3 T = unpack_bx2(I.T); //
float3 B = unpack_bx2(I.B); //
N = normalize(N);
B = normalize(B);
T = normalize(T);
//tangent basis
float3 flatB = float3(0,0,1);
if (abs(dot(sphereN, flatB)) > 0.99f)
flatB = float3(0,1,0);
float3 flatT = normalize(cross(sphereN, flatB));
flatB = normalize(cross(sphereN, flatT));
//foliage
float foliageMat = 0.5; //foliage
//float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
float foliageMask = (abs(xmaterial-foliageMat) >= 0.2) ? 1 : 0; //foliage
//float foliageMask = 1; //foliage
N = normalize(lerp(N, sphereN, foliageMask)); //blend to foliage normals
//B = normalize(lerp(B, flatB, foliageMask)); //blend to foliage normals
//T = normalize(lerp(T, flatT, foliageMask)); //blend to foliage normals
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
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
return O;
}
FXVS;
@@ -0,0 +1,75 @@
#include "common.h"
uniform float3x4 m_xform;
uniform float3x4 m_xform_v;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
v2p_flat main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
v2p_flat o;
// Transform to world coords
float3 pos = mul (m_xform, I.P);
//
float base = m_xform._24; // take base height from matrix
float dp = calc_cyclic (wave.w+dot(pos,(float3)wave));
float H = pos.y - base; // height of vertex (scaled, rotated, etc.)
float frac = I.tc.z*consts.x; // fractional (or rigidity)
float inten = H * dp; // intensity
float2 result = calc_xz_wave (wind.xz*inten, frac);
#ifdef USE_TREEWAVE
result = 0;
#endif
float4 f_pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
//Normal mapping
float3 N = unpack_bx2(I.Nh);
float3 sphereOffset = float3(0.0, 1.0, 0.0);
float3 sphereScale = float3(1.0, 2.0, 1.0);
float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); //Spherical normals trick
float3 flatN = (float3(0, 1, 0));
/*
float3 camFacingN = normalize((f_pos - eye_position.xyz) * float3(-1,0,-1));
sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
sphereN.xz *= 0.5;
sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
sphereN = normalize(sphereN);
*/
//foliage
float foliageMat = 0.5; //foliage
//float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
float foliageMask = (abs(xmaterial-foliageMat) >= 0.2) ? 1 : 0; //foliage
//float foliageMask = 1; //foliage
N = normalize(lerp(N, sphereN, foliageMask)); //blend to foliage normals
// Final xform(s)
// Final xform
float3 Pe = mul (m_V, f_pos );
//float3 Pe = mul(m_V, float4(pos.xyz,1));
float hemi = I.Nh.w*c_scale.w + c_bias.w;
//float hemi = I.Nh.w;
o.hpos = mul (m_VP, f_pos );
o.N = mul((float3x3)m_xform_v, N);
o.tcdh = float4 ((I.tc * consts).xyyy );
o.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
o.tcdh.w = suno; // (,,,dir-occlusion)
#endif
#ifdef USE_TDETAIL
o.tcdbump = o.tcdh*dt_params; // dt tc
#endif
return o;
}
FXVS;
@@ -0,0 +1,105 @@
#include "common.h"
uniform float3x4 m_xform ;
uniform float3x4 m_xform_v ;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
v2p_bumped main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
// Transform to world coords
float3 pos = mul (m_xform, I.P);
float H = I.P;
//
float2 result = 0;
float4 w_pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
float2 tc = (I.tc * consts).xy;
float hemi = I.Nh.w * c_scale.w + c_bias.w;
// float hemi = I.Nh.w;
// Eye-space pos/normal
v2p_bumped O;
float3 Pe = mul (m_V, w_pos );
//float3 Pe = mul(m_V, float4(pos.xyz,1));
O.tcdh = float4 (tc.xyyy );
O.hpos = mul (m_VP, w_pos );
O.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
O.tcdh.w = suno; // (,,,dir-occlusion)
#endif
// Calculate the 3x3 transform from tangent space to eye-space
// TangentToEyeSpace = object2eye * tangent2object
// = object2eye * transpose(object2tangent) (since the inverse of a rotation is its transpose)
float3 N = unpack_bx2(I.Nh); // just scale (assume normal in the -.5f, .5f)
float3 T = unpack_bx2(I.T); //
float3 B = unpack_bx2(I.B); //
N = normalize(N);
B = normalize(B);
T = normalize(T);
float3 sphereOffset = float3(0.0, 1.0, 0.0);
float3 sphereScale = float3(1.0, 2.0, 1.0);
float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); //Spherical normals trick
/*
float3 camFacingN = normalize((w_pos - eye_position.xyz) * float3(-1,0,-1));
sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
sphereN.xz *= 0.5;
sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
sphereN = normalize(sphereN);
*/
//tangent basis
float3 flatB = float3(0,0,1);
if (abs(dot(sphereN, flatB)) > 0.99f)
flatB = float3(0,1,0);
float3 flatT = normalize(cross(sphereN, flatB));
flatB = normalize(cross(sphereN, flatT));
//foliage
float foliageMat = 0.5; //foliage
//float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
float foliageMask = (abs(xmaterial-foliageMat) >= 0.2) ? 1 : 0; //foliage
//float foliageMask = 1; //foliage
N = normalize(lerp(N, sphereN, foliageMask)); //blend to foliage normals
//B = normalize(lerp(B, flatB, foliageMask)); //blend to foliage normals
//T = normalize(lerp(T, flatT, foliageMask)); //blend to foliage normals
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
));
// The pixel shader operates on the bump-map in [0..1] range
// Remap this range in the matrix, anyway we are pixel-shader limited :)
// ...... [ 2 0 0 0]
// ...... [ 0 2 0 0]
// ...... [ 0 0 2 0]
// ...... [-1 -1 -1 1]
// issue: strange, but it's slower :(
// issue: interpolators? dp4? VS limited? black magic?
// Feed this transform to pixel shader
O.M1 = xform[0];
O.M2 = xform[1];
O.M3 = xform[2];
#ifdef USE_TDETAIL
O.tcdbump = O.tcdh * dt_params; // dt tc
#endif
return O;
}
FXVS;
@@ -0,0 +1,67 @@
#include "common.h"
uniform float3x4 m_xform;
uniform float3x4 m_xform_v;
uniform float4 consts; // {1/quant,1/quant,???,???}
uniform float4 c_scale,c_bias,wind,wave;
uniform float2 c_sun; // x=*, y=+
v2p_flat main (v_tree I)
{
I.Nh = unpack_D3DCOLOR(I.Nh);
I.T = unpack_D3DCOLOR(I.T);
I.B = unpack_D3DCOLOR(I.B);
v2p_flat o;
// Transform to world coords
float3 pos = mul (m_xform, I.P);
float H = I.P;
//
float2 result = 0;
float4 f_pos = float4(pos.x+result.x, pos.y, pos.z+result.y, 1);
//Normal mapping
float3 N = unpack_bx2(I.Nh);
float3 sphereOffset = float3(0.0, 1.0, 0.0);
float3 sphereScale = float3(1.0, 2.0, 1.0);
float3 sphereN = normalize(sphereScale * I.P.xyz + sphereOffset); //Spherical normals trick
float3 flatN = (float3(0, 1, 0));
/*
float3 camFacingN = normalize((f_pos - eye_position.xyz) * float3(-1,0,-1));
sphereN = lerp(camFacingN, sphereN, saturate(H)); //roots face the camera, the tips face the sky
sphereN.xz *= 0.5;
sphereN.y = sqrt(1 - saturate(dot(sphereN.xz, sphereN.xz)));
sphereN = normalize(sphereN);
*/
//foliage
float foliageMat = 0.5; //foliage
//float foliageMask = saturate(abs(xmaterial-foliageMat)-0.02); //foliage
float foliageMask = (abs(xmaterial-foliageMat) >= 0.2) ? 1 : 0; //foliage
//float foliageMask = 1; //foliage
N = normalize(lerp(N, sphereN, foliageMask)); //blend to foliage normals
// Final xform(s)
float3 Pe = mul (m_V, f_pos );
//float3 Pe = mul(m_V, float4(pos.xyz,1));
float hemi = I.Nh.w*c_scale.w + c_bias.w;
//float hemi = I.Nh.w;
o.hpos = mul (m_VP, f_pos );
o.N = mul ((float3x3)m_xform_v, N );
o.tcdh = float4 ((I.tc * consts).xyyy );
o.position = float4 (Pe, hemi );
#if defined(USE_R2_STATIC_SUN) && !defined(USE_LM_HEMI)
float suno = I.Nh.w * c_sun.x + c_sun.y ;
o.tcdh.w = suno; // (,,,dir-occlusion)
#endif
#ifdef USE_TDETAIL
o.tcdbump = o.tcdh*dt_params; // dt tc
#endif
return o;
}
FXVS;
@@ -0,0 +1,15 @@
--Normal pass, with bumpmapping
function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_grass","deffer_grass")
: fog (false)
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
shader:dx10texture("s_base", t_base)
shader:dx10texture("s_bump", t_base.."_bump")
shader:dx10texture("s_bumpX", t_base.."_bump#")
shader:dx10sampler("smp_base")
end
@@ -0,0 +1,126 @@
#ifndef HMODEL_H
#define HMODEL_H
#define CUBE_MIPS 6 //mipmaps for ambient shading and specular
#include "pbr_cubemap_check.h"
//gamma correction is set up to be semi gamma correct
TextureCube env_s0;
TextureCube env_s1;
uniform float4 env_color; // color.w = lerp factor
float4 hmodel_stuff; //x - hemi vibrance // y - hemi contrast // z - wet surface factor
void hmodel
(
out float3 hdiffuse, out float3 hspecular,
float m, float h, float4 alb_gloss, float3 Pnt, float3 normal
)
{
//PBR style
float3 albedo = calc_albedo(alb_gloss, m);
float3 specular = calc_specular(alb_gloss, m);
float rough = calc_rough(alb_gloss, m);
calc_rain(albedo, specular, rough, alb_gloss, m, h);
calc_foliage(albedo, specular, rough, alb_gloss, m);
float roughCube = rough;
//float roughCube = sqrt(rough); //cubemap mipmaps (brdf too?)
//float RoughMip = roughCube * CUBE_MIPS;
float RoughMip = CUBE_MIPS - ((1 - roughCube) * CUBE_MIPS);
//normal vector
normal = normalize(normal);
float3 nw = mul(m_inv_V, normal);
//nw = normalize(nw);
//view vector
Pnt = normalize(Pnt);
float3 v2Pnt = mul(m_inv_V, Pnt);
//v2Pnt = normalize(v2Pnt);
//normal remap
float3 nwRemap = nw;
float3 vnormabs = abs(nwRemap);
float vnormmax = max(vnormabs.x, max(vnormabs.y, vnormabs.z));
nwRemap /= vnormmax;
if (nwRemap.y < 0.999) nwRemap.y = nwRemap.y*2-1; // fake remapping
//reflection vector
float3 vreflect= reflect(v2Pnt, nw );
//reflect remap
float3 vreflectRemap = vreflect;
float3 vreflectabs = abs(vreflectRemap);
float vreflectmax = max(vreflectabs.x, max(vreflectabs.y, vreflectabs.z));
vreflectRemap /= vreflectmax;
if (vreflectRemap.y < 0.999) vreflectRemap.y = vreflectRemap.y*2-1; //fake remapping
//normalize
nwRemap = normalize(nwRemap);
vreflectRemap = normalize(vreflectRemap);
//DICE reflection vector roughness
vreflectRemap = getSpecularDominantDir(nwRemap, vreflectRemap, rough);
//Valve style ambient cube to prevent seams
const float Epsilon = 0.001;
float3 nSquared = nw * nw;
float3 e0d = 0;
e0d += nSquared.x * (env_s0.SampleLevel(smp_base, float3(nwRemap.x, Epsilon, Epsilon), CUBE_MIPS).rgb);
e0d += nSquared.y * (env_s0.SampleLevel(smp_base, float3(Epsilon, nwRemap.y, Epsilon), CUBE_MIPS).rgb);
e0d += nSquared.z * (env_s0.SampleLevel(smp_base, float3(Epsilon, Epsilon, nwRemap.z), CUBE_MIPS).rgb);
//e0d = LinearTosRGB(e0d);
//e0d = env_s0.SampleLevel(smp_base, nwRemap, CUBE_MIPS);
float3 e1d = 0;
e1d += nSquared.x * (env_s1.SampleLevel(smp_base, float3(nwRemap.x, Epsilon, Epsilon), CUBE_MIPS).rgb);
e1d += nSquared.y * (env_s1.SampleLevel(smp_base, float3(Epsilon, nwRemap.y, Epsilon), CUBE_MIPS).rgb);
e1d += nSquared.z * (env_s1.SampleLevel(smp_base, float3(Epsilon, Epsilon, nwRemap.z), CUBE_MIPS).rgb);
//e1d = LinearTosRGB(e1d);
//e1d = env_s1.SampleLevel(smp_base, nwRemap, CUBE_MIPS);
//specular color
float3 e0s = env_s0.SampleLevel( smp_base, vreflectRemap, RoughMip );
float3 e1s = env_s1.SampleLevel( smp_base, vreflectRemap, RoughMip );
//lerp
float3 env_d = lerp(e0d, e1d, env_color.w);
float3 env_s = lerp(e0s, e1s, env_color.w);
// hscale - something like diffuse reflection
float hscale = h; //. * (.5h + .5h*nw.y);
float hspec = .5h + .5h * dot( vreflect, v2Pnt);
//TODO - make hscale normal mapped
float4 light = float4(hscale, hscale, hscale, hscale);
//float4 light = s_material.SampleLevel( smp_material, float3( hscale, hspec, m ), 0 ).xxxy;
//tint color
//float3 env_col = 1.0;
float3 env_col = env_color.rgb;
//float3 env_col = fog_color.rgb * 2.0;
env_d *= env_col;
env_s *= env_col;
//lightmap ambient
env_d *= light.xxx;
env_s *= light.www;
//ambient color
float3 amb_col = L_ambient.rgb;
env_d += amb_col;
env_s += amb_col; //*(env_s/env_d);
env_d = SRGBToLinear(env_d);
env_s = SRGBToLinear(env_s); //gamma correct
hdiffuse = Amb_BRDF(rough, albedo, specular, env_d, env_s, -v2Pnt, nw ).rgb;
hspecular = 0; //do not use hspec at all
}
#endif
@@ -0,0 +1,96 @@
#ifndef LMODEL_H
#define LMODEL_H
#include "common.h"
#include "common_brdf.h"
#include "pbr_brdf.h"
//////////////////////////////////////////////////////////////////////////////////////////
// Lighting formulas
float4 compute_lighting(float3 N, float3 V, float3 L, float4 alb_gloss, float mat_id)
{
float3 albedo = calc_albedo(alb_gloss, mat_id);
float3 specular = calc_specular(alb_gloss, mat_id);
float rough = calc_rough(alb_gloss, mat_id);
//calc_rain(albedo, specular, rough, alb_gloss, mat_id, 1);
calc_foliage(albedo, specular, rough, alb_gloss, mat_id);
float3 light = Lit_BRDF(rough, albedo, specular, V, N, L );
//if(mat_id == MAT_FLORA) //Be aware of precision loss/errors
if(abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) //Be aware of precision loss/errors
{
//Simple subsurface scattering
float subsurface = SSS(N,V,L);
light.rgb += subsurface*albedo;
}
return float4(light, 0);
}
float4 plight_infinity(float m, float3 pnt, float3 normal, float4 c_tex, float3 light_direction )
{
//gsc vanilla stuff
float3 N = normalize(normal); // normal
float3 V = normalize(-pnt); // vector2eye
float3 L = normalize(-light_direction); // vector2light
float4 light = compute_lighting(N,V,L,c_tex,m);
return light; // output (albedo.gloss)
}
float4 plight_local(float m, float3 pnt, float3 normal, float4 c_tex, float3 light_position, float light_range_rsq, out float rsqr )
{
float atteps = 0.1;
float3 L2P = pnt - light_position; // light2point
rsqr = dot(L2P,L2P); // distance 2 light (squared)
rsqr = max(rsqr, atteps);
//rsqr = rsqr + 1.0;
//vanilla atten - linear
float att = saturate(1.0 - rsqr*light_range_rsq); // q-linear attenuate
att = SRGBToLinear(att);
/*
//unity atten - quadtratic
//catlikecoding.com/unity/tutorials/custom-srp/point-and-spot-lights/
att = rsqr * light_range_rsq;
att *= att;
att = saturate(1.0 - att);
att *= att;
att = att / rsqr;
*/
float3 N = normalize(normal); // normal
float3 V = normalize(-pnt); // vector2eye
float3 L = normalize(-L2P); // vector2light
float4 light = compute_lighting(N,V,L,c_tex,m);
return att*light; // output (albedo.gloss)
}
float3 specular_phong(float3 pnt, float3 normal, float3 light_direction)
{
float3 H = normalize(pnt + light_direction );
float nDotL = saturate(dot(normal, light_direction));
float nDotH = saturate(dot(normal, H));
float nDotV = saturate(dot(normal, pnt));
float lDotH = saturate(dot(light_direction, H));
//float vDotH = saturate(dot(pnt, H));
return L_sun_color.rgb * Lit_Specular(nDotL, nDotH, nDotV, lDotH, 0.02, 0.1);
}
// TODO: DX10: Remove path without blending
half4 blendp(half4 value, float4 tcp)
{
return value;
}
half4 blend(half4 value, float2 tc)
{
return value;
}
#endif
@@ -0,0 +1,122 @@
//=================================================================================================
//Mip Fog for STALKER Anomaly
//Inspired by Uncharted 4
//=================================================================================================
#define HEIGHTFOGMAX 50
#define HEIGHTFOGMIN -75
#define FOGMAXSHARPNESS 0.995
#define FOGROUGHCURVE 1.5
#define MIPFOGAMOUNT 1.0
#define SUNFOGAMOUNT 0.25
#define MINFOGDENSITY 0.2
#define MAXFOGDENSITY 5.0
#define HEIGHTFOGCURVE 5
//=================================================================================================
float Calc_Exponent(float a)
{
return 1 / (pow(2, a));
}
float Calc_Height(float3 wpos)
{
return 1 - saturate((wpos.y - HEIGHTFOGMIN) / (HEIGHTFOGMAX-HEIGHTFOGMIN));
}
float Calc_FinalFog(float fog, float height)
{
float HeightLerp = pow(height, HEIGHTFOGCURVE);
/*
float CamHeight = Calc_Height(eye_position);
float CamLerp = pow(CamHeight, HEIGHTFOGCURVE);
//HeightLerp = max(HeightLerp, CamLerp);
HeightLerp = (HeightLerp * (1-CamLerp)) + CamLerp;
*/
float Fog = Calc_Exponent(fog * lerp(MINFOGDENSITY, MAXFOGDENSITY, HeightLerp));
return saturate(1 - Fog);
}
float3 Calc_SunFog(float3 pos, float3 fogrough)
{
float3 SunFog = saturate(dot(normalize(Ldynamic_dir), -normalize(pos)));
float gloss = lerp(FOGMAXSHARPNESS*0.5, 0, fogrough);
gloss = gloss*gloss;
gloss = pow(8192, gloss);
SunFog = pow(SunFog, gloss) * ((gloss + 2)/(8 * PI)); //BLOPS2 blinn
SunFog *= SRGBToLinear(Ldynamic_color.rgb);
return SunFog * SUNFOGAMOUNT;
}
float3 Calc_MipFog(float3 sky, float3 fogrough)
{
sky = normalize(sky);
//cubemap projection
float3 skyabs = abs(sky);
float skymax = max(skyabs.x, max(skyabs.y, skyabs.z));
sky /= skymax;
if (sky.y < 0.999)
sky.y = sky.y*2-1; //fake remapping
sky = normalize(sky);
float FogMip = lerp(CUBE_MIPS - (CUBE_MIPS * FOGMAXSHARPNESS), CUBE_MIPS, fogrough); //don't use base mip
float3 s0 = env_s0.SampleLevel(smp_base, sky, FogMip);
float3 s1 = env_s1.SampleLevel(smp_base, sky, FogMip);
float3 MipFog = lerp(s0,s1,env_color.w);
//srgb tint
float3 FogTint = lerp(fog_color.rgb * 2.0, env_color.rgb, fogrough*fogrough); //env for close, fog for far
MipFog *= FogTint;
//linear cubemap
MipFog = SRGBToLinear(MipFog);
return MipFog * MIPFOGAMOUNT;
}
float3 Calc_Fog(float3 pos, float3 color)
{
color = SRGBToLinear(color.rgb);
//view to world space
float3 sky = mul(m_inv_V, pos );
float3 wpos = sky + eye_position;
float distance = length(pos);
float fog = saturate(distance * fog_params.w + fog_params.x);
float height = Calc_Height(wpos);
float FinalFog = Calc_FinalFog(fog, height);
float fogrough = fog;
fogrough = pow(1 - fogrough , FOGROUGHCURVE);
float3 MipFog = Calc_MipFog(sky, fogrough);
float3 SunFog = Calc_SunFog(pos, fogrough);
float3 FogColor = MipFog + SunFog;
//fog blend
float3 FogBlend = FinalFog;
//fog alpha
float fogalpha = fog * fog;
FogBlend *= 1 - fogalpha;
FogBlend += fogalpha;
float3 Final = lerp(color, FogColor, FogBlend);
Final = LinearTosRGB(Final);
return Final;
}
@@ -0,0 +1,27 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_model_flat","deffer_base_flat")
: fog (false)
: emissive (true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
--shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
-- shader:begin ("shadow_direct_model", "accum_emissive")
shader:begin ("deffer_model_flat", "accum_emissive")
: zb (true,false)
: fog (false)
: emissive (true)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
--shader: dx10color_write_enable( true, true, true, true)
end
@@ -0,0 +1,28 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_model_flat","deffer_base_flat")
: fog (false)
: emissive (true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
--shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
-- shader:begin ("shadow_direct_model", "accum_emissivel")
shader:begin ("deffer_model_flat", "accum_emissivel")
: zb (true,false)
: fog (false)
: emissive (true)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
--shader: dx10color_write_enable( true, true, true, false)
--shader: dx10color_write_enable( true, true, true, true)
end
@@ -0,0 +1,27 @@
function normal (shader, t_base, t_second, t_detail)
shader:begin ("deffer_model_flat","deffer_base_flat")
: fog (false)
: emissive (true)
-- shader:sampler ("s_base") :texture (t_base)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
shader:dx10stencil ( true, cmp_func.always,
255 , 127,
stencil_op.keep, stencil_op.replace, stencil_op.keep)
shader:dx10stencil_ref (1)
--shader: dx10color_write_enable( true, true, true, false)
end
function l_special (shader, t_base, t_second, t_detail)
-- shader:begin ("shadow_direct_model", "accum_emissivel")
shader:begin ("deffer_model_flat", "accum_emissivel")
: zb (true,false)
: fog (false)
: emissive (true)
shader:dx10texture ("s_base", t_base)
shader:dx10sampler ("smp_base")
--shader: dx10color_write_enable( true, true, true, true)
end
@@ -0,0 +1,285 @@
//=================================================================================================
//Pseudo PBR shading for STALKER Anomaly
//Roughness is controlled with r2_gloss_min
//=================================================================================================
#include "pbr_settings.h" //load settings files
#define PI 3.14159265359
//=================================================================================================
//Metalness
//
float calc_metalness(float4 alb_gloss, float material_ID)
{
//material ID experiment
float metallerp = max(0.0, (material_ID*4)-0.5)/4; //approx material + weight? //nowhere near
//metallerp = saturate((metallerp - 0.5) * 2); //metal threshold
//metallerp = saturate(((metallerp * 4) - 2) * 0.5); //metal threshold
//binary metalness
float metalness = saturate(material_ID - 0.75 - 0.001) > 0 ? 1 : 0;
//float metal_thres = METALNESS_THRESHOLD;
//float metal_soft = METALNESS_SOFTNESS;
//float metal_thres = METALNESS_THRESHOLD * (1 - metallerp) * 2;
float metal_thres = pow(METALNESS_THRESHOLD, exp2(metallerp));
float metal_soft = metal_thres * 0.9;
//lerp on gloss
//metalness *= saturate(smoothstep(METALNESS_THRESHOLD-METALNESS_SOFTNESS, METALNESS_THRESHOLD+METALNESS_SOFTNESS, alb_gloss.a));
metalness *= saturate((alb_gloss.a - (metal_thres-metal_soft)) / ((metal_thres+metal_soft) - (metal_thres-metal_soft)));
return metalness;
}
float3 Soft_Light (float3 base, float3 blend)
{
return (blend <= 0.5) ? base - (1-2*blend)*base*(1-base) : base + (2*blend-1)*(sqrt(base)-base);
}
//=================================================================================================
//Material
//
float3 calc_albedo_boost(float3 albedo)
{
float3 blend = lerp(0.5, 1-dot(albedo, LUMINANCE_VECTOR), ALBEDO_BOOST); //boost albedo by inv
return Soft_Light(albedo, blend);
}
float3 calc_albedo(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
float3 albedo = alb_gloss.rgb;
//albedo = SRGBToLinear(albedo);
albedo = calc_albedo_boost(albedo);
//albedo = SRGBToLinear(albedo);
float3 screen_contrib = albedo;
screen_contrib = (1-(1-screen_contrib)*(1-screen_contrib))-lerp(dot(screen_contrib, LUMINANCE_VECTOR), screen_contrib, 0.5);
albedo = SRGBToLinear(albedo);
screen_contrib = SRGBToLinear(screen_contrib);
float3 albedo_metal = screen_contrib; //metal albedo is screen blend contrib, it gets rid of all highlights.
return saturate(lerp(albedo, albedo_metal, metalness)*ALBEDO_AMOUNT);
}
float3 calc_specular(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
float3 specular = float3(SPECULAR_BASE, SPECULAR_BASE, SPECULAR_BASE); //base fresnel to tweak
float3 specular_metal = alb_gloss.rgb; //metal uses diffuse for specular
specular_metal = calc_albedo_boost(specular_metal); //boost albedo
specular_metal = SRGBToLinear(specular_metal);
//tweaks for specular boost
//material_ID = sqrt(material_ID/0.75);
material_ID = saturate(material_ID * 1.425);
alb_gloss.a = sqrt(alb_gloss.a);
/*
//old spec boost
float specular_boost = ((0.5+material_ID) * (0.5+alb_gloss.a))-0.25; //0.0 - 2.0 range
specular_boost = specular_boost - 1; //scale in -1 to +1 range
specular_boost = SPECULAR_RANGE * specular_boost;
specular_boost = max(0, specular_boost + 1); //0 - 2
*/
float specular_boost = (material_ID*2-1) + (alb_gloss.a*2-1); //-2.0 - +2.0 range
specular_boost = exp2(SPECULAR_RANGE * specular_boost);
specular_boost = pow(specular_boost, SPECULAR_POW);
specular *= specular_boost;
return saturate(lerp(specular, specular_metal, metalness));
}
float calc_rough(float4 alb_gloss, float material_ID)
{
float metalness = calc_metalness(alb_gloss, material_ID);
alb_gloss.a = pow(alb_gloss.a, ROUGHNESS_POW - (metalness * METAL_BOOST)); //metal boost
float roughpow = 0.5 / max(0.001, 1 - Ldynamic_color.w);
float rough = pow(lerp(ROUGHNESS_HIGH, ROUGHNESS_LOW, alb_gloss.a), roughpow);
//rough = pow(rough, 1 + (metalness * METAL_BOOST)); //metal boost
return saturate(rough*rough);
}
//=================================================================================================
//Rain and Foliage
//
void calc_rain(inout float3 albedo, inout float3 specular, inout float rough, in float4 alb_gloss, in float material_ID, in float rainmask)
{
//rain based on Remember Me's implementation
//float wetness = saturate(rain_params.x*rainmask);
float wetness = saturate(smoothstep(0.1,0.9,rain_params.x*rainmask));
float porosity = 1-saturate(material_ID*1.425); //metal material at 0, concrete at 1
//porosity = saturate((porosity-0.5)/0.4); //Remember Me rain porosity
float factor = lerp(1,0.2, porosity); //albedo darkening factor
albedo *= lerp(1, factor, wetness);
rough = lerp(0.001, rough, lerp(1, factor, wetness));
specular = lerp(specular, 0.02, wetness);
}
void calc_foliage(inout float3 albedo, inout float3 specular, inout float rough, in float4 alb_gloss, in float mat_id)
{
//specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? calc_specular(alb_gloss, 0.0) : specular;
specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? alb_gloss.g * 0.02 : specular;
//specular = (abs(mat_id-MAT_FLORA) <= MAT_FLORA_ELIPSON) ? pow(alb_gloss.g * 0.1414, 2) : specular;
}
//=================================================================================================
//Functions
//
float F_Shlick(float f0, float f90, float vDotH)
{
return lerp(f0, f90, pow(1-vDotH, 5));
}
float3 F_Shlick(float3 f0, float3 f90, float vDotH)
{
return lerp(f0, f90, pow(1-vDotH, 5));
}
// We have a better approximation of the off specular peak
// but due to the other approximations we found this one performs better .
// N is the normal direction
// R is the mirror vector
// This approximation works fine for G smith correlated and uncorrelated
float3 getSpecularDominantDir(float3 N, float3 R, float roughness)
{
float smoothness = saturate(1 - roughness);
float lerpFactor = smoothness * (sqrt(smoothness) + roughness);
// The result is not normalized as we fetch in a cubemap
return lerp(N, R, lerpFactor);
}
//=================================================================================================
//Shading
//
//include BRDFs
#include "pbr_brdf_blinn.h" //brdf
#include "pbr_brdf_ggx.h" //brdf
float Lit_Burley(float nDotL, float nDotV, float vDotH, float rough)
{
float fd90 = 0.5 + 2 * vDotH * vDotH * rough;
float lightScatter = F_Shlick(1, fd90, nDotL);
float viewScatter = F_Shlick(1, fd90, nDotV);
return (lightScatter * viewScatter) / PI;
}
float Lambert_Source(float nDotL,float rough)
{
float exponent = lerp(1.4, 0.6, rough);
return (pow(nDotL, exponent) * ((exponent + 1.0) * 0.5)) / max(1e-5, PI * nDotL);
}
float Lit_Diffuse(float nDotL, float nDotV, float vDotH, float rough)
{
#ifdef USE_BURLEY_DIFFUSE
return Lit_Burley(nDotL, nDotV, vDotH, rough);
#else
return Lambert_Source(nDotL, rough);
#endif
}
float3 Lit_Specular(float nDotL, float nDotH, float nDotV, float vDotH, float3 f0, float rough)
{
#ifdef USE_GGX_SPECULAR
return Lit_GGX(nDotL, nDotH, nDotV, vDotH, f0, rough); //GGX is much more expensive but looks nicer
#else
return Lit_Blinn(nDotL, nDotH, nDotV, vDotH, f0, rough); //much cheaper pbr blinn
#endif
}
float3 Lit_BRDF(float rough, float3 albedo, float3 f0, float3 V, float3 N, float3 L )
{
float3 H = normalize(V + L );
float nDotL = saturate(dot(N, L));
float nDotH = saturate(dot(N, H));
//float nDotV = saturate(dot(N, V));
//float nDotV = 1e-5 + abs(dot(N, V)); //DICE
float nDotV = max(1e-5, dot(N, V));
float vDotH = saturate(dot(V, H));
float3 diffuse_term = Lit_Diffuse(nDotL, nDotV, vDotH, rough).rrr;
diffuse_term *= albedo;
float3 specular_term = Lit_Specular(nDotL, nDotH, nDotV, vDotH, f0, rough);
// horizon occlusion with falloff, should be computed for direct specular too
//float R = reflect(V, N);
//float R = 2 * dot(N, V) * N - V;
//float horizon = saturate(1.0 + dot(R, N)); //needs vertex normals
float horizon = saturate(0.95 + dot(N, V));
horizon *= horizon;
specular_term *= horizon; //horizon atten
return (diffuse_term + specular_term) * nDotL * PI;
}
//=================================================================================================
//Ambient
//
float EnvBurley(float roughness, float NV)
{
//Burley (Hill's curve)
float d0 = 0.97619 - 0.488095 * pow(1.0 - NV, 5.0);
float d1 = 1.55754 + (-2.02221 + (2.56283 - 1.06244 * NV) * NV) * NV;
return lerp(d0, d1, roughness);
}
float Amb_Diffuse(float3 f0, float rough, float nDotV)
{
#ifdef USE_BURLEY_DIFFUSE
return EnvBurley(rough, nDotV);
#else
return 1.0;
#endif
}
float3 Amb_Specular(float3 f0, float rough, float nDotV)
{
#ifdef USE_GGX_SPECULAR
return EnvGGX(f0, rough, nDotV);
#else
return EnvBlops2(f0, rough, nDotV);
#endif
}
float3 Amb_BRDF(float rough, float3 albedo, float3 f0, float3 env_d, float3 env_s, float3 V, float3 N)
{
//float nDotV = saturate(dot(N, V));
//float nDotV = 1e-5 + abs(dot(N, V)); //DICE
float nDotV = max(1e-5, dot(N, V));
float3 diffuse_term = Amb_Diffuse(f0, rough, nDotV);
diffuse_term *= env_d * albedo;
float3 specular_term = Amb_Specular(f0, rough, nDotV);
specular_term *= env_s;
// horizon occlusion with falloff, should be computed for direct specular too
//float R = reflect(V, N);
//float horizon = saturate(1.0 + dot(R, N)); //needs vertex normals
float horizon = saturate(0.95 + dot(N, V));
horizon *= horizon;
specular_term *= horizon; //horizon atten
return diffuse_term + specular_term;
}
@@ -0,0 +1,65 @@
//BLOPS 2 blinn phong PBR
//credit to Treyarch
float CalcGlossmap(float rough)
{
return 1.0 - rough;
}
float RoughToGlossExp(float rough)
{
//return = 2 / ((rough*rough) - 2); UE4 blinn
return pow(8192, CalcGlossmap(rough));//blops2
//return pow(2, 11 * CalcGlossmap(rough)) - 1;
}
float D_Blinn(float a, float nDotH)
{
return pow(nDotH, a) * ((a+2)/(8*PI)); //BLOPS2
}
float G_Smith(float a, float nDotX)
{
float k = 2 / sqrt(PI * (a + 2)); //remapping for BLOPS
return nDotX / (nDotX * (1 - k) + k);
}
float G_SmithBLOPS(float a, float nDotl, float nDotv)
{
float k = 2 / sqrt(PI * (a + 2)); //remapping for BLOPS
float A = nDotl * (1 - k) + k; //remapping for BLOPS
float B = nDotv * (1 - k) + k; //remapping for BLOPS
return 1 / (A*B);
}
float3 Lit_Blinn(float nDotL, float nDotH, float nDotV, float vDotH, float3 f0, float rough)
{
float a = RoughToGlossExp(rough);
float d = D_Blinn(a, nDotH);
//float v = G_Smith(a, nDotL) * G_Smith(a, nDotV);
float v = G_SmithBLOPS(a, nDotL, nDotV);
float3 f90Atten = saturate(50*f0); //UE4 specular shadowing
float3 f = F_Shlick(f0, f90Atten, vDotH);
return d * f * v;
}
float3 EnvBlops2(float3 f0, float rough, float NoV )
{
float g = CalcGlossmap(rough);
float3 f90Atten = saturate(50*f0); //UE4 specular shadowing
float4 t = float4(1/0.96, 0.475, (0.0275-0.25*0.04)/0.96, 0.25);
t *= float4(g, g, g, g);
t += float4(0, 0, (0.015-0.75*0.04)/0.96, 0.75);
float a0 = t.x * min(t.y, exp2(-9.28*NoV)) + t.z;
float a1 = t.w;
return saturate(f90Atten * a0 + f0 * (a1 - a0));
}
@@ -0,0 +1,124 @@
float D_GGX(float NdotH, float a2)
{
float denominator = (NdotH * a2 - NdotH) * NdotH + 1.0;
return a2 / (PI * denominator * denominator);
}
float Lambda_Smith(float NdotX, float a)
{
float a2 = a * a;
float NdotX_2 = NdotX * NdotX;
return (-1.0 + sqrt(a2 * (1.0 - NdotX_2) / NdotX_2 + 1.0)) * 0.5;
}
//Height Correlated Masking-shadowing function
float G2_Smith_Correlated(float NdotL, float NdotV, float a)
{
float lambdaV = Lambda_Smith(NdotV, a);
float lambdaL = Lambda_Smith(NdotL, a);
return 1.0 / (1.0 + lambdaV + lambdaL);
}
float G2_SmithJointApprox(float NdotL, float NdotV, float a)
{
float Vis_V = NdotL * ( NdotV * ( 1 - a ) + a );
float Vis_L = NdotV * ( NdotL * ( 1 - a ) + a );
return 0.5 * rcp( Vis_V + Vis_L );
}
float3 Lit_GGX(float NdotL, float NdotH, float NdotV, float VdotH, float3 F0, float rough)
{
//Alpha
float a = rough * rough;
float a2 = a * a;
//Normal distribution function
float D = D_GGX(NdotH, a2);
//Masking-shadowing
//float V = G2_Smith_Correlated(NdotL, NdotV, a);
float V = G2_SmithJointApprox(NdotL, NdotV, a); //denom included?
//Fresnel
float3 f90Atten = saturate(50*F0); //UE4 specular shadowing
float3 F = F_Shlick(F0, f90Atten, VdotH);
//Numerator
float3 numerator = (D * V) * F;
//Denominator
float denominator = 4.0 * NdotV;
return numerator; //UE4 has no denom
//return numerator / denominator;
}
//UE4 mobile approx
float2 EnvBRDFApprox(float Roughness, float NoV )
{
const float4 c0 = { -1, -0.0275, -0.572, 0.022 };
const float4 c1 = { 1, 0.0425, 1.04, -0.04 };
float4 r = Roughness * c0 + c1;
float a004 = min(r.x * r.x, exp2(-9.28 * NoV ) ) * r.x + r.y;
float2 AB = float2(-1.04, 1.04 ) * a004 + r.zw;
return AB;
}
//-------------------------------------------------------------------------------------------------
// Returns scale and bias values for environment specular reflections that represents the
// integral of the geometry/visibility + fresnel terms for a GGX BRDF given a particular
// viewing angle and roughness value. The final value is computed using polynomials that were
// fitted to tabulated data generated via monte carlo integration.
//-------------------------------------------------------------------------------------------------
float2 GGXEnvironmentBRDFScaleBias(float roughness, float nDotV)
{
const float sqrtRoughness = sqrt(roughness);
const float nDotV2 = nDotV * nDotV;
const float sqrtRoughness2 = sqrtRoughness * sqrtRoughness;
const float sqrtRoughness3 = sqrtRoughness2 * sqrtRoughness;
const float delta = 0.991086418474895f + (0.412367709802119f * sqrtRoughness * nDotV2) -
(0.363848256078895f * sqrtRoughness2) -
(0.758634385642633f * nDotV * sqrtRoughness2);
const float bias = saturate((0.0306613448029984f * sqrtRoughness) + 0.0238299731830387f /
(0.0272458171384516f + sqrtRoughness3 + nDotV2) -
0.0454747751719356f);
const float scale = saturate(delta - bias);
return float2(scale, bias);
}
//LVutner ambient BRDF
float2 integrate_brdf(float roughness, float NV)
{
//Schlick's approximation
float F_partial = pow(1.0 - NV, 5.0);
//GGX
const float4 c0 = float4(-1.0, -0.0275, -0.26, 0.0109);
const float4 c1 = float4(1.0, 0.0455, 1.0417, -0.0417);
float4 r = roughness * c0 + c1;
float a004 = min(0.9 - 0.75 * roughness, F_partial) * r.x + r.y;
float2 AB = float2(-1.0417, 1.0417) * a004 + r.zw;
//Output (Scale, Bias, Burley)
return float2(AB.x, AB.y);
}
float3 EnvGGX(float3 f0, float rough, float nDotV )
{
//UE4 GGX
float3 f90Atten = saturate(50*f0); //UE4 specular shadowing
float2 AB = EnvBRDFApprox(rough, nDotV);
/*
//Matt Pettineo GGX
float2 AB = GGXEnvironmentBRDFScaleBias(rough, nDotV);
//LVutner GGX
float2 AB = integrate_brdf(rough, nDotV);
*/
return (f0 * AB.x + AB.y * f90Atten);
}
@@ -0,0 +1,2 @@
//PBR Cubemaps are installed
#define USE_PBR_CUBEMAPS
@@ -0,0 +1,20 @@
//=================================================================================================
//Settings for PBR conversion
//=================================================================================================
#define USE_BURLEY_DIFFUSE //use expensive Disney/Burley diffuse
//#define USE_GGX_SPECULAR //use more expensive GGX specular
//=================================================================================================
#define ALBEDO_BOOST 0.50
#define ALBEDO_AMOUNT 1.00
#define ROUGHNESS_LOW 0.5
#define ROUGHNESS_HIGH 1.0
#define ROUGHNESS_POW 1.0
#define SPECULAR_BASE 0.04
#define SPECULAR_RANGE 1.0
#define SPECULAR_POW 1.0
#define METAL_BOOST 0.25
#define METALNESS_THRESHOLD 0.125
#define METALNESS_SOFTNESS 0.125
@@ -0,0 +1,43 @@
#include "common.h"
#include "pbr_cubemap_check.h"
struct v2p
{
float4 factor : COLOR0; // rgb tint
float4 tc0 : TEXCOORD0; //tonemap in alpha
float3 tc1 : TEXCOORD1;
};
struct _out
{
float4 low : SV_Target0;
float4 high : SV_Target1;
};
TextureCube s_sky0 :register(t0);
TextureCube s_sky1 :register(t1);
//////////////////////////////////////////////////////////////////////////////////////////
// Pixel
_out main(v2p I )
{
float3 s0 = s_sky0.Sample(smp_rtlinear, I.tc0 );
float3 s1 = s_sky1.Sample(smp_rtlinear, I.tc1 );
float3 sky = lerp (s0,s1,I.factor.w);
//srgb tint (matches hmodel)
float3 SkyTint = I.factor.rgb;
float TintPow = 1.0;
sky = pow(sky, TintPow);
sky *= SkyTint;
sky = pow(sky, 1/TintPow);
// final tone-mapping
float tm_scale = I.tc0.w;
_out o;
tonemap(o.low, o.high, sky, tm_scale) ; //factor contains tonemapping
return o;
}
@@ -0,0 +1,41 @@
#include "common.h"
struct vi
{
float4 p : POSITION;
float4 c : COLOR0;
float3 tc0 : TEXCOORD0;
float3 tc1 : TEXCOORD1;
};
struct v2p
{
float4 c : COLOR0;
float4 tc0 : TEXCOORD0;
float3 tc1 : TEXCOORD1;
float4 hpos : SV_Position;
};
v2p main (vi v)
{
v2p o;
//v.c.rgb = v.c.bgr; // fix skybox color
float4 tpos = float4(2000*v.p.x, 2000*v.p.y, 2000*v.p.z, 2000*v.p.w);
o.hpos = mul (m_WVP, tpos);
o.hpos.z = o.hpos.w;
o.tc0.xyz = v.tc0; // copy tc
o.tc1.xyz = v.tc1; // copy tc
float scale = s_tonemap.Load(int3(0,0,0) ).x;
float3 tint = v.c.rgb * 1.7;
//float3 tint = 1.0;
//float3 tint = env_color.rgb;
//float3 tint = fog_color.rgb * 2.0;
o.c = float4(tint, v.c.a ); // copy color, pre-scale by tonemap //float4 (v.c.rgb*scale*2, v.c.a );
o.tc0.w = scale;
return o;
}
@@ -0,0 +1,289 @@
#define USE_ERROR_CORRECTION
//#define RECALCULATENORMALZ
//#define NORMALIZE_TEXTURES
static const float NORMAL_STRENGTH = 1.0;
static const float DETAIL_STRENGTH = 1.0;
static const float DETAIL_TINT = 1.0;
static const float DETAIL_GLOSS = 1.0;
#ifndef SLOAD_H
#define SLOAD_H
#include "common.h"
#ifdef MSAA_ALPHATEST_DX10_1
#if MSAA_SAMPLES == 2
static const float2 MSAAOffsets[2] = { float2(4,4), float2(-4,-4) };
#endif
#if MSAA_SAMPLES == 4
static const float2 MSAAOffsets[4] = { float2(-2,-6), float2(6,-2), float2(-6,2), float2(2,6) };
#endif
#if MSAA_SAMPLES == 8
static const float2 MSAAOffsets[8] = { float2(1,-3), float2(-1,3), float2(5,1), float2(-3,-5),
float2(-5,5), float2(-7,-1), float2(3,7), float2(7,-7) };
#endif
#endif // MSAA_ALPHATEST_DX10_1
//////////////////////////////////////////////////////////////////////////////////////////
// Texture samplers and blenders //
//////////////////////////////////////////////////////////////////////////////////////////
float3 SampleNormal(float4 N, float4 NE)
{
float3 Norm = unpack_normal(N.wzy);
#ifdef USE_ERROR_CORRECTION
Norm += unpack_normal(NE.xyz);
#endif
#ifdef RECALCULATENORMALZ
Norm.z = sqrt(1 - saturate(dot(Norm.xy, Norm.xy)));
#endif
#ifdef NORMALIZE_TEXTURES
Norm = normalize(Norm);
#endif
return Norm;
}
float3 NormalStrength(float3 N, float Strength)
{
if(Strength != 1.0)
{
N.xy *= Strength;
N.z = sqrt(1 - saturate(dot(N.xy, N.xy)));
N = normalize(N);
}
return N;
}
float SampleGloss(float4 N)
{
return N.x;
}
float SampleHeight(float4 NE)
{
return NE.w;
}
float3 ApplyDetailAlbedo(float3 A1, float3 A2)
{
//return saturate(A1 * A2 * 2);
return saturate(A1 * exp2(DETAIL_TINT * (A2 * 2 - 1)));
}
float3 ApplyDetailNormal(float3 N1, float3 N2)
{
N1 += float3( 0, 0, 1);
N2 *= float3(-1, -1, 1);
return normalize(N1*dot(N1, N2)/N1.z - N2);
}
float ApplyDetailGloss(float G1, float G2)
{
//return saturate(G1 * G2 * 2);
//return saturate(G1 + (DETAIL_GLOSS * (G2 * 2 - 1)));
return saturate(G1 * exp2(DETAIL_GLOSS * (G2 * 2 - 1)));
}
float ApplyDetailHeight(float H1, float H2)
{
return H1 + (H2 * 2 - 1);
}
//////////////////////////////////////////////////////////////////////////////////////////
// Bumped surface loader //
//////////////////////////////////////////////////////////////////////////////////////////
struct surface_bumped
{
float4 base;
float3 normal;
float gloss;
float height;
};
float4 tbase( float2 tc )
{
return s_base.Sample( smp_base, tc);
}
#if defined(ALLOW_STEEPPARALLAX) && defined(USE_STEEPPARALLAX)
//Always remember to check defines, variables, and shit.... god
#define PARALLAX_NEAR_PLANE 0.01
#define PARALLAX_FAR_PLANE 35
#define PARALLAX_DEPTH 0.045
//Ok, we can comment old gsc parallax now.
//We need to change input, to p_bumped struct like in GSC shader
//We also change name of this function to GSC
//Time to change input to stuff from p_bumped.
void UpdateTC( inout p_bumped I)
{
//Here's "limited" range of parallax. We use linear depth (z vector of view space position) to do that
if ((I.position.z > PARALLAX_NEAR_PLANE) && (I.position.z < PARALLAX_FAR_PLANE))
{
//That M1/M2/M3 stuff is our TBN matrix (we aligin tangent normals/vectors to to just geometry normals
float3 eye = normalize(mul(float3x3(I.M1.x, I.M2.x, I.M3.x,
I.M1.y, I.M2.y, I.M3.y,
I.M1.z, I.M2.z, I.M3.z), -I.position.xyz));
// steps minmax and refines minmax
int4 steps = int4(3, 10, 7, 16); // 3..10, 7..16
bool need_disp_lerp = true;
bool need_refine = true; //Thats refinement steps, used to smoothout raymarched results
float view_angle = abs(dot(float3(0.0, 0.0, 1.0), eye));
float layer_step = rcp(lerp(steps.y, steps.x, view_angle));
//float2 tc_step = layer_step * eye.xy * PARALLAX_DEPTH);
float2 tc_step = layer_step * eye.xy * (parallax.x);
//Now, we have to change this huita. p.tcdbump is our "tiled" texture coordinate
//I.tcdh is our "normal" texcoord, lets see above
float2 displaced_tc = I.tcdh;
float curr_disp, curr_layer = 0.0;
do
{
displaced_tc -= tc_step;
curr_disp = 1 - s_bumpX.SampleLevel(smp_base, displaced_tc, 0).w; //Our heightmap sampler
curr_layer += layer_step;
} while (curr_layer < curr_disp);
if (need_refine)
{
displaced_tc += tc_step;
curr_layer -= layer_step;
float refine_steps = lerp(steps.w, steps.z, view_angle);
tc_step /= refine_steps;
layer_step /= refine_steps;
do
{
displaced_tc -= tc_step;
curr_disp = 1.0 - s_bumpX.SampleLevel(smp_base, displaced_tc, 0).w;
curr_layer += layer_step;
} while (curr_layer < curr_disp);
}
if (need_disp_lerp)
{
float2 displaced_tc_prev = displaced_tc + tc_step;
float after_depth = curr_disp - curr_layer;
float before_depth = 1.0 - s_bumpX.SampleLevel(smp_base, displaced_tc_prev, 0).w - curr_layer + layer_step; //Another sampler name
float weight = after_depth / (after_depth - before_depth);
displaced_tc = lerp(displaced_tc, displaced_tc_prev, weight);
}
//Tiling for detail/tiled textures
#if defined(USE_TDETAIL) && defined(USE_STEEPPARALLAX)
I.tcdbump = I.tcdh * dt_params; //tiled UV
I.tcdbump += displaced_tc - I.tcdh; //offset
#endif
I.tcdh = displaced_tc;
}
}
#elif defined(USE_PARALLAX) || defined(USE_STEEPPARALLAX)
void UpdateTC( inout p_bumped I)
{
float3 eye = mul (float3x3(I.M1.x, I.M2.x, I.M3.x,
I.M1.y, I.M2.y, I.M3.y,
I.M1.z, I.M2.z, I.M3.z), -I.position.xyz);
float height = s_bumpX.Sample( smp_base, I.tcdh).w; //
//height /= 2;
//height *= 0.8;
height = height*(parallax.x) + (parallax.y); //
float2 new_tc = I.tcdh + height * normalize(eye); //
//Tiling for detail/tiled textures
#if defined(USE_TDETAIL) && defined(USE_STEEPPARALLAX)
I.tcdbump = I.tcdh * dt_params + height * normalize(eye);
#endif
// Output the result
I.tcdh.xy = new_tc;
}
#else // USE_PARALLAX
void UpdateTC( inout p_bumped I)
{
;
}
#endif // USE_PARALLAX
surface_bumped sload_i( p_bumped I)
{
surface_bumped S;
UpdateTC(I); // All kinds of parallax are applied here.
//Base textures
//
S.base = tbase(I.tcdh);
float4 Nu = s_bump.Sample( smp_base, I.tcdh );
float4 NuE = s_bumpX.Sample( smp_base, I.tcdh);
float3 TangentNormal = NormalStrength(SampleNormal(Nu, NuE), NORMAL_STRENGTH);
S.normal = TangentNormal;
S.gloss = SampleGloss(Nu);
S.height = SampleHeight(NuE);
//Detail textures
//
#ifdef USE_TDETAIL
float4 detail = s_detail.Sample( smp_base, I.tcdbump);
S.base.rgb = ApplyDetailAlbedo(S.base.rgb, detail.rgb);
#ifdef USE_TDETAIL_BUMP
float4 NDetail = s_detailBump.Sample( smp_base, I.tcdbump);
float4 NDetailX = s_detailBumpX.Sample( smp_base, I.tcdbump);
float3 DetailNormal = NormalStrength(SampleNormal(NDetail, NDetailX), DETAIL_STRENGTH);
S.normal = ApplyDetailNormal(TangentNormal, DetailNormal);
//float DetailGloss = SampleGloss(NDetail);
float DetailGloss = detail.w; //higher res most of the time
float DetailHeight = SampleHeight(NDetailX);
S.height = ApplyDetailHeight(S.height, DetailHeight);
#else
float DetailGloss = detail.w;
#endif
S.gloss = ApplyDetailGloss(S.gloss, DetailGloss);
#endif
//
return S;
}
surface_bumped sload ( p_bumped I)
{
return sload_i (I);
}
surface_bumped sload ( p_bumped I, float2 pixeloffset )
{
// apply offset
#ifdef MSAA_ALPHATEST_DX10_1
I.tcdh.xy += pixeloffset.x * ddx(I.tcdh.xy) + pixeloffset.y * ddy(I.tcdh.xy);
#ifdef USE_TDETAIL
I.tcdbump.xy += pixeloffset.x * ddx(I.tcdbump.xy) + pixeloffset.y * ddy(I.tcdbump.xy);
#endif
#endif
return sload_i (I);
}
#endif
@@ -0,0 +1,65 @@
//=================================================================================================
//Gamma Correction
//=================================================================================================
//#define USE_STRICT_GAMMA_CORRECTION //use gamma correction for sky blending, might distort the original colors
//=================================================================================================
float LinearTosRGB(float gammaPre)
{
/*
float Low = gammaPre * 12.92;
float High = (pow(gammaPre, 1.0 / 2.4) * 1.055) - 0.055;
return (gammaPre <= 0.0031308) ? Low : High;
*/
//return (gammaPre <= 0.00313080495356037151702786377709) ? gammaPre * 12.92 : (1.055 * pow(gammaPre, 0.41666666666666666666666666666667) - 0.055);
//return max(1.055 * pow(gammaPre, 0.416666667) - 0.055, 0.0);
//Cheap sRGB doesn't cause clipping
return pow(gammaPre, 0.45454545);
}
float3 LinearTosRGB(float3 gammaPre)
{
gammaPre = max(0.0, gammaPre);
float3 gammaPost = float3(
LinearTosRGB(gammaPre.r),
LinearTosRGB(gammaPre.g),
LinearTosRGB(gammaPre.b));
return gammaPost;
}
/*
float4 LinearTosRGB(float4 gammaPre)
{
return float4(LinearTosRGB(gammaPre.rgb), gammaPre.a);
}
*/
float SRGBToLinear(float gammaPre)
{
/*
float Low = gammaPre / 12.92;
float High = pow((gammaPre + 0.055) / 1.055, 2.4);
return(gammaPre <= 0.04045) ? Low : High;
*/
//return (gammaPre <= 0.04045) ? gammaPre * 0.07739938080495356037151702786378 : pow((gammaPre + 0.055) * 0.94786729857819905213270142180095, 2.4);
//return gammaPre * (gammaPre * (gammaPre * 0.305306011 + 0.682171111) + 0.012522878);
//Cheap sRGB doesn't cause clipping
return pow(gammaPre, 2.2);
}
float3 SRGBToLinear(float3 gammaPre)
{
gammaPre = max(0.0, gammaPre);
float3 gammaPost = float3(
SRGBToLinear(gammaPre.r),
SRGBToLinear(gammaPre.g),
SRGBToLinear(gammaPre.b));
return gammaPost;
}
/*
float4 SRGBToLinear(float4 gammaPre)
{
return float4(SRGBToLinear(gammaPre.rgb), gammaPre.a);
}
*/
#include "tonemap_srgb.h"
@@ -0,0 +1,23 @@
//=================================================================================================
//Gamma Correct Tonemapping without Color Grading
//=================================================================================================
float3 tonemap_sRGB(float3 x, float w )
{
//convert into linear gamma space
x = SRGBToLinear(x);
//reinhard tonemapping
x = x/(x+1);
x /= w/(w+1);
//float fWhiteIntensitySQR = w*w;
//x = x/(1+(x/fWhiteIntensitySQR));
//convert into sRGB gamma space
x = LinearTosRGB(x);
//return with saturate, everything should be in LDR sRGB
return saturate(x);
}
@@ -0,0 +1,30 @@
#ifndef TONEMAPPING_H
#define TONEMAPPING_H
//
uniform float tnmp_a;
uniform float tnmp_b;
uniform float tnmp_c;
uniform float tnmp_d;
uniform float tnmp_e;
uniform float tnmp_f;
uniform float tnmp_w;
uniform float tnmp_exposure;
uniform float tnmp_gamma;
uniform float tnmp_onoff;
float3 Uncharted2ToneMapping(float3 gammaPre)
{
//GET RID OF THIS
//IT IS ADDED AFTER TONEMAPPING AND CLIPS EVERYTHING
return 0;
/*
gammaPre *= tnmp_exposure;
gammaPre = ((gammaPre * (tnmp_a * gammaPre + tnmp_c * tnmp_b) + tnmp_d * tnmp_e) / (gammaPre * (tnmp_a * gammaPre + tnmp_b) + tnmp_d * tnmp_f)) - tnmp_e / tnmp_f;
float white = ((tnmp_w * (tnmp_a * tnmp_w + tnmp_c * tnmp_b) + tnmp_d * tnmp_e) / (tnmp_w * (tnmp_a * tnmp_w + tnmp_b) + tnmp_d * tnmp_f)) - tnmp_e / tnmp_f;
gammaPre /= white;
gammaPre = pow(gammaPre, (1.f / tnmp_gamma));
return gammaPre;
*/
}
#endif

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