Welcome to mirror list, hosted at ThFree Co, Russian Federation.

lightprobe_sh_frag.glsl « shaders « eevee « engines « draw « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 1bb14b76f42f6d64564104a4a3c708f61f51baa9 (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

uniform samplerCube probeHdr;
uniform int probeSize;
uniform float lodBias;

in vec3 worldPosition;

out vec4 FragColor;

#define M_4PI 12.5663706143591729

const mat3 CUBE_ROTATIONS[6] = mat3[](
	mat3(vec3( 0.0,  0.0, -1.0),
		 vec3( 0.0, -1.0,  0.0),
		 vec3(-1.0,  0.0,  0.0)),
	mat3(vec3( 0.0,  0.0,  1.0),
		 vec3( 0.0, -1.0,  0.0),
		 vec3( 1.0,  0.0,  0.0)),
	mat3(vec3( 1.0,  0.0,  0.0),
		 vec3( 0.0,  0.0,  1.0),
		 vec3( 0.0, -1.0,  0.0)),
	mat3(vec3( 1.0,  0.0,  0.0),
		 vec3( 0.0,  0.0, -1.0),
		 vec3( 0.0,  1.0,  0.0)),
	mat3(vec3( 1.0,  0.0,  0.0),
		 vec3( 0.0, -1.0,  0.0),
		 vec3( 0.0,  0.0, -1.0)),
	mat3(vec3(-1.0,  0.0,  0.0),
		 vec3( 0.0, -1.0,  0.0),
		 vec3( 0.0,  0.0,  1.0)));

vec3 get_cubemap_vector(vec2 co, int face)
{
	return normalize(CUBE_ROTATIONS[face] * vec3(co * 2.0 - 1.0, 1.0));
}

float area_element(float x, float y)
{
    return atan(x * y, sqrt(x * x + y * y + 1));
}
 
float texel_solid_angle(vec2 co, float halfpix)
{
	vec2 v1 = (co - vec2(halfpix)) * 2.0 - 1.0;
	vec2 v2 = (co + vec2(halfpix)) * 2.0 - 1.0;

	return area_element(v1.x, v1.y) - area_element(v1.x, v2.y) - area_element(v2.x, v1.y) + area_element(v2.x, v2.y);
}

void main()
{
	float pixstep = 1.0 / probeSize;
	float halfpix = pixstep / 2.0;

	float weight_accum = 0.0;
	vec3 sh = vec3(0.0);

	int shnbr = int(floor(gl_FragCoord.x));

	for (int face = 0; face < 6; ++face) {
		for (float x = halfpix; x < 1.0; x += pixstep) {
			for (float y = halfpix; y < 1.0; y += pixstep) {
				float shcoef;

				vec2 facecoord = vec2(x,y);
				vec3 cubevec = get_cubemap_vector(facecoord, face);
				float weight = texel_solid_angle(facecoord, halfpix);

				if (shnbr == 0) {
					shcoef = 0.282095;
				}
				else if (shnbr == 1) {
					shcoef = -0.488603 * cubevec.z * 2.0 / 3.0;
				}
				else if (shnbr == 2) {
					shcoef = 0.488603 * cubevec.y * 2.0 / 3.0;
				}
				else if (shnbr == 3) {
					shcoef = -0.488603 * cubevec.x * 2.0 / 3.0;
				}
				else if (shnbr == 4) {
					shcoef = 1.092548 * cubevec.x * cubevec.z * 1.0 / 4.0;
				}
				else if (shnbr == 5) {
					shcoef = -1.092548 * cubevec.z * cubevec.y * 1.0 / 4.0;
				}
				else if (shnbr == 6) {
					shcoef = 0.315392 * (3.0 * cubevec.y * cubevec.y - 1.0) * 1.0 / 4.0;
				}
				else if (shnbr == 7) {
					shcoef = 1.092548 * cubevec.x * cubevec.y * 1.0 / 4.0;
				}
				else { /* (shnbr == 8) */
					shcoef = 0.546274 * (cubevec.x * cubevec.x - cubevec.z * cubevec.z) * 1.0 / 4.0;
				}

				vec4 sample = textureLod(probeHdr, cubevec, lodBias);
				sh += sample.rgb * shcoef * weight;
				weight_accum += weight;
			}
		}
	}

	sh *= M_4PI / weight_accum;

	FragColor = vec4(sh, 1.0);
}