citro3d
Loading...
Searching...
No Matches
light.h
Go to the documentation of this file.
1/**
2 * @file light.h
3 * @brief Configure dynamic light, shading, and shadows
4 *
5 * \section frag_eqn Fragment Light Equations
6 * The equations used for calculating fragment lighting appears to be as follows:
7 *
8 * \f[ C_{pri} = s^{(a)} + \sum_{i = 0}^{\#lights} a * SpotlightLut(d_0) * o * (l_i^{(d)} * f_i(L_i \cdot N) + l_i^{(a)}) \f]
9 * \f[ C_{sec} = \sum_{i = 0}^{\#lights} a * SpotlightLut(d_0) * h * o * (l_i^{(s_0)}LutD_0(d_1)*G_i^{(0)} + l_i^{(s_1)}LutD_1(d_3)*G_i^{(1)}*ReflectionLutsRGB(d_2)) \f]
10 * \f[ C_{alpha} = FresnelLut(d_4) \f]
11 *
12 * Outputs:
13 * - \f$C_{pri}\f$ - \ref GPU_FRAGMENT_PRIMARY_COLOR
14 * - \f$C_{sec}\f$ - \ref GPU_FRAGMENT_SECONDARY_COLOR
15 * - \f$C_{alpha}\f$ - Primary and/or secondary alpha. Output is selectable using \ref C3D_LightEnvFresnel().
16 *
17 * Inputs, per-fragment:
18 * - \f$a\f$ - Distance attenuation factor calculated from distance attenuation LUT.
19 * - \f$N\f$ - Interpolated normal
20 * - \f$V\f$ - View direction vector (fragment <-> camera)
21 * - \f$T\f$ - Tangent direction vector
22 *
23 * Inputs, per-pass:
24 * - \f$d_{0...4}\f$ - Configurable LUT inputs - one of the following: \f$N \cdot H\f$, \f$V \cdot H_i\f$, \f$N \cdot V\f$, \f$L_i \cdot N\f$, \f$-L_i \cdot P\f$, \f$\cos \phi_i\f$.
25 * - \f$s^{(a)}\f$ - Scene ambient color
26 * - \f$o\f$ - Shadow attenuation from the shadow map (if there is one). Output is selectable using \ref C3D_LightEnvShadowMode().
27 * - \f$h\f$ - Clamps lighting for \f$N \cdot L_i < 0\f$ if \ref C3D_LightEnvClampHighlights() is enabled
28 *
29 * Inputs, per-Light:
30 * - \f$P_i\f$ - Spotlight direction
31 * - \f$L_i\f$ - Light vector (just lightPosition when positional lighting is enabled, lightPosition + view when directional lighting is enabled)
32 * - \f$H_i\f$ - Half-vector between \f$L_i\f$ and \f$V\f$
33 * - \f$\phi_i\f$ - Angle between the projection of \f$H_i\f$ into the tangent plane and \f$T\f$
34 * - \f$f_i\f$ - Clamps product of \f$N \cdot L_i\f$ to zero if \ref C3D_LightTwoSideDiffuse() is disabled for the light source, otherwise gets the absolute value
35 * - \f$l_i^{(a)}\f$ - Light ambient color
36 * - \f$l_i^{(d)}\f$ - Light diffuse color
37 * - \f$l_i^{(s_0)}\f$ - Light specular0 color
38 * - \f$l_i^{(s_1)}\f$ - Light specular1 color
39 * - \f$G_i^{(0)},G_i^{(1)}\f$ - Cook-Torrance geometric factor, or 1 when disabled
40 *
41 * In citro3d, some inputs may be configured by multiple variables, for example:
42 * - \f$s^{(a)}\f$ = mtl.emission + mtl.ambient * env.ambient
43 * - \f$l_i^{(a)}\f$ = mtl.ambient * light.ambient
44 * - \f$l_i^{(d)}\f$ = mtl.diffuse * light.diffuse
45 * - \f$l_i^{(s_0)}\f$ = mtl.specular0 * light.specular0
46 * - \f$l_i^{(s_1)}\f$ = mtl.specular1 * light.specular1
47 *
48 * \sa https://github.com/PabloMK7/citra/blob/baca2bfc6bd0af97ce74b911d69af2391815c9d7/src/video_core/renderer_software/sw_lighting.cpp#L26-L332
49 */
50
51#pragma once
52#include "lightlut.h"
53#include "maths.h"
54
55/// Material
56typedef struct
57{
58 float ambient[3]; ///< Color used for global illumination for the material, multiplied by \ref C3D_LightEnvAmbient()
59 float diffuse[3]; ///< Color used when calculating directional lighting
60 float specular0[3]; ///< Specular color, multiplied by lutD0
61 float specular1[3]; ///< Specular color, multiplied by lutD1
62 float emission[3]; ///< Color used for global illumination for the material, added to the product of the ambient illumination
64
65/**
66 * @name Light Environment
67 * @{
68 */
69
70// Forward declarations
71typedef struct C3D_Light_t C3D_Light;
72typedef struct C3D_LightEnv_t C3D_LightEnv;
73
74typedef struct
75{
76 u32 abs, select, scale;
78
79typedef struct
80{
81 u32 ambient;
82 u32 numLights;
83 u32 config[2];
84 C3D_LightLutInputConf lutInput;
85 u32 permutation;
87
88enum
89{
90 C3DF_LightEnv_Dirty = BIT(0),
91 C3DF_LightEnv_MtlDirty = BIT(1),
92 C3DF_LightEnv_LCDirty = BIT(2),
93
94#define C3DF_LightEnv_IsCP(n) BIT(18+(n))
95#define C3DF_LightEnv_IsCP_Any (0xFF<<18)
96#define C3DF_LightEnv_LutDirty(n) BIT(26+(n))
97#define C3DF_LightEnv_LutDirtyAll (0x3F<<26)
98};
99
101{
102 u32 flags;
103 C3D_LightLut* luts[6];
104 float ambient[3];
105 C3D_Light* lights[8];
106 C3D_LightEnvConf conf;
107 C3D_Material material;
108};
109
110/**
111 * @brief Resets and initializes \ref C3D_LightEnv structure to default values.
112 * @note Using fragment lighting without at least one light source configured and enabled
113 * may result in undefined behavior.
114 * @param[out] env Pointer to light environment structure.
115 * @return Light id on success, negative on failure.
116 * @sa \ref C3D_LightInit()
117 * @sa \ref frag_eqn
118 */
120
121/**
122 * @brief Binds \ref C3D_LightEnv pointer to be used for configuring internal state.
123 * @param[in] env Pointer to light environment structure or NULL to disable the fragment lighting stage altogether.
124 */
126
127/**
128 * @brief Coppies material properties to \ref C3D_LightEnv.
129 * @param[out] env Pointer to light environment structure.
130 * @param[in] mtl Pointer to material properties structure.
131 */
133
134/**
135 * @brief Sets global ambient lighting.
136 * @param[out] env Pointer to light environment structure.
137 * @param[in] r Red component.
138 * @param[in] g Green component.
139 * @param[in] b Blue component.
140 */
141void C3D_LightEnvAmbient(C3D_LightEnv* env, float r, float g, float b);
142
143/**
144 * @brief Uploads pre-calculated lighting lookup table for specified function.
145 * @note For the full lighting equation see the \ref frag_eqn section.
146 * This is used to calculate the values of \ref GPU_FRAGMENT_PRIMARY_COLOR
147 * and \ref GPU_FRAGMENT_SECONDARY_COLOR.
148 * @param[out] env Pointer to light environment structure.
149 * @param[in] lutId Specify function of the lookup table.
150 * @param[in] input Specify arguments of the function.
151 * @param[in] negative If true, the LUT inputs can be read as positive or negative, if false the absolute value of the lut inputs will be used.
152 * @param[in] lut Pointer to pre-computed lookup table, or NULL to disable the function.
153 * @sa \ref LightLut_FromArray()
154 * @sa \ref LightLut_FromFunc()
155 */
156void C3D_LightEnvLut(C3D_LightEnv* env, GPU_LIGHTLUTID lutId, GPU_LIGHTLUTINPUT input, bool negative, C3D_LightLut* lut);
157
158enum
159{
160 GPU_SHADOW_PRIMARY = BIT(16),
161 GPU_SHADOW_SECONDARY = BIT(17),
162 GPU_INVERT_SHADOW = BIT(18),
163 GPU_SHADOW_ALPHA = BIT(19),
164};
165
166/**
167 * @brief Enables or disables writing fresnel and shadow alpha component to \ref GPU_FRAGMENT_PRIMARY_COLOR and \ref GPU_FRAGMENT_SECONDARY_COLOR.
168 * @param[out] env Light environment.
169 * @param[in] selector Output selector, or \ref GPU_NO_FRESNEL to disable writing the alpha
170 * component to both \ref GPU_FRAGMENT_PRIMARY_COLOR and \ref GPU_FRAGMENT_SECONDARY_COLOR.
171 * @sa \ref frag_eqn
172 */
174
175/**
176 * @brief Configures bump map texture properties.
177 * @param[out] env Pointer to light environment structure.
178 * @param[in] mode Bump map type. Use \ref GPU_BUMP_AS_BUMP to specify normal map,
179 * use \ref GPU_BUMP_AS_TANG to specify tangent map, or use \ref GPU_BUMP_NOT_USED to disable bump mapping.
180 * @sa C3D_LightEnvBumpSel()
181 */
183
184/**
185 * @brief Configures bump map texture unit id.
186 * @param[out] env Pointer to light environment structure.
187 * @param[in] texUnit Id of texture unit the bump texture is bound to (IDs 0 through 2).
188 * @sa C3D_LightEnvBumpMode()
189 * @sa C3D_TexBind()
190 */
191void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit);
192
193/**
194 * @brief Configures whether to use the z component of the normal map.
195 * @param[out] env Pointer to light environment structure.
196 * @param[in] enable true enables using the z component from the normal map,
197 * false enables z component reconstruction from the xy components of the normal map.
198 */
199void C3D_LightEnvBumpNormalZ(C3D_LightEnv *env, bool enable);
200
201/**
202 * @brief Configures shadow mapping behavior.
203 * @param[out] env Pointer to light environment structure.
204 * @param[in] mode One or more of the following bitflags, \ref GPU_SHADOW_PRIMARY,
205 * \ref GPU_SHADOW_SECONDARY, \ref GPU_INVERT_SHADOW, and \ref GPU_SHADOW_ALPHA.
206 */
208
209/**
210 * @brief Configures shadow mapping texture.
211 * @note Shadow depth textures must be assigned to texture unit 0.
212 * @param[out] env Pointer to light environment structure.
213 * @param[in] texUnit Id of texture unit the shadow texture is bound to (IDs 0 through 2).
214 */
215void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit);
216
217/**
218 * @brief Enables or disables clamping specular highlights.
219 * @param[out] env Pointer to light environment structure.
220 * @param[in] clamp true to enable clamping specular highlights based on the normal vector,
221 * false to disable clamping specular highlights.
222 */
224
225/** @} */
226
227/**
228 * @name Light
229 * @{
230 */
231
232typedef struct
233{
234 u32 specular0, specular1, diffuse, ambient;
236
237typedef struct
238{
239 C3D_LightMatConf material;
240 u16 position[3]; u16 padding0;
241 u16 spotDir[3]; u16 padding1;
242 u32 padding2;
243 u32 config;
244 u32 distAttnBias, distAttnScale;
246
247enum
248{
249 C3DF_Light_Enabled = BIT(0),
250 C3DF_Light_Dirty = BIT(1),
251 C3DF_Light_MatDirty = BIT(2),
252 //C3DF_Light_Shadow = BIT(3),
253 //C3DF_Light_Spot = BIT(4),
254 //C3DF_Light_DistAttn = BIT(5),
255
256 C3DF_Light_SPDirty = BIT(14),
257 C3DF_Light_DADirty = BIT(15),
258};
259
261{
262 u16 flags, id;
263 C3D_LightEnv* parent;
264 C3D_LightLut *lut_SP, *lut_DA;
265 float ambient[3];
266 float diffuse[3];
267 float specular0[3];
268 float specular1[3];
269 C3D_LightConf conf;
270};
271
272/**
273 * @brief Adds light to \ref C3D_LightEnv.
274 * @note Only 8 lights can be configured simultaneously.
275 * @param[in] light Light struct to add to light environment.
276 * @param[out] env Light environment.
277 * @return Light id on success, negative on failure.
278 * @sa \ref frag_eqn
279 */
281
282/**
283 * @brief Enables or disables light source.
284 * @note At least one light source must be enabled at all times. Disabling all
285 * light sources will result in undefined behavior.
286 * @param[out] light Light source structure.
287 * @param[in] enable true to enable light source, false to disable light source.
288 */
289void C3D_LightEnable(C3D_Light* light, bool enable);
290
291/**
292 * @brief Enables or disables light source.
293 * @param[out] light Light source structure.
294 * @param[in] enable true to enable two sided lighting (illuminates both the inside and outside of a mesh),
295 * false to disable two sided lighting.
296 */
297void C3D_LightTwoSideDiffuse(C3D_Light* light, bool enable);
298
299/**
300 * @brief Enables or disables cock-torrance geometric factor.
301 * @param[out] light Light source structure.
302 * @param[in] id Geometric factor id. (0 or 1)
303 * @param[in] enable true to enable geometric factor id, false to disable it.
304 */
305void C3D_LightGeoFactor(C3D_Light* light, int id, bool enable);
306
307/**
308 * @brief Configures global ambient color emitted by light source.
309 * @param[out] light Light source structure.
310 * @param[in] r Red component.
311 * @param[in] g Green component.
312 * @param[in] b Blue component.
313 */
314void C3D_LightAmbient(C3D_Light* light, float r, float g, float b);
315
316/**
317 * @brief Configures diffuse lighting color emitted by light source.
318 * @param[out] light Light source structure.
319 * @param[in] r Red component.
320 * @param[in] g Green component.
321 * @param[in] b Blue component.
322 */
323void C3D_LightDiffuse(C3D_Light* light, float r, float g, float b);
324
325/**
326 * @brief Configures specular0 lighting color emitted by light source.
327 * @param[out] light Light source structure.
328 * @param[in] r Red component.
329 * @param[in] g Green component.
330 * @param[in] b Blue component.
331 */
332void C3D_LightSpecular0(C3D_Light* light, float r, float g, float b);
333
334/**
335 * @brief Configures specular1 lighting color emitted by light source.
336 * @param[out] light Light source structure.
337 * @param[in] r Red component.
338 * @param[in] g Green component.
339 * @param[in] b Blue component.
340 */
341void C3D_LightSpecular1(C3D_Light* light, float r, float g, float b);
342
343/**
344 * @brief Configures light position vector.
345 * @note The w-component of the position vector is a flag where
346 * 0 specifies positional lighting and any other value specifies directional lighting.
347 * @param[out] light Light source structure.
348 * @param[in] pos Position vector.
349 */
351
352/**
353 * @brief Enables or disables shadow mapping on light source.
354 * @note The shadow mapping texture can be specified using \ref C3D_LightEnvShadowSel().
355 * @param[out] light Light source structure.
356 * @param[in] enable true to enable shadow mapping, false to disable shadow mapping.
357 */
358void C3D_LightShadowEnable(C3D_Light* light, bool enable);
359
360/**
361 * @brief Enables or disables spot light for specified light source.
362 * @param[out] light Light source structure.
363 * @param[in] enable true to enable spot light, false to disable spot light.
364 */
365void C3D_LightSpotEnable(C3D_Light* light, bool enable);
366
367/**
368 * @brief Configures spot light direction vector for specified light source.
369 * @param[out] light Light source structure.
370 * @param[in] x X component.
371 * @param[in] y Y component.
372 * @param[in] z Z component.
373 */
374void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z);
375
376/**
377 * @brief Configures spotlight lookup table.
378 * @param[out] light Light source structure.
379 * @param[in] lut Pointer to pre-computed lighting lookup table.
380 */
382
383/**
384 * @brief Enables or disables distance attenuation for specified light source.
385 * @param[out] light Light source structure.
386 * @param[in] enable Enable distance attenuation factor for light source.
387 */
388void C3D_LightDistAttnEnable(C3D_Light* light, bool enable);
389
390/**
391 * @brief Uploads pre-calculated distance attenuation lookup table for specified light source.
392 * @param[out] light Light source structure.
393 * @param[in] lut Pointer to pre-computed distance attenuation lookup table.
394 */
396
397/**
398 * @brief Configures diffuse and specular0/1 color emitted by light source.
399 * @param[out] light Light source structure.
400 * @param[in] r Red component.
401 * @param[in] g Green component.
402 * @param[in] b Blue component.
403 */
404static inline void C3D_LightColor(C3D_Light* light, float r, float g, float b)
405{
406 C3D_LightDiffuse(light, r, g, b);
407 C3D_LightSpecular0(light, r, g, b);
408 C3D_LightSpecular1(light, r, g, b);
409}
410
411/** @} */
GPU_FRESNELSEL
GPU_LIGHTLUTID
GPU_BUMPMODE
GPU_LIGHTLUTINPUT
void C3D_LightEnvMaterial(C3D_LightEnv *env, const C3D_Material *mtl)
Coppies material properties to C3D_LightEnv.
void C3D_LightSpecular0(C3D_Light *light, float r, float g, float b)
Configures specular0 lighting color emitted by light source.
void C3D_LightAmbient(C3D_Light *light, float r, float g, float b)
Configures global ambient color emitted by light source.
void C3D_LightEnable(C3D_Light *light, bool enable)
Enables or disables light source.
void C3D_LightEnvLut(C3D_LightEnv *env, GPU_LIGHTLUTID lutId, GPU_LIGHTLUTINPUT input, bool negative, C3D_LightLut *lut)
Uploads pre-calculated lighting lookup table for specified function.
void C3D_LightEnvBumpSel(C3D_LightEnv *env, int texUnit)
Configures bump map texture unit id.
void C3D_LightEnvBumpMode(C3D_LightEnv *env, GPU_BUMPMODE mode)
Configures bump map texture properties.
void C3D_LightEnvAmbient(C3D_LightEnv *env, float r, float g, float b)
Sets global ambient lighting.
void C3D_LightEnvBind(C3D_LightEnv *env)
Binds C3D_LightEnv pointer to be used for configuring internal state.
void C3D_LightShadowEnable(C3D_Light *light, bool enable)
Enables or disables shadow mapping on light source.
void C3D_LightSpecular1(C3D_Light *light, float r, float g, float b)
Configures specular1 lighting color emitted by light source.
void C3D_LightEnvFresnel(C3D_LightEnv *env, GPU_FRESNELSEL selector)
Enables or disables writing fresnel and shadow alpha component to GPU_FRAGMENT_PRIMARY_COLOR and GPU_...
void C3D_LightEnvShadowMode(C3D_LightEnv *env, u32 mode)
Configures shadow mapping behavior.
void C3D_LightPosition(C3D_Light *light, C3D_FVec *pos)
Configures light position vector.
void C3D_LightEnvBumpNormalZ(C3D_LightEnv *env, bool enable)
Configures whether to use the z component of the normal map.
void C3D_LightTwoSideDiffuse(C3D_Light *light, bool enable)
Enables or disables light source.
void C3D_LightDistAttnEnable(C3D_Light *light, bool enable)
Enables or disables distance attenuation for specified light source.
void C3D_LightSpotEnable(C3D_Light *light, bool enable)
Enables or disables spot light for specified light source.
void C3D_LightGeoFactor(C3D_Light *light, int id, bool enable)
Enables or disables cock-torrance geometric factor.
void C3D_LightSpotLut(C3D_Light *light, C3D_LightLut *lut)
Configures spotlight lookup table.
void C3D_LightDistAttn(C3D_Light *light, C3D_LightLutDA *lut)
Uploads pre-calculated distance attenuation lookup table for specified light source.
void C3D_LightDiffuse(C3D_Light *light, float r, float g, float b)
Configures diffuse lighting color emitted by light source.
void C3D_LightSpotDir(C3D_Light *light, float x, float y, float z)
Configures spot light direction vector for specified light source.
void C3D_LightEnvShadowSel(C3D_LightEnv *env, int texUnit)
Configures shadow mapping texture.
int C3D_LightInit(C3D_Light *light, C3D_LightEnv *env)
Adds light to C3D_LightEnv.
void C3D_LightEnvInit(C3D_LightEnv *env)
Resets and initializes C3D_LightEnv structure to default values.
void C3D_LightEnvClampHighlights(C3D_LightEnv *env, bool clamp)
Enables or disables clamping specular highlights.
static void C3D_LightColor(C3D_Light *light, float r, float g, float b)
Configures diffuse and specular0/1 color emitted by light source.
Definition light.h:404
Generate lighting lookup tables.
Basic math library for matrix, vector, and quaternion operations.
Definition light.h:238
Definition light.h:80
Definition light.h:101
Definition lightlut.h:15
Definition light.h:75
Definition lightlut.h:10
Definition light.h:233
Definition light.h:261
Material.
Definition light.h:57
#define BIT(n)
uint16_t u16
uint32_t u32
Float vector.
Definition types.h:52