-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathenbeffectprepass.fx
418 lines (346 loc) · 10.7 KB
/
enbeffectprepass.fx
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ENBSeries TES Skyrim SE hlsl DX11 format, sample file
// visit http://enbdev.com for updates
// Author: Boris Vorontsov
// It's similar to enbeffectpostpass.fx, but works with hdr input and output
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//basic example of using skinned objects mask to make edge detection
//+++++++++++++++++++++++++++++
//internal parameters, modify or add new
//+++++++++++++++++++++++++++++
/*
//example parameters with annotations for in-game editor
float ExampleScalar
<
string UIName="Example scalar";
string UIWidget="spinner";
float UIMin=0.0;
float UIMax=1000.0;
> = {1.0};
float3 ExampleColor
<
string UIName = "Example color";
string UIWidget = "color";
> = {0.0, 1.0, 0.0};
float4 ExampleVector
<
string UIName="Example vector";
string UIWidget="vector";
> = {0.0, 1.0, 0.0, 0.0};
int ExampleQuality
<
string UIName="Example quality";
string UIWidget="quality";
int UIMin=0;
int UIMax=3;
> = {1};
Texture2D ExampleTexture
<
string UIName = "Example texture";
string ResourceName = "test.bmp";
>;
SamplerState ExampleSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
*/
int EOutlineType
<
string UIName="OutlineType";
string UIWidget="Spinner";
int UIMin=0;
int UIMax=2;
> = {0};
float EOutlineThickness
<
string UIName="OutlineThickness";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=2.0;
> = {1.0};
float EOutlineFadeDistance
<
string UIName="OutlineFadeDistance";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=3.0;
> = {1.0};
float EOutlineTransparency
<
string UIName="OutlineTransparency";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=1.0;
> = {0.0};
float3 EOutlineColor <
string UIName="OutlineColor";
string UIWidget="Color";
> = {0.0, 0.0, 0.0};
float EOutlineModulateIntensity
<
string UIName="OutlineModulateIntensity";
string UIWidget="Spinner";
float UIMin=0.0;
float UIMax=10.0;
> = {1.0};
float3 EOutlineModulateColor <
string UIName="OutlineModulateColor";
string UIWidget="Color";
> = {0.0, 0.0, 0.0};
//+++++++++++++++++++++++++++++
//external enb parameters, do not modify
//+++++++++++++++++++++++++++++
//x = generic timer in range 0..1, period of 16777216 ms (4.6 hours), y = average fps, w = frame time elapsed (in seconds)
float4 Timer;
//x = Width, y = 1/Width, z = aspect, w = 1/aspect, aspect is Width/Height
float4 ScreenSize;
//changes in range 0..1, 0 means full quality, 1 lowest dynamic quality (0.33, 0.66 are limits for quality levels)
float AdaptiveQuality;
//x = current weather index, y = outgoing weather index, z = weather transition, w = time of the day in 24 standart hours. Weather index is value from weather ini file, for example WEATHER002 means index==2, but index==0 means that weather not captured.
float4 Weather;
//x = dawn, y = sunrise, z = day, w = sunset. Interpolators range from 0..1
float4 TimeOfDay1;
//x = dusk, y = night. Interpolators range from 0..1
float4 TimeOfDay2;
//changes in range 0..1, 0 means that night time, 1 - day time
float ENightDayFactor;
//changes 0 or 1. 0 means that exterior, 1 - interior
float EInteriorFactor;
float FieldOfView;
//+++++++++++++++++++++++++++++
//external enb debugging parameters for shader programmers, do not modify
//+++++++++++++++++++++++++++++
//keyboard controlled temporary variables. Press and hold key 1,2,3...8 together with PageUp or PageDown to modify. By default all set to 1.0
float4 tempF1; //0,1,2,3
float4 tempF2; //5,6,7,8
float4 tempF3; //9,0
// xy = cursor position in range 0..1 of screen;
// z = is shader editor window active;
// w = mouse buttons with values 0..7 as follows:
// 0 = none
// 1 = left
// 2 = right
// 3 = left+right
// 4 = middle
// 5 = left+middle
// 6 = right+middle
// 7 = left+right+middle (or rather cat is sitting on your mouse)
float4 tempInfo1;
// xy = cursor position of previous left mouse button click
// zw = cursor position of previous right mouse button click
float4 tempInfo2;
//+++++++++++++++++++++++++++++
//mod parameters, do not modify
//+++++++++++++++++++++++++++++
Texture2D TextureOriginal; //color R16B16G16A16 64 bit hdr format
Texture2D TextureColor; //color which is output of previous technique (except when drawed to temporary render target), R16B16G16A16 64 bit hdr format
Texture2D TextureDepth; //scene depth R32F 32 bit hdr format
Texture2D TextureJitter; //blue noise
Texture2D TextureMask; //alpha channel is mask for skinned objects (less than 1) and amount of sss
//temporary textures which can be set as render target for techniques via annotations like <string RenderTarget="RenderTargetRGBA32";>
Texture2D RenderTargetRGBA32; //R8G8B8A8 32 bit ldr format
Texture2D RenderTargetRGBA64; //R16B16G16A16 64 bit ldr format
Texture2D RenderTargetRGBA64F; //R16B16G16A16F 64 bit hdr format
Texture2D RenderTargetR16F; //R16F 16 bit hdr format with red channel only
Texture2D RenderTargetR32F; //R32F 32 bit hdr format with red channel only
Texture2D RenderTargetRGB32F; //32 bit hdr format without alpha
SamplerState Sampler0
{
Filter = MIN_MAG_MIP_POINT;//MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
SamplerState Sampler1
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Clamp;
AddressV = Clamp;
};
//+++++++++++++++++++++++++++++
//
//+++++++++++++++++++++++++++++
struct VS_INPUT_POST
{
float3 pos : POSITION;
float2 txcoord : TEXCOORD0;
};
struct VS_OUTPUT_POST
{
float4 pos : SV_POSITION;
float2 txcoord0 : TEXCOORD0;
};
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
VS_OUTPUT_POST VS_PostProcess(VS_INPUT_POST IN)
{
VS_OUTPUT_POST OUT;
float4 pos;
pos.xyz=IN.pos.xyz;
pos.w=1.0;
OUT.pos=pos;
OUT.txcoord0.xy=IN.txcoord.xy;
return OUT;
}
//generate edges
float4 PS_DrawEdge1(VS_OUTPUT_POST IN, float4 v0 : SV_Position0) : SV_Target
{
float4 res;
float4 coord;
coord.zw=0.0;
coord.xy=IN.txcoord0.xy;
float2 invscreensize=ScreenSize.y;
invscreensize.y*=ScreenSize.z;
float4 mask=TextureMask.Sample(Sampler1, coord.xy);
//if (mask.w==1.0) mask=0.0; else mask=1.0;
// mask=(mask.w == 1.0) ? 0.0 : 1.0;
//reduce bugs of alpha test objects
mask.w=1.0-mask.w;
mask.w*=mask.w;
mask.w*=mask.w;
//clip((254.0/255.0) - mask.w); //works properly only with one pass to increase speed, otherwise make one more pass
float depth=TextureDepth.Sample(Sampler1, coord.xy).x;
float origdepth=depth;
depth=1.0/(1.0-depth);
float fadefact=saturate(1.0-depth*0.005*EOutlineFadeDistance);
invscreensize*=fadefact;
invscreensize*=EOutlineThickness;
float2 offset[16]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),
float2(1.0, 0.0),
float2(-1.0, 0.0),
float2(0.0, 1.0),
float2(0.0, -1.0),
float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41),
float2(1.41, 1.41),
float2(-1.41, -1.41),
float2(-1.41, 1.41),
float2(1.41, -1.41)
};
float weight=1.0;
float edges=0.0;
float averagedepth=depth;
for (int i=0; i<16; i++)
{
float tempdepth;
coord.xy=IN.txcoord0.xy + offset[i].xy*invscreensize;
tempdepth=TextureDepth.SampleLevel(Sampler1, coord, 0.0).x;
tempdepth=1.0/(1.0-tempdepth);
float depthdiff=depth-tempdepth;
float4 tempmask=TextureMask.SampleLevel(Sampler1, coord, 0.0);
// tempmask=(tempmask.w == 1.0) ? 0.0 : 1.0;
//reduce bugs of alpha test objects
tempmask.w=1.0-tempmask.w;
tempmask.w*=tempmask.w;
tempmask.w*=tempmask.w;
//if (depthdiff<0.0) tempmask.w=0.0; //remove from overlayed objects
tempmask.w*=saturate(1.0+depthdiff*5.0); //remove from overlayed objects
mask.w=max(tempmask.w, mask.w);
//mask.x=min(tempmask.w, mask.x);
//float tempweight=1.0;
//not works because of linear textures filtering for mask and depth
//tempweight=((depthdiff>0.3) && (tempmask.x==0.0)) ? 0.0 : 1.0; //remove from overlayed objects
//edges+=saturate( depthdiff*4.0 );
edges+=saturate( abs(depthdiff*4.0) );
averagedepth+=tempdepth;
// float tempweight;
// tempweight=saturate( -(depthdiff) );
// averagedepth+=tempdepth * tempweight;
// weight+=tempweight;
}
edges=max(edges-2.0, 0.0); //skip 2 pixels to reduce bugs
edges=saturate(edges);
averagedepth*=1.0/17.0;
//averagedepth/=weight;
float diff=(depth-averagedepth)*8.0;
diff/=max(EOutlineThickness, 0.1); //correction for high scaling
//edges*=saturate( diff ); //outer edges
//edges*=saturate( -diff ); //inner edges
//edges*=saturate( abs(diff) ); //both edges
if (EOutlineType==1) diff=-diff;
if (EOutlineType==2) diff=abs(diff);
edges=saturate( diff );
edges=lerp(0.0, edges, fadefact);
res.w=saturate(edges);
res.xyz=mask.w;
// res.y=saturate(mask.w-mask.x);
return res;
}
//blur previously generated edges and mix with colors
float4 PS_DrawEdge2(VS_OUTPUT_POST IN, float4 v0 : SV_Position0) : SV_Target
{
float4 res;
float4 coord;
coord.zw=0.0;
coord.xy=IN.txcoord0.xy;
float2 invscreensize=ScreenSize.y;
invscreensize.y*=ScreenSize.z;
invscreensize*=0.5;
float4 origcolor=TextureOriginal.Sample(Sampler0, coord.xy);
float4 color=TextureColor.Sample(Sampler0, coord.xy);
float2 offset[16]=
{
float2(1.0, 1.0),
float2(-1.0, -1.0),
float2(-1.0, 1.0),
float2(1.0, -1.0),
float2(1.0, 0.0),
float2(-1.0, 0.0),
float2(0.0, 1.0),
float2(0.0, -1.0),
float2(1.41, 0.0),
float2(-1.41, 0.0),
float2(0.0, 1.41),
float2(0.0, -1.41),
float2(1.41, 1.41),
float2(-1.41, -1.41),
float2(-1.41, 1.41),
float2(1.41, -1.41)
};
for (int i=0; i<8; i++)
{
float4 tempcolor;
coord.xy=IN.txcoord0.xy + offset[i].xy*invscreensize;
tempcolor=TextureColor.SampleLevel(Sampler0, coord, 0.0);
color+=tempcolor;
}
color*=1.0/9.0;
color.w*=color.x;
color.w=saturate(1.0-color.w);
res.xyz=lerp(EOutlineColor.xyz, origcolor.xyz, saturate(color.w+EOutlineTransparency));
color.xyz=lerp(EOutlineModulateColor, 0.0, color.w);
res.xyz+=color * origcolor * EOutlineModulateIntensity;
res.w=1.0;
return res;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// Techniques are drawn one after another and they use the result of
// the previous technique as input color to the next one. The number
// of techniques is limited to 255. If UIName is specified, then it
// is a base technique which may have extra techniques with indexing
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
technique11 DrawEdge <string UIName="DrawEdge";>
{
pass p0
{
SetVertexShader(CompileShader(vs_5_0, VS_PostProcess()));
SetPixelShader(CompileShader(ps_5_0, PS_DrawEdge1()));
}
}
technique11 DrawEdge1
{
pass p0
{
SetVertexShader(CompileShader(vs_5_0, VS_PostProcess()));
SetPixelShader(CompileShader(ps_5_0, PS_DrawEdge2()));
}
}