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

volumetric_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: e0a79872928e6b09f5a7d2df40932b044affbe09 (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
148
149
150
151
152
153
154
155
156
157
158

#pragma BLENDER_REQUIRE(volumetric_lib.glsl)

/* Based on Frosbite Unified Volumetric.
 * https://www.ea.com/frostbite/news/physically-based-unified-volumetric-rendering-in-frostbite */

#ifdef MESH_SHADER
uniform vec3 volumeOrcoLoc;
uniform vec3 volumeOrcoSize;
uniform mat4 volumeObjectToTexture;
uniform float volumeDensityScale = 1.0;
#endif

flat in int slice;

/* Warning: these are not attributes, these are global vars. */
vec3 worldPosition = vec3(0.0);
vec3 viewPosition = vec3(0.0);
vec3 viewNormal = vec3(0.0);
vec3 volumeOrco = vec3(0.0);

layout(location = 0) out vec4 volumeScattering;
layout(location = 1) out vec4 volumeExtinction;
layout(location = 2) out vec4 volumeEmissive;
layout(location = 3) out vec4 volumePhase;

/* Store volumetric properties into the froxel textures. */

#ifdef MESH_SHADER
GlobalData init_globals(void)
{
  GlobalData surf;
  surf.P = worldPosition;
  surf.N = vec3(0.0);
  surf.Ng = vec3(0.0);
  surf.is_strand = false;
  surf.hair_time = 0.0;
  surf.hair_thickness = 0.0;
  surf.hair_strand_id = 0;
  surf.barycentric_coords = vec2(0.0);
  surf.barycentric_dists = vec3(0.0);
  surf.ray_type = RAY_TYPE_CAMERA;
  surf.ray_depth = 0.0;
  surf.ray_length = distance(surf.P, cameraPos);
  return surf;
}

vec3 coordinate_camera(vec3 P)
{
  vec3 vP;
  vP = transform_point(ViewMatrix, P);
  vP.z = -vP.z;
  return vP;
}

vec3 coordinate_screen(vec3 P)
{
  vec3 window = vec3(0.0);
  window.xy = project_point(ViewProjectionMatrix, P).xy * 0.5 + 0.5;
  window.xy = window.xy * CameraTexCoFactors.xy + CameraTexCoFactors.zw;
  return window;
}

vec3 coordinate_reflect(vec3 P, vec3 N)
{
  return vec3(0.0);
}

vec3 coordinate_incoming(vec3 P)
{
  return cameraVec(P);
}
#endif

void main()
{
  ivec3 volume_cell = ivec3(ivec2(gl_FragCoord.xy), slice);
  vec3 ndc_cell = volume_to_ndc((vec3(volume_cell) + volJitter.xyz) * volInvTexSize.xyz);

  viewPosition = get_view_space_from_depth(ndc_cell.xy, ndc_cell.z);
  worldPosition = point_view_to_world(viewPosition);
#ifdef MESH_SHADER
  volumeOrco = point_world_to_object(worldPosition);
  /* TODO: redundant transform */
  volumeOrco = (volumeOrco - volumeOrcoLoc + volumeOrcoSize) / (volumeOrcoSize * 2.0);
  volumeOrco = (volumeObjectToTexture * vec4(volumeOrco, 1.0)).xyz;

  if (any(lessThan(volumeOrco, vec3(0.0))) || any(greaterThan(volumeOrco, vec3(1.0)))) {
    /* Note: Discard is not an explicit return in Metal prior to versions 2.3.
     * adding return after discard ensures consistent behaviour and avoids GPU
     * side-effects where control flow continues with undefined values. */
    discard;
    return;
  }
#endif

#ifdef CLEAR
  volumeScattering = vec4(0.0, 0.0, 0.0, 1.0);
  volumeExtinction = vec4(0.0, 0.0, 0.0, 1.0);
  volumeEmissive = vec4(0.0, 0.0, 0.0, 1.0);
  volumePhase = vec4(0.0, 0.0, 0.0, 0.0);
#else
#  ifdef MESH_SHADER
  g_data = init_globals();
  attrib_load();
#  endif
  Closure cl = nodetree_exec();
#  ifdef MESH_SHADER
  cl.scatter *= volumeDensityScale;
  cl.absorption *= volumeDensityScale;
  cl.emission *= volumeDensityScale;
#  endif

  volumeScattering = vec4(cl.scatter, 1.0);
  volumeExtinction = vec4(cl.absorption + cl.scatter, 1.0);
  volumeEmissive = vec4(cl.emission, 1.0);
  /* Do not add phase weight if no scattering. */
  if (all(equal(cl.scatter, vec3(0.0)))) {
    volumePhase = vec4(0.0);
  }
  else {
    volumePhase = vec4(cl.anisotropy, vec3(1.0));
  }
#endif
}

vec3 attr_load_orco(vec4 orco)
{
  return volumeOrco;
}
vec4 attr_load_tangent(vec4 tangent)
{
  return vec4(0);
}
vec4 attr_load_vec4(vec4 attr)
{
  return vec4(0);
}
vec3 attr_load_vec3(vec3 attr)
{
  return vec3(0);
}
vec2 attr_load_vec2(vec2 attr)
{
  return vec2(0);
}
float attr_load_float(float attr)
{
  return 0.0;
}
vec4 attr_load_color(vec4 attr)
{
  return vec4(0);
}
vec3 attr_load_uv(vec3 attr)
{
  return vec3(0);
}