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
|
#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout (set = 1, binding = 0) uniform sampler2D samplerColor;
layout (set = 1, binding = 1) uniform sampler2D samplerNormal;
layout (set = 1, binding = 2) uniform sampler2D samplerOcclusion;
layout (set = 1, binding = 3) uniform sampler2D samplerMetalRoughness;
layout (set = 1, binding = 4) uniform sampler2D samplerEmissive;
layout (location = 0) in vec2 inUV;
layout (location = 1) in vec3 inN;
layout (location = 2) in vec3 inV;//ViewDir
layout (location = 0) out vec4 outFragColor;
layout(push_constant) uniform PushConsts {
layout(offset = 64)
vec4 baseColorFactor;
vec4 emissiveFactor;
uint availableAttachments;
uint alphaMode;
float alphaCutoff;
float metallicFactor;
float roughnessFactor;
} pc;
const uint MAP_COLOR = 0x1;
const uint MAP_NORMAL = 0x2;
const uint MAP_AMBIENTOCCLUSION = 0x4;
const uint MAP_METAL = 0x8;
const uint MAP_ROUGHNESS = 0x16;
const uint MAP_METALROUGHNESS = 0x32;
const uint MAP_EMISSIVE = 0x64;
const float M_PI = 3.141592653589793;
vec3 light = vec3(1.0,.0,1.0);
// http://www.thetenthplanet.de/archives/1180
mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)
{
// get edge vectors of the pixel triangle
vec3 dp1 = dFdx( p );
vec3 dp2 = dFdy( p );
vec2 duv1 = dFdx( uv );
vec2 duv2 = dFdy( uv );
// solve the linear system
vec3 dp2perp = cross( dp2, N );
vec3 dp1perp = cross( N, dp1 );
vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;
vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;
// construct a scale-invariant frame
float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );
return mat3( T * invmax, B * invmax, N );
}
vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord )
{
// assume N, the interpolated vertex normal and
// V, the view vector (vertex to eye)
vec3 map = texture(samplerNormal, texcoord).xyz;
map = map * 255./127. - 128./127.;
mat3 TBN = cotangent_frame(N, -V, texcoord);
return normalize(TBN * map);
}
void main()
{
vec4 base_color = pc.baseColorFactor;
if ((pc.availableAttachments & MAP_COLOR) == MAP_COLOR)
base_color *= texture(samplerColor, inUV);
float rough = pc.roughnessFactor;
float metallic = pc.metallicFactor;
if ((pc.availableAttachments & MAP_METALROUGHNESS) == MAP_METALROUGHNESS) {
rough *= texture(samplerMetalRoughness, inUV).g;
metallic *= texture(samplerMetalRoughness, inUV).b;
}
vec3 emit;
if ((pc.availableAttachments & MAP_EMISSIVE) == MAP_EMISSIVE)
emit = pc.emissiveFactor.rgb * texture(samplerEmissive, inUV).rgb;
vec3 n = normalize(inN);
vec3 l = normalize(light);
vec3 pn = perturb_normal(n, inV, inUV);
float lambert = max(0.0, dot(pn, l));
vec3 f0 = vec3(0.04);
vec3 diff = base_color.rgb * (vec3(1.0) - f0);
diff *= 1.0 - metallic;
diff *= lambert * texture(samplerOcclusion, inUV).r;
diff += emit;
vec3 spec = mix(f0, base_color.rgb, metallic);
vec3 amb = vec3(0.1);
if (lambert >= 0.0) {
vec3 rd = reflect(-l, pn);
float s = dot(rd, normalize(inV));
spec = vec3(0.9,0.9,0.9)* //light.specular.xyz * material.specular.xyz *
pow(max(0.0, s), 10.0); //0.5 = mat shininess
}
outFragColor = vec4(diff + amb + spec , base_color.a); //
}
|