aboutsummaryrefslogtreecommitdiff
path: root/src/shaders/ShaderCommon.h
blob: f4b8f80256aebe7295473aec13a54bb264828ae3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
// This code contains NVIDIA Confidential Information and is disclosed
// under the Mutual Non-Disclosure Agreement.
//
// Notice
// ALL NVIDIA DESIGN SPECIFICATIONS AND CODE ("MATERIALS") ARE PROVIDED "AS IS" NVIDIA MAKES
// NO REPRESENTATIONS, WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
// THE MATERIALS, AND EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTIES OF NONINFRINGEMENT,
// MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
//
// NVIDIA Corporation assumes no responsibility for the consequences of use of such
// information or for any infringement of patents or other rights of third parties that may
// result from its use. No license is granted by implication or otherwise under any patent
// or patent rights of NVIDIA Corporation. No third party distribution is allowed unless
// expressly authorized by NVIDIA.  Details are subject to change without notice.
// This code supersedes and replaces all information previously supplied.
// NVIDIA Corporation products are not authorized for use as critical
// components in life support devices or systems without express written approval of
// NVIDIA Corporation.
//
// Copyright (C) 2013, NVIDIA Corporation. All rights reserved.

/*===========================================================================
Constants
===========================================================================*/

static const float PI = 3.1415926535898f;
static const float EDGE_FACTOR = 1.0f - (2.0f/64.0f) * (1.0f/64.0f);
static const uint MAX_PHASE_TERMS = 4;

#ifdef __PSSL__
static const float2 SAMPLE_POSITIONS[] = {
	// 1x
	float2( 0, 0)/16.f,
	// 2x
	float2(-4, 4)/16.f,
	float2( 4,-4)/16.f,
	// 4x
	float2(-6, 6)/16.f,
	float2( 6,-6)/16.f,
	float2(-2,-2)/16.f,
	float2( 2, 2)/16.f,
	// 8x
	float2(-7,-3)/16.f,
	float2( 7, 3)/16.f,
	float2( 1,-5)/16.f,
	float2(-5, 5)/16.f,
	float2(-3,-7)/16.f,
	float2( 3, 7)/16.f,
	float2( 5,-1)/16.f,
	float2(-1, 1)/16.f
};

// constant buffers
#define cbuffer ConstantBuffer

// textures and samplers
#define Texture2DMS MS_Texture2D
#define Texture2DArray Texture2D_Array
#define SampleLevel SampleLOD
#define GetSamplePosition(s) GetSamplePoint(s)

// semantics
#define SV_DEPTH S_DEPTH_OUTPUT
#define SV_DOMAINLOCATION S_DOMAIN_LOCATION
#define SV_INSIDETESSFACTOR S_INSIDE_TESS_FACTOR
#define SV_INSTANCEID S_INSTANCE_ID
#define SV_ISFRONTFACE S_FRONT_FACE
#define SV_OUTPUTCONTROLPOINTID S_OUTPUT_CONTROL_POINT_ID
#define SV_POSITION S_POSITION
#define SV_POSITION S_POSITION
#define SV_PRIMITIVEID S_PRIMITIVE_ID
#define SV_SAMPLEINDEX S_SAMPLE_INDEX
#define SV_TARGET S_TARGET_OUTPUT
#define SV_TARGET0 S_TARGET_OUTPUT0
#define SV_TARGET1 S_TARGET_OUTPUT1
#define SV_TESSFACTOR S_EDGE_TESS_FACTOR
#define SV_VERTEXID S_VERTEX_ID

// hull and domain shader properties
#define domain DOMAIN_PATCH_TYPE
#define partitioning PARTITIONING_TYPE
#define outputtopology OUTPUT_TOPOLOGY_TYPE
#define outputcontrolpoints OUTPUT_CONTROL_POINTS
#define patchconstantfunc PATCH_CONSTANT_FUNC
#define maxtessfactor MAX_TESS_FACTOR

// need to figure out how to deal with those exactly:
#define shared
#endif

/*===========================================================================
Sampler states
===========================================================================*/
SamplerState 	 sPoint : register(s0);
SamplerState 	 sBilinear : register(s1);

/*===========================================================================
Constant buffers
===========================================================================*/
shared cbuffer cbContext : register(b0)
{
	float2 g_vOutputSize				: packoffset(c0);
	float2 g_vOutputSize_Inv			: packoffset(c0.z);
	float2 g_vBufferSize				: packoffset(c1);
	float2 g_vBufferSize_Inv			: packoffset(c1.z);
	float g_fResMultiplier				: packoffset(c2);
	unsigned int g_uBufferSamples		: packoffset(c2.y);
}

shared cbuffer cbFrame : register(b1)
{
	column_major float4x4 g_mProj		: packoffset(c0);
	column_major float4x4 g_mViewProj	: packoffset(c4);
    column_major float4x4 g_mViewProjInv: packoffset(c8);
    float2 g_vOutputViewportSize        : packoffset(c12);
    float2 g_vOutputViewportSize_Inv    : packoffset(c12.z);
    float2 g_vViewportSize              : packoffset(c13);
    float2 g_vViewportSize_Inv          : packoffset(c13.z);
    float3 g_vEyePosition				: packoffset(c14);
	float2 g_vJitterOffset				: packoffset(c15);
	float g_fZNear						: packoffset(c15.z);
	float g_fZFar						: packoffset(c15.w);
    float3 g_vScatterPower              : packoffset(c16);
    unsigned int g_uNumPhaseTerms       : packoffset(c16.w);
    float3 g_vSigmaExtinction           : packoffset(c17);
    unsigned int g_uPhaseFunc[4]		: packoffset(c18);
    float4 g_vPhaseParams[4]			: packoffset(c22);
};

shared cbuffer cbVolume : register(b2)
{
	column_major float4x4 g_mLightToWorld	: packoffset(c0);
	float g_fLightFalloffAngle				: packoffset(c4.x);
	float g_fLightFalloffPower				: packoffset(c4.y);
	float g_fGridSectionSize				: packoffset(c4.z);
	float g_fLightToEyeDepth				: packoffset(c4.w);
    float g_fLightZNear                     : packoffset(c5);
    float g_fLightZFar                      : packoffset(c5.y);
	float4 g_vLightAttenuationFactors		: packoffset(c6);
	column_major float4x4 g_mLightProj[4]	: packoffset(c7);
	column_major float4x4 g_mLightProjInv[4]: packoffset(c23);
	float3 g_vLightDir						: packoffset(c39);
	float g_fGodrayBias						: packoffset(c39.w);
	float3 g_vLightPos						: packoffset(c40);
    unsigned int g_uMeshResolution          : packoffset(c40.w);
	float3 g_vLightIntensity				: packoffset(c41);
	float g_fTargetRaySize					: packoffset(c41.w);
	float4 g_vElementOffsetAndScale[4]		: packoffset(c42); 
	float4 g_vShadowMapDim					: packoffset(c46);
	unsigned int g_uElementIndex[4]	        : packoffset(c47);
};

shared cbuffer cbApply : register(b3)
{
	column_major float4x4 g_mHistoryXform	: packoffset(c0);	
	float g_fFilterThreshold				: packoffset(c4);
	float g_fHistoryFactor					: packoffset(c4.y);
	float3 g_vFogLight						: packoffset(c5);
	float g_fMultiScattering				: packoffset(c5.w);
};

/*===========================================================================
Shader inputs
===========================================================================*/
struct VS_POLYGONAL_INPUT
{
	float4 vPos : POSITION;
};

struct HS_POLYGONAL_INPUT
{
	float4 vPos : SV_POSITION;
	float4 vWorldPos : TEXCOORD0;
	float4 vClipPos : TEXCOORD1;
};

struct HS_POLYGONAL_CONTROL_POINT_OUTPUT
{
	float4 vWorldPos : TEXCOORD0;
	float4 vClipPos : TEXCOORD1;
};

struct HS_POLYGONAL_CONSTANT_DATA_OUTPUT
{
    float fEdges[4] : SV_TESSFACTOR;
    float fInside[2] : SV_INSIDETESSFACTOR;
    float debug[4] : TEXCOORD2;
};

struct PS_POLYGONAL_INPUT
{
    float4 vPos : SV_POSITION;
    float4 vWorldPos : TEXCOORD0;
#ifdef __PSSL__
	float dummy : CLIPPPOSDUMMY;  //Workaround for compiler exception in polygon hull shaders.
#endif
};

struct VS_QUAD_OUTPUT
{
	float4 vPos : SV_POSITION;
	sample float4 vWorldPos : TEXCOORD0;
	sample float2 vTex : TEXCOORD1;
};

/*===========================================================================
Common functions
===========================================================================*/

float LinearizeDepth(float d, float zn, float zf)
{
	return d * zn / (zf - ((zf - zn) * d));
}

float WarpDepth(float z, float zn, float zf)
{
	return z * (1+zf/zn) / (1+z*zf/zn);
}

float MapDepth(float d, float zn, float zf)
{
	return (d - zn) / (zf - zn);
}

// Approximates a non-normalized gaussian with Sigma == 1
float GaussianApprox(float2 sample_pos, float width)
{
	float x_sqr = sample_pos.x*sample_pos.x + sample_pos.y*sample_pos.y;
	// exp(-0.5*(x/w)^2) ~ (1-(x/(8*w))^2)^32
	float w = saturate(1.0f - x_sqr/(64.0f * width*width));
	w = w*w;	// ^2
	w = w*w;	// ^4
	w = w*w;	// ^8
	w = w*w;	// ^16
	w = w*w;	// ^32
	return w;
}

#if defined(ATTENUATIONMODE)
float AttenuationFunc(float d)
{
    if (ATTENUATIONMODE == ATTENUATIONMODE_POLYNOMIAL)
    {
        // 1-(A+Bx+Cx^2)
        return saturate(1.0f - (g_vLightAttenuationFactors.x + g_vLightAttenuationFactors.y*d + g_vLightAttenuationFactors.z*d*d));
    }
    else if (ATTENUATIONMODE == ATTENUATIONMODE_INV_POLYNOMIAL)
    {
        // 1 / (A+Bx+Cx^2) + D
        return saturate(1.0f / (g_vLightAttenuationFactors.x + g_vLightAttenuationFactors.y*d + g_vLightAttenuationFactors.z*d*d) + g_vLightAttenuationFactors.w);
    }
    else //if (ATTENUATIONMODE == ATTENUATIONMODE_NONE)
    {
        return 1.0f;
    }
}
#endif

float3 GetPhaseFactor(Texture2D tex, float cos_theta)
{
    float2 tc;
    tc.x = 0;
    tc.y = acos(clamp(-cos_theta, -1.0f, 1.0f)) / PI;
    return g_vScatterPower*tex.SampleLevel(sBilinear, tc, 0).rgb;
}