-
Notifications
You must be signed in to change notification settings - Fork 1
/
lighting.h
120 lines (104 loc) · 2.76 KB
/
lighting.h
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
/*
* File: lighting.h
* Author: alexander.busarov
*
* Created on November 22, 2017, 1:52 PM
*/
#include "hlsl.h"
#include "matrices.h"
#ifndef LIGHTING_H
#define LIGHTING_H
struct LightItem {
float Kind : Kind;
float Dist : Dist;
float2 wPos : wPos;
float4 Color : Color;
};
struct LightNode {
uint LightIdx : LightIdx;
uint Next : Next;
};
Texture2D<uint> LightHead;
StructuredBuffer<LightNode> LightList;
StructuredBuffer<LightItem> LightData;
StructuredBuffer<float3x3> LightProj;
Texture2D ShadowMap; SamplerState ShadowMapSampler;
float LightZ;
#define SHADOW_SAMPLES 5
float EvalShadow(float2 p, float2 dir, float y, uint lightIdx) {
uint side;
if (abs(dir.y)>abs(dir.x)) {
if (dir.y < 0) {
side = 1;
} else {
side = 3;
}
} else {
if (dir.x < 0) {
side = 2;
} else {
side = 0;
}
}
float3x3 m = LightProj[lightIdx*8+side];
float3 pp = mul(m, float3(p,1.0));
pp.xy /= pp.z;
pp.x += 1.0;
pp.x *= 0.5;
float4 shadow = ShadowMap.SampleLevel(ShadowMapSampler, float2(pp.x, y), 0);
float d = 0;
switch (side) {
case 0: d = shadow.x; break;
case 1: d = shadow.y; break;
case 2: d = shadow.z; break;
case 3: d = shadow.w; break;
}
if (d > pp.y) {
return pow(saturate(d),1/5.0);
} else {
return 1.0;
};
}
float4 ApplyLight(uint lightIdx, float2 p) {
LightItem l = LightData[lightIdx];
//lighting
float2 dir = p - l.wPos;
float dist = length(dir);
float att = saturate(1.0 - dist/l.Dist);
//return lerp(0.0, l.Color*1.0, att*att);
float shadowSumm = 0;
if (dot(dir, dir) > 0) {
float smw, smh;
ShadowMap.GetDimensions(smw, smh);
float y = (lightIdx+0.5)/smh;
float2 n = float2(-dir.y, dir.x)*0.00625;
for (uint i = 0; i<SHADOW_SAMPLES; i++) {
float2 psample = p-n*(SHADOW_SAMPLES - 1.0)*0.5+i*n;
shadowSumm += EvalShadow(psample, psample - l.wPos, y, lightIdx);
}
shadowSumm /= SHADOW_SAMPLES;
} else {
shadowSumm = 1.0;
}
return lerp(0.0, l.Color*1.0, att*att*shadowSumm);
}
float4 ApplyLighting(float2 UV, float2 Pos) {
float4 Out = 0.0;
uint2 pix = floor(UV*0.9999*(64.0));
uint idx = LightHead[pix];
//return UV.xyxy;
//idx = 0;
//return (idx != 0xFFFFFFFF)*100.0;
for (int i = 0; i < 30; i++){
if (idx != 0xFFFFFFFF) {
LightNode ln = LightList[idx];
Out += ApplyLight(ln.LightIdx, Pos);
idx = ln.Next;
//Out += 1.0;
} else {
return Out;
}
}
return Out;
}
#endif /* LIGHTING_H */