forked from vsg-dev/VulkanSceneGraph
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathassimp_phong_frag.cpp
278 lines (233 loc) · 7.95 KB
/
assimp_phong_frag.cpp
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
#include <vsg/io/VSG.h>
static auto assimp_phong_frag = []() {std::istringstream str(
R"(#vsga 0.4.3
Root id=1 vsg::ShaderStage
{
userObjects 0
stage 16
entryPointName "main"
module id=2 vsg::ShaderModule
{
userObjects 0
hints id=0
source "#version 450
#extension GL_ARB_separate_shader_objects : enable
#pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSACLE_DIFFUSE_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING)
#ifdef VSG_DIFFUSE_MAP
layout(set = 0, binding = 0) uniform sampler2D diffuseMap;
#endif
#ifdef VSG_NORMAL_MAP
layout(set = 0, binding = 2) uniform sampler2D normalMap;
#endif
#ifdef VSG_LIGHTMAP_MAP
layout(set = 0, binding = 3) uniform sampler2D aoMap;
#endif
#ifdef VSG_EMISSIVE_MAP
layout(set = 0, binding = 4) uniform sampler2D emissiveMap;
#endif
#ifdef VSG_SPECULAR_MAP
layout(set = 0, binding = 5) uniform sampler2D specularMap;
#endif
layout(set = 0, binding = 10) uniform MaterialData
{
vec4 ambientColor;
vec4 diffuseColor;
vec4 specularColor;
vec4 emissiveColor;
float shininess;
float alphaMask;
float alphaMaskCutoff;
} material;
layout(set = 1, binding = 0) uniform LightData
{
vec4 values[64];
} lightData;
layout(location = 0) in vec3 eyePos;
layout(location = 1) in vec3 normalDir;
layout(location = 2) in vec4 vertexColor;
#ifndef VSG_POINT_SPRITE
layout(location = 3) in vec2 texCoord0;
#endif
layout(location = 5) in vec3 viewDir;
layout(location = 0) out vec4 outColor;
// Find the normal for this fragment, pulling either from a predefined normal map
// or from the interpolated mesh normal and tangent attributes.
vec3 getNormal()
{
#ifdef VSG_NORMAL_MAP
// Perturb normal, see http://www.thetenthplanet.de/archives/1180
vec3 tangentNormal = texture(normalMap, texCoord0).xyz * 2.0 - 1.0;
//tangentNormal *= vec3(2,2,1);
vec3 q1 = dFdx(eyePos);
vec3 q2 = dFdy(eyePos);
vec2 st1 = dFdx(texCoord0);
vec2 st2 = dFdy(texCoord0);
vec3 N = normalize(normalDir);
vec3 T = normalize(q1 * st2.t - q2 * st1.t);
vec3 B = -normalize(cross(N, T));
mat3 TBN = mat3(T, B, N);
return normalize(TBN * tangentNormal);
#else
return normalize(normalDir);
#endif
}
vec3 computeLighting(vec3 ambientColor, vec3 diffuseColor, vec3 specularColor, vec3 emissiveColor, float shininess, float ambientOcclusion, vec3 ld, vec3 nd, vec3 vd)
{
vec3 color = vec3(0.0);
color.rgb += ambientColor;
float diff = max(dot(ld, nd), 0.0);
color.rgb += diffuseColor * diff;
if (diff > 0.0)
{
vec3 halfDir = normalize(ld + vd);
color.rgb += specularColor * pow(max(dot(halfDir, nd), 0.0), shininess);
}
vec3 result = color + emissiveColor;
result *= ambientOcclusion;
return result;
}
void main()
{
#ifdef VSG_POINT_SPRITE
vec2 texCoord0 = gl_PointCoord.xy;
#endif
vec4 diffuseColor = vertexColor * material.diffuseColor;
#ifdef VSG_DIFFUSE_MAP
#ifdef VSG_GREYSACLE_DIFFUSE_MAP
float v = texture(diffuseMap, texCoord0.st).s;
diffuseColor *= vec4(v, v, v, 1.0);
#else
diffuseColor *= texture(diffuseMap, texCoord0.st);
#endif
#endif
vec4 ambientColor = diffuseColor * material.ambientColor * material.ambientColor.a;
vec4 specularColor = material.specularColor;
vec4 emissiveColor = material.emissiveColor;
float shininess = material.shininess;
float ambientOcclusion = 1.0;
if (material.alphaMask == 1.0f)
{
if (diffuseColor.a < material.alphaMaskCutoff)
discard;
}
#ifdef VSG_EMISSIVE_MAP
emissiveColor *= texture(emissiveMap, texCoord0.st);
#endif
#ifdef VSG_LIGHTMAP_MAP
ambientOcclusion *= texture(aoMap, texCoord0.st).r;
#endif
#ifdef VSG_SPECULAR_MAP
specularColor *= texture(specularMap, texCoord0.st);
#endif
vec3 nd = getNormal();
vec3 vd = normalize(viewDir);
vec3 color = vec3(0.0, 0.0, 0.0);
vec4 lightNums = lightData.values[0];
int numAmbientLights = int(lightNums[0]);
int numDirectionalLights = int(lightNums[1]);
int numPointLights = int(lightNums[2]);
int numSpotLights = int(lightNums[3]);
int index = 1;
if (numAmbientLights>0)
{
// ambient lights
for(int i = 0; i<numAmbientLights; ++i)
{
vec4 lightColor = lightData.values[index++];
color += (ambientColor.rgb * lightColor.rgb) * (lightColor.a);
}
}
if (numDirectionalLights>0)
{
// directional lights
for(int i = 0; i<numDirectionalLights; ++i)
{
vec4 lightColor = lightData.values[index++];
vec3 direction = -lightData.values[index++].xyz;
float unclamped_LdotN = dot(direction, nd);
#ifdef VSG_TWO_SIDED_LIGHTING
if (unclamped_LdotN < 0.0)
{
nd = -nd;
unclamped_LdotN = -unclamped_LdotN;
}
#endif
float diff = max(unclamped_LdotN, 0.0);
color.rgb += (diffuseColor.rgb * lightColor.rgb) * (diff * lightColor.a);
if (shininess > 0.0 && diff > 0.0)
{
vec3 halfDir = normalize(direction + vd);
color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * lightColor.a);
}
}
}
if (numPointLights>0)
{
// point light
for(int i = 0; i<numPointLights; ++i)
{
vec4 lightColor = lightData.values[index++];
vec3 position = lightData.values[index++].xyz;
vec3 delta = position - eyePos;
float distance2 = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
vec3 direction = delta / sqrt(distance2);
float scale = lightColor.a / distance2;
float unclamped_LdotN = dot(direction, nd);
#ifdef VSG_TWO_SIDED_LIGHTING
if (unclamped_LdotN < 0.0)
{
nd = -nd;
unclamped_LdotN = -unclamped_LdotN;
}
#endif
float diff = scale * max(unclamped_LdotN, 0.0);
color.rgb += (diffuseColor.rgb * lightColor.rgb) * diff;
if (shininess > 0.0 && diff > 0.0)
{
vec3 halfDir = normalize(direction + vd);
color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
}
}
}
if (numSpotLights>0)
{
// spot light
for(int i = 0; i<numSpotLights; ++i)
{
vec4 lightColor = lightData.values[index++];
vec4 position_cosInnerAngle = lightData.values[index++];
vec4 lightDirection_cosOuterAngle = lightData.values[index++];
vec3 delta = position_cosInnerAngle.xyz - eyePos;
float distance2 = delta.x * delta.x + delta.y * delta.y + delta.z * delta.z;
vec3 direction = delta / sqrt(distance2);
float dot_lightdirection = dot(lightDirection_cosOuterAngle.xyz, -direction);
float scale = (lightColor.a * smoothstep(lightDirection_cosOuterAngle.w, position_cosInnerAngle.w, dot_lightdirection)) / distance2;
float unclamped_LdotN = dot(direction, nd);
#ifdef VSG_TWO_SIDED_LIGHTING
if (unclamped_LdotN < 0.0)
{
nd = -nd;
unclamped_LdotN = -unclamped_LdotN;
}
#endif
float diff = scale * max(unclamped_LdotN, 0.0);
color.rgb += (diffuseColor.rgb * lightColor.rgb) * diff;
if (shininess > 0.0 && diff > 0.0)
{
vec3 halfDir = normalize(direction + vd);
color.rgb += specularColor.rgb * (pow(max(dot(halfDir, nd), 0.0), shininess) * scale);
}
}
}
outColor.rgb = (color * ambientOcclusion) + emissiveColor.rgb;
outColor.a = diffuseColor.a;
}
"
code 0
}
NumSpecializationConstants 0
}
)");
vsg::VSG io;
return io.read_cast<vsg::ShaderStage>(str);
};