summaryrefslogtreecommitdiffstats
path: root/src/datavis3d/engine/shaders/fragmentShadowNoTex
blob: a08b6b402f7b14d801ddd79bbc67c47720a9ba70 (plain)
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
#version 120
//#version 130 // use with version 1

uniform highp float lightStrength;
uniform highp float ambientStrength;
uniform highp float shadowQuality;
uniform highp vec3 color_mdl;
uniform highp sampler2DShadow shadowMap; // use with version 2
//uniform highp sampler2D shadowMap; // use with version 1

varying highp vec4 shadowCoord;
varying highp vec2 UV;
varying highp vec3 position_wrld;
varying highp vec3 normal_cmr;
varying highp vec3 eyeDirection_cmr;
varying highp vec3 lightDirection_cmr;

const highp vec2 poissonDisk[16] = vec2[](vec2(-0.94201624, -0.39906216),
                                          vec2(0.94558609, -0.76890725),
                                          vec2(-0.094184101, -0.92938870),
                                          vec2(0.34495938, 0.29387760),
                                          vec2(-0.91588581, 0.45771432),
                                          vec2(-0.81544232, -0.87912464),
                                          vec2(-0.38277543, 0.27676845),
                                          vec2(0.97484398, 0.75648379),
                                          vec2(0.44323325, -0.97511554),
                                          vec2(0.53742981, -0.47373420),
                                          vec2(-0.26496911, -0.41893023),
                                          vec2(0.79197514, 0.19090188),
                                          vec2(-0.24188840, 0.99706507),
                                          vec2(-0.81409955, 0.91437590),
                                          vec2(0.19984126, 0.78641367),
                                          vec2(0.14383161, -0.14100790));

/*const highp vec2 poissonDisk[16] = vec2[](vec2(-0.25, -0.25),
                                          vec2(0.25, -0.25),
                                          vec2(-0.25, 0.25),
                                          vec2(0.25, 0.25),
                                          vec2(-0.5, -0.5),
                                          vec2(0.5, -0.5),
                                          vec2(-0.5, 0.5),
                                          vec2(0.5, 0.5),
                                          vec2(-0.75, -0.75),
                                          vec2(0.75, -0.75),
                                          vec2(-0.75, 0.75),
                                          vec2(0.75, 0.75),
                                          vec2(-1.0, -1.0),
                                          vec2(1.0, -1.0),
                                          vec2(-1.0, 1.0),
                                          vec2(1.0, 1.0));*/

/*float random(vec3 seed, int i) {
    vec4 seed4 = vec4(seed, i);
    float dot_product = dot(seed4, vec4(12.9898, 78.233, 45.164, 94.673));
    return fract(sin(dot_product) * 43758.5453);
}*/

// Version 1: Causes self-shadowing, but shadows are smooth
/*void main() {
    float shadowFactor = 1.0; // default to '1' meaning "no shadow"
    vec4 shadCoordsPD = shadowCoord;
    shadCoordsPD.z += 0.005;
    shadCoordsPD /= shadowCoord.w;
    if (shadowCoord.w <= 0.0) { // ignore negative projection
        shadowFactor = 1.0;
    } else if (shadCoordsPD.x < 0.0 || shadCoordsPD.y < 0.0) { // outside light frustum, ignore
        shadowFactor = 1.0;
    } else if (shadCoordsPD.x >= 1.0 || shadCoordsPD.y >= 1.0) { // outside light frustum, ignore
        shadowFactor = 1.0;
    } else {
        // This does not work perfectly. It causes self-shadowing, which we should get rid of.
        // Requires at least #version 130
        float shadow = 0.0;
        shadow += textureProjOffset(shadowMap, shadCoordsPD, ivec2(0, 0));
        shadow += textureProjOffset(shadowMap, shadCoordsPD, ivec2(-1, 1));
        shadow += textureProjOffset(shadowMap, shadCoordsPD, ivec2(1, 1));
        shadow += textureProjOffset(shadowMap, shadCoordsPD, ivec2(-1, -1));
        shadow += textureProjOffset(shadowMap, shadCoordsPD, ivec2(1, -1));
        shadow *= 0.2;
        shadowFactor = shadow;
    }

    highp vec3 materialDiffuseColor = color_mdl.rgb;
    highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
    highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);

    highp vec3 n = normalize(normal_cmr);
    highp vec3 l = normalize(lightDirection_cmr);
    highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);

    highp vec3 E = normalize(eyeDirection_cmr);
    highp vec3 R = reflect(-l, n);
    highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);

    // Shadow strength can be adjusted by using pow(shadowFactor, strength), but it causes self-shadowing issues that need to be solved
    gl_FragColor.rgb =
        shadowFactor * (materialAmbientColor +
        materialDiffuseColor * lightStrength * cosTheta +
        materialSpecularColor * lightStrength * pow(cosAlpha, 20));
    gl_FragColor.a = 1.0;
}*/

// Version 2: Shadows are a bit rugged (may be fixed with poisson disk?)
void main() {
    highp vec3 materialDiffuseColor = color_mdl.rgb;
    highp vec3 materialAmbientColor = vec3(ambientStrength, ambientStrength, ambientStrength) * materialDiffuseColor;
    highp vec3 materialSpecularColor = vec3(1.0, 1.0, 1.0);

    highp vec3 n = normalize(normal_cmr);
    highp vec3 l = normalize(lightDirection_cmr);
    highp float cosTheta = clamp(dot(n, l), 0.0, 1.0);

    highp vec3 E = normalize(eyeDirection_cmr);
    highp vec3 R = reflect(-l, n);
    highp float cosAlpha = clamp(dot(E, R), 0.0, 1.0);

    highp float bias = 0.005 * tan(acos(cosTheta));
    bias = clamp(bias, 0.0, 0.01);

    vec4 shadCoords = shadowCoord;
    shadCoords.z -= bias;
    // adjust shadow strength by increasing the multiplier and lowering the addition (their sum must be 1)
    // direct method; needs large shadow texture to look good
    //highp float visibility = 0.75 * shadow2DProj(shadowMap, shadCoords).r + 0.25;
    // poisson disk sampling; smoothes edges
    highp float visibility = 0.2;
    for (int i = 0; i < 15; i++) {
        vec4 shadCoordsPD = shadCoords;
        shadCoordsPD.x += cos(poissonDisk[i].x) / shadowQuality;
        shadCoordsPD.y += sin(poissonDisk[i].y) / shadowQuality;
        visibility += 0.05 * shadow2DProj(shadowMap, shadCoordsPD).r;
    }
    // stratified poisson; produces noise but hides pixel edges well
    /*for (int i = 0; i < 15; i++) {
        vec4 shadCoordsPD = shadCoords;
        int index = int(16.0 * random(gl_FragCoord.xyy, i));
        shadCoordsPD.xy += poissonDisk[index] / 150.0;
        visibility += 0.05 * shadow2DProj(shadowMap, shadCoordsPD).r;
    }
    */

    gl_FragColor.rgb =
        visibility * (materialAmbientColor +
        materialDiffuseColor * lightStrength * cosTheta +
        materialSpecularColor * lightStrength * pow(cosAlpha, 10));
    gl_FragColor.a = 1.0;
}