mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
Lighting Engine: Awesome Edition
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
Some checks are pending
Build coop / build-linux (push) Waiting to run
Build coop / build-steamos (push) Waiting to run
Build coop / build-windows-opengl (push) Waiting to run
Build coop / build-windows-directx (push) Waiting to run
Build coop / build-macos-arm (push) Waiting to run
Build coop / build-macos-intel (push) Waiting to run
Just making a brief commit and thats all to add onto dj's lighting engine improvements because I heard about the PR, in mine I * allowed all Vtx objects to be manipulated/retrieved * updated lighting engine demo to be an SM64 night mode with a flashlight * Fixed longterm bug where lighting bugs out unless you spawn a light * Added new default LE mode LE_MODE_AFFECT_ALL_SHADED_AND_COLORED which also affects vertex colored surfaces
This commit is contained in:
parent
82ca45eeb6
commit
7009e7da86
13 changed files with 218 additions and 117 deletions
|
|
@ -52,7 +52,8 @@ in_files = [
|
||||||
"src/pc/network/lag_compensation.h",
|
"src/pc/network/lag_compensation.h",
|
||||||
"src/pc/djui/djui_panel_menu.h",
|
"src/pc/djui/djui_panel_menu.h",
|
||||||
"src/engine/lighting_engine.h",
|
"src/engine/lighting_engine.h",
|
||||||
"include/PR/gbi.h"
|
"include/PR/gbi.h",
|
||||||
|
"include/PR/gbi_extension.h"
|
||||||
]
|
]
|
||||||
|
|
||||||
exclude_constants = {
|
exclude_constants = {
|
||||||
|
|
@ -106,7 +107,8 @@ include_constants = {
|
||||||
"^G_SETSCISSOR$",
|
"^G_SETSCISSOR$",
|
||||||
"^G_TEXRECTFLIP$",
|
"^G_TEXRECTFLIP$",
|
||||||
"^G_TEXRECT$",
|
"^G_TEXRECT$",
|
||||||
]
|
],
|
||||||
|
"include/PR/gbi_extension.h": [ "G_VTX_EXT" ]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Constants that exist in the source code but should not appear
|
# Constants that exist in the source code but should not appear
|
||||||
|
|
|
||||||
|
|
@ -2933,6 +2933,9 @@ G_TEXRECTFLIP = 0xe5
|
||||||
--- @type integer
|
--- @type integer
|
||||||
G_TEXRECT = 0xe4
|
G_TEXRECT = 0xe4
|
||||||
|
|
||||||
|
--- @type integer
|
||||||
|
G_VTX_EXT = 0x11
|
||||||
|
|
||||||
BACKGROUND_OCEAN_SKY = 0 --- @type SkyBackgroundParams
|
BACKGROUND_OCEAN_SKY = 0 --- @type SkyBackgroundParams
|
||||||
BACKGROUND_FLAMING_SKY = 1 --- @type SkyBackgroundParams
|
BACKGROUND_FLAMING_SKY = 1 --- @type SkyBackgroundParams
|
||||||
BACKGROUND_UNDERWATER_CITY = 2 --- @type SkyBackgroundParams
|
BACKGROUND_UNDERWATER_CITY = 2 --- @type SkyBackgroundParams
|
||||||
|
|
@ -3608,10 +3611,12 @@ HUD_DISPLAY_DEFAULT = HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_CO
|
||||||
--- | `HUD_DISPLAY_NONE`
|
--- | `HUD_DISPLAY_NONE`
|
||||||
--- | `HUD_DISPLAY_DEFAULT`
|
--- | `HUD_DISPLAY_DEFAULT`
|
||||||
|
|
||||||
LE_MODE_AFFECT_ALL_SHADED = 0 --- @type LEMode
|
LE_MODE_AFFECT_ALL_SHADED_AND_COLORED = 0 --- @type LEMode
|
||||||
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE = 1 --- @type LEMode
|
LE_MODE_AFFECT_ALL_SHADED = 1 --- @type LEMode
|
||||||
|
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE = 2 --- @type LEMode
|
||||||
|
|
||||||
--- @alias LEMode
|
--- @alias LEMode
|
||||||
|
--- | `LE_MODE_AFFECT_ALL_SHADED_AND_COLORED`
|
||||||
--- | `LE_MODE_AFFECT_ALL_SHADED`
|
--- | `LE_MODE_AFFECT_ALL_SHADED`
|
||||||
--- | `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE`
|
--- | `LE_MODE_AFFECT_ONLY_GEOMETRY_MODE`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ static Gfx *DynOS_Gfx_Duplicate(Gfx *aGfx, bool shouldDuplicate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Duplicate referenced vertices
|
// Duplicate referenced vertices
|
||||||
if (op == G_VTX) {
|
if (op == G_VTX || op == G_VTX_EXT) {
|
||||||
cmd->words.w1 = (uintptr_t) DynOS_Vtx_Duplicate((Vtx *) cmd->words.w1, C0(cmd, 12, 8), shouldDuplicate);
|
cmd->words.w1 = (uintptr_t) DynOS_Vtx_Duplicate((Vtx *) cmd->words.w1, C0(cmd, 12, 8), shouldDuplicate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@
|
||||||
- [enum DialogSound](#enum-DialogSound)
|
- [enum DialogSound](#enum-DialogSound)
|
||||||
- [first_person_cam.h](#first_person_camh)
|
- [first_person_cam.h](#first_person_camh)
|
||||||
- [gbi.h](#gbih)
|
- [gbi.h](#gbih)
|
||||||
|
- [gbi_extension.h](#gbi_extensionh)
|
||||||
- [geo_commands.h](#geo_commandsh)
|
- [geo_commands.h](#geo_commandsh)
|
||||||
- [enum SkyBackgroundParams](#enum-SkyBackgroundParams)
|
- [enum SkyBackgroundParams](#enum-SkyBackgroundParams)
|
||||||
- [graph_node.h](#graph_nodeh)
|
- [graph_node.h](#graph_nodeh)
|
||||||
|
|
@ -1289,6 +1290,13 @@
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
|
## [gbi_extension.h](#gbi_extension.h)
|
||||||
|
- G_VTX_EXT
|
||||||
|
|
||||||
|
[:arrow_up_small:](#)
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
## [geo_commands.h](#geo_commands.h)
|
## [geo_commands.h](#geo_commands.h)
|
||||||
|
|
||||||
### [enum SkyBackgroundParams](#SkyBackgroundParams)
|
### [enum SkyBackgroundParams](#SkyBackgroundParams)
|
||||||
|
|
@ -1627,8 +1635,9 @@
|
||||||
### [enum LEMode](#LEMode)
|
### [enum LEMode](#LEMode)
|
||||||
| Identifier | Value |
|
| Identifier | Value |
|
||||||
| :--------- | :---- |
|
| :--------- | :---- |
|
||||||
| LE_MODE_AFFECT_ALL_SHADED | 0 |
|
| LE_MODE_AFFECT_ALL_SHADED_AND_COLORED | 0 |
|
||||||
| LE_MODE_AFFECT_ONLY_GEOMETRY_MODE | 1 |
|
| LE_MODE_AFFECT_ALL_SHADED | 1 |
|
||||||
|
| LE_MODE_AFFECT_ONLY_GEOMETRY_MODE | 2 |
|
||||||
|
|
||||||
### [enum LEToneMapping](#LEToneMapping)
|
### [enum LEToneMapping](#LEToneMapping)
|
||||||
| Identifier | Value |
|
| Identifier | Value |
|
||||||
|
|
|
||||||
|
|
@ -4274,7 +4274,7 @@ Vtx canals_dl_skybox_mesh_layer_5_vtx_0[46] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
Gfx canals_dl_skybox_mesh_layer_5_tri_0[] = {
|
Gfx canals_dl_skybox_mesh_layer_5_tri_0[] = {
|
||||||
gsSPVertex(canals_dl_skybox_mesh_layer_5_vtx_0 + 0, 16, 0),
|
gsSPVertexNonGlobal(canals_dl_skybox_mesh_layer_5_vtx_0 + 0, 16, 0),
|
||||||
gsSP1Triangle(0, 1, 2, 0),
|
gsSP1Triangle(0, 1, 2, 0),
|
||||||
gsSP1Triangle(0, 3, 1, 0),
|
gsSP1Triangle(0, 3, 1, 0),
|
||||||
gsSP1Triangle(4, 3, 0, 0),
|
gsSP1Triangle(4, 3, 0, 0),
|
||||||
|
|
@ -4289,7 +4289,7 @@ Gfx canals_dl_skybox_mesh_layer_5_tri_0[] = {
|
||||||
gsSP1Triangle(12, 11, 13, 0),
|
gsSP1Triangle(12, 11, 13, 0),
|
||||||
gsSP1Triangle(14, 12, 13, 0),
|
gsSP1Triangle(14, 12, 13, 0),
|
||||||
gsSP1Triangle(14, 13, 15, 0),
|
gsSP1Triangle(14, 13, 15, 0),
|
||||||
gsSPVertex(canals_dl_skybox_mesh_layer_5_vtx_0 + 16, 16, 0),
|
gsSPVertexNonGlobal(canals_dl_skybox_mesh_layer_5_vtx_0 + 16, 16, 0),
|
||||||
gsSP1Triangle(0, 1, 2, 0),
|
gsSP1Triangle(0, 1, 2, 0),
|
||||||
gsSP1Triangle(0, 2, 3, 0),
|
gsSP1Triangle(0, 2, 3, 0),
|
||||||
gsSP1Triangle(1, 0, 4, 0),
|
gsSP1Triangle(1, 0, 4, 0),
|
||||||
|
|
@ -4304,7 +4304,7 @@ Gfx canals_dl_skybox_mesh_layer_5_tri_0[] = {
|
||||||
gsSP1Triangle(12, 11, 13, 0),
|
gsSP1Triangle(12, 11, 13, 0),
|
||||||
gsSP1Triangle(13, 11, 14, 0),
|
gsSP1Triangle(13, 11, 14, 0),
|
||||||
gsSP1Triangle(13, 14, 15, 0),
|
gsSP1Triangle(13, 14, 15, 0),
|
||||||
gsSPVertex(canals_dl_skybox_mesh_layer_5_vtx_0 + 32, 14, 0),
|
gsSPVertexNonGlobal(canals_dl_skybox_mesh_layer_5_vtx_0 + 32, 14, 0),
|
||||||
gsSP1Triangle(0, 1, 2, 0),
|
gsSP1Triangle(0, 1, 2, 0),
|
||||||
gsSP1Triangle(3, 1, 0, 0),
|
gsSP1Triangle(3, 1, 0, 0),
|
||||||
gsSP1Triangle(3, 4, 1, 0),
|
gsSP1Triangle(3, 4, 1, 0),
|
||||||
|
|
|
||||||
|
|
@ -1,88 +1,27 @@
|
||||||
-- name: Lighting Engine Demo
|
-- name: Lighting Engine Demo
|
||||||
-- description: Lighting Engine Demo\nBy \\#ec7731\\Agent X\n\n\\#dcdcdc\\Open the panel in the pause menu to see what you can do.
|
-- description: Lighting Engine Demo\nBy \\#ec7731\\Agent X\n\n\\#dcdcdc\\Open the mod menu in the pause menu to see what you can do.
|
||||||
|
|
||||||
local flashlightColor = { 255, 255, 200 }
|
flashlightColor = { 255, 255, 200 }
|
||||||
|
|
||||||
|
--- @param cmd Gfx
|
||||||
|
--- @param op integer
|
||||||
|
local function parse_dl(cmd, op)
|
||||||
|
if op == G_SETENVCOLOR then
|
||||||
|
gfx_set_command(cmd, "gsDPSetEnvColor(255, 255, 255, %i)", if_then_else(_G.dayNightCycleApi ~= nil and _G.dayNightCycleApi.is_dnc_enabled(), 0, 255))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
--- @param node GraphNode
|
--- @param node GraphNode
|
||||||
function geo_hide_if_dnc(node)
|
function geo_hide_if_dnc(node)
|
||||||
local dl = cast_graph_node(node.next)
|
local dl = cast_graph_node(node.next)
|
||||||
gfx_parse(dl.displayList, function(cmd, op)
|
gfx_parse(dl.displayList, parse_dl)
|
||||||
if op == G_SETENVCOLOR then
|
|
||||||
gfx_set_command(cmd, "gsDPSetEnvColor(255, 255, 255, %i)", if_then_else(_G.dayNightCycleApi ~= nil and _G.dayNightCycleApi.is_dnc_enabled(), 0, 255))
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
--- @param o Object
|
local function update()
|
||||||
local function bhv_spawn_point_light(o)
|
shading_update()
|
||||||
local light = spawn_non_sync_object(
|
|
||||||
id_bhvPointLight,
|
|
||||||
E_MODEL_NONE,
|
|
||||||
o.oPosX, o.oPosY, o.oPosZ,
|
|
||||||
nil
|
|
||||||
)
|
|
||||||
if get_id_from_behavior(o.behavior) == id_bhvKoopaShell then
|
|
||||||
light.oBehParams = 0x00FF0032
|
|
||||||
else
|
|
||||||
light.oBehParams = 0xFFFFFF32
|
|
||||||
end
|
|
||||||
light.parentObj = o
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param o Object
|
--- @type MarioState
|
||||||
function bhv_flashlight_loop(o)
|
local m = gMarioStates[0]
|
||||||
local pos = gMarioStates[0].pos
|
|
||||||
local yaw = gFirstPersonCamera.yaw + 0x8000
|
|
||||||
o.oPosX = pos.x + sins(yaw) * 300
|
|
||||||
o.oPosY = pos.y + -gFirstPersonCamera.pitch * 0.06
|
|
||||||
o.oPosZ = pos.z + coss(yaw) * 300
|
|
||||||
le_set_light_pos(o.oLightID, o.oPosX, o.oPosY, o.oPosZ)
|
|
||||||
le_set_light_color(o.oLightID, flashlightColor[1], flashlightColor[2], flashlightColor[3])
|
|
||||||
end
|
|
||||||
|
|
||||||
local function spawn_flashlight()
|
|
||||||
local flashlight = spawn_non_sync_object(
|
|
||||||
bhvFlashlight,
|
|
||||||
E_MODEL_NONE,
|
|
||||||
0, 0, 0,
|
|
||||||
nil
|
|
||||||
)
|
|
||||||
flashlight.oBehParams = (flashlightColor[1] << 24) | (flashlightColor[2] << 16) | (flashlightColor[3] << 8) | (90)
|
|
||||||
return flashlight
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param flashlight Object
|
|
||||||
local function delete_flashlight(flashlight)
|
|
||||||
le_remove_light(flashlight.oLightID)
|
|
||||||
obj_mark_for_deletion(flashlight)
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param m MarioState
|
|
||||||
local function calculate_mario_lighting(m)
|
|
||||||
local color = { r = 0, g = 0, b = 0 }
|
|
||||||
local dir = { x = 0, y = 0, z = 0 }
|
|
||||||
|
|
||||||
le_calculate_lighting_color(m.pos, color, 0.25)
|
|
||||||
le_calculate_lighting_dir(m.pos, dir)
|
|
||||||
|
|
||||||
m.marioBodyState.lightR = color.r
|
|
||||||
m.marioBodyState.lightG = color.g
|
|
||||||
m.marioBodyState.lightB = color.b
|
|
||||||
m.marioBodyState.shadeR = m.marioBodyState.lightR * 0.5
|
|
||||||
m.marioBodyState.shadeG = m.marioBodyState.lightG * 0.5
|
|
||||||
m.marioBodyState.shadeB = m.marioBodyState.lightB * 0.5
|
|
||||||
|
|
||||||
m.marioBodyState.lightingDirX = -DEFAULT_LIGHTING_DIR + dir.x
|
|
||||||
m.marioBodyState.lightingDirY = -DEFAULT_LIGHTING_DIR + dir.y
|
|
||||||
m.marioBodyState.lightingDirZ = -DEFAULT_LIGHTING_DIR + dir.z
|
|
||||||
end
|
|
||||||
|
|
||||||
--- @param m MarioState
|
|
||||||
local function mario_update(m)
|
|
||||||
if m.playerIndex ~= 0 then return end
|
|
||||||
|
|
||||||
calculate_mario_lighting(m)
|
|
||||||
|
|
||||||
if (m.controller.buttonPressed & L_JPAD) ~= 0 then
|
if (m.controller.buttonPressed & L_JPAD) ~= 0 then
|
||||||
audio_sample_play(SOUND_CUSTOM_FLASHLIGHT, m.pos, 1.0)
|
audio_sample_play(SOUND_CUSTOM_FLASHLIGHT, m.pos, 1.0)
|
||||||
|
|
@ -95,14 +34,27 @@ local function mario_update(m)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function on_level_init()
|
||||||
|
local levelNum = gNetworkPlayers[0].currLevelNum
|
||||||
|
if levelNum == LEVEL_HL or levelNum == LEVEL_CANALS then return end
|
||||||
|
|
||||||
|
le_set_ambient_color(30, 30, 75)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
local function on_set_flashlight_color(index, value)
|
local function on_set_flashlight_color(index, value)
|
||||||
flashlightColor[index + 1] = value
|
flashlightColor[index + 1] = value
|
||||||
end
|
end
|
||||||
|
|
||||||
id_bhvKoopaShell = hook_behavior(id_bhvKoopaShell, OBJ_LIST_LEVEL, false, bhv_spawn_point_light, nil, "bhvKoopaShell")
|
set_override_skybox(BACKGROUND_HAUNTED)
|
||||||
|
set_fog_color(0, 30)
|
||||||
|
set_fog_color(1, 30)
|
||||||
|
set_fog_color(2, 75)
|
||||||
|
|
||||||
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
djui_popup_create("Use Left D-Pad to turn on the flashlight.", 2)
|
||||||
|
|
||||||
|
hook_event(HOOK_UPDATE, update)
|
||||||
|
hook_event(HOOK_ON_LEVEL_INIT, on_level_init)
|
||||||
|
|
||||||
hook_mod_menu_slider("Flashlight Red", flashlightColor[1], 0, 255, on_set_flashlight_color)
|
hook_mod_menu_slider("Flashlight Red", flashlightColor[1], 0, 255, on_set_flashlight_color)
|
||||||
hook_mod_menu_slider("Flashlight Green", flashlightColor[2], 0, 255, on_set_flashlight_color)
|
hook_mod_menu_slider("Flashlight Green", flashlightColor[2], 0, 255, on_set_flashlight_color)
|
||||||
|
|
|
||||||
58
docs/lua/examples/lighting-engine-demo/objects.lua
Normal file
58
docs/lua/examples/lighting-engine-demo/objects.lua
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
--- @param o Object
|
||||||
|
local function bhv_spawn_point_light(o)
|
||||||
|
local light = spawn_non_sync_object(
|
||||||
|
id_bhvPointLight,
|
||||||
|
E_MODEL_NONE,
|
||||||
|
o.oPosX, o.oPosY, o.oPosZ,
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
if get_id_from_behavior(o.behavior) == id_bhvKoopaShell then
|
||||||
|
light.oBehParams = 0x00FF0064
|
||||||
|
else
|
||||||
|
light.oBehParams = 0xFFFFFF32
|
||||||
|
end
|
||||||
|
light.parentObj = o
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param o Object
|
||||||
|
function bhv_flashlight_loop(o)
|
||||||
|
local fp = get_first_person_enabled()
|
||||||
|
local pos = gMarioStates[0].pos
|
||||||
|
local yaw = if_then_else(fp, gFirstPersonCamera.yaw + 0x8000, gMarioStates[0].faceAngle.y)
|
||||||
|
|
||||||
|
local dirX = sins(yaw) * 300
|
||||||
|
local dirY = if_then_else(fp, -gFirstPersonCamera.pitch * 0.06, 120)
|
||||||
|
local dirZ = coss(yaw) * 300
|
||||||
|
|
||||||
|
local raycast = collision_find_surface_on_ray(pos.x, pos.y, pos.z, dirX, dirY, dirZ)
|
||||||
|
if raycast.surface == nil then
|
||||||
|
o.oPosX = pos.x + dirX
|
||||||
|
o.oPosY = pos.y + dirY
|
||||||
|
o.oPosZ = pos.z + dirZ
|
||||||
|
else
|
||||||
|
vec3f_to_object_pos(o, raycast.hitPos)
|
||||||
|
end
|
||||||
|
|
||||||
|
le_set_light_pos(o.oLightID, o.oPosX, o.oPosY, o.oPosZ)
|
||||||
|
le_set_light_color(o.oLightID, flashlightColor[1], flashlightColor[2], flashlightColor[3])
|
||||||
|
end
|
||||||
|
|
||||||
|
function spawn_flashlight()
|
||||||
|
local flashlight = spawn_non_sync_object(
|
||||||
|
bhvFlashlight,
|
||||||
|
E_MODEL_NONE,
|
||||||
|
0, 0, 0,
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
flashlight.oBehParams = (flashlightColor[1] << 24) | (flashlightColor[2] << 16) | (flashlightColor[3] << 8) | (90)
|
||||||
|
return flashlight
|
||||||
|
end
|
||||||
|
|
||||||
|
--- @param flashlight Object
|
||||||
|
function delete_flashlight(flashlight)
|
||||||
|
le_remove_light(flashlight.oLightID)
|
||||||
|
obj_mark_for_deletion(flashlight)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
id_bhvKoopaShell = hook_behavior(id_bhvKoopaShell, OBJ_LIST_LEVEL, false, bhv_spawn_point_light, nil, "bhvKoopaShell")
|
||||||
51
docs/lua/examples/lighting-engine-demo/shading.lua
Normal file
51
docs/lua/examples/lighting-engine-demo/shading.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
-- special thanks to Coolio for figuring out worldspace shading
|
||||||
|
|
||||||
|
--- @param dest Vec3f
|
||||||
|
--- @param rotate Vec3f
|
||||||
|
--- Rotates `dest` around the Z, Y, and X axes
|
||||||
|
local function vec3f_rotate_zyx(dest, rotate)
|
||||||
|
local v = { x = dest.x, y = dest.y, z = dest.z }
|
||||||
|
|
||||||
|
local sx = sins(rotate.x)
|
||||||
|
local cx = coss(rotate.x)
|
||||||
|
|
||||||
|
local sy = sins(rotate.y)
|
||||||
|
local cy = coss(rotate.y)
|
||||||
|
|
||||||
|
local sz = sins(rotate.z)
|
||||||
|
local cz = coss(rotate.z)
|
||||||
|
|
||||||
|
-- Rotation around Z axis
|
||||||
|
local xz = v.x * cz - v.y * sz
|
||||||
|
local yz = v.x * sz + v.y * cz
|
||||||
|
local zz = v.z
|
||||||
|
|
||||||
|
-- Rotation around Y axis
|
||||||
|
local xy = xz * cy + zz * sy
|
||||||
|
local yy = yz
|
||||||
|
local zy = -xz * sy + zz * cy
|
||||||
|
|
||||||
|
-- Rotation around X axis
|
||||||
|
dest.x = xy
|
||||||
|
dest.y = yy * cx - zy * sx
|
||||||
|
dest.z = yy * sx + zy * cx
|
||||||
|
|
||||||
|
return dest
|
||||||
|
end
|
||||||
|
|
||||||
|
local LIGHTING_OFFSET = { x = 0x28 / 0xFF, y = 0x28 / 0xFF, z = 0x28 / 0xFF }
|
||||||
|
|
||||||
|
function shading_update()
|
||||||
|
local l = gLakituState
|
||||||
|
local pitch = calculate_pitch(l.pos, l.focus)
|
||||||
|
local yaw = calculate_yaw(l.pos, l.focus)
|
||||||
|
local roll = l.roll
|
||||||
|
|
||||||
|
local lightingDir = gVec3fOne()
|
||||||
|
vec3f_rotate_zyx(lightingDir, { x = -pitch, y = -yaw, z = roll })
|
||||||
|
vec3f_sub(lightingDir, LIGHTING_OFFSET)
|
||||||
|
|
||||||
|
set_lighting_dir(0, lightingDir.x)
|
||||||
|
set_lighting_dir(1, lightingDir.y)
|
||||||
|
set_lighting_dir(2, lightingDir.z)
|
||||||
|
end
|
||||||
|
|
@ -6,10 +6,10 @@
|
||||||
|
|
||||||
#define LE_MAX_LIGHTS 256
|
#define LE_MAX_LIGHTS 256
|
||||||
|
|
||||||
static Color sAmbientColor = { 127, 127, 127 };
|
Color gLEAmbientColor = { 127, 127, 127 };
|
||||||
static void* sLights = NULL;
|
static void* sLights = NULL;
|
||||||
static s32 sLightID = 0;
|
static s32 sLightID = 0;
|
||||||
static enum LEMode sMode = LE_MODE_AFFECT_ALL_SHADED;
|
static enum LEMode sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
|
||||||
static enum LEToneMapping sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
static enum LEToneMapping sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
||||||
static bool sEnabled = false;
|
static bool sEnabled = false;
|
||||||
|
|
||||||
|
|
@ -129,9 +129,9 @@ void le_calculate_vertex_lighting(Vtx_t* v, Vec3f pos, OUT Color out) {
|
||||||
|
|
||||||
// tone map and output
|
// tone map and output
|
||||||
Color vtxAmbient = {
|
Color vtxAmbient = {
|
||||||
v->cn[0] * (sAmbientColor[0] / 255.0f),
|
v->cn[0] * (gLEAmbientColor[0] / 255.0f),
|
||||||
v->cn[1] * (sAmbientColor[1] / 255.0f),
|
v->cn[1] * (gLEAmbientColor[1] / 255.0f),
|
||||||
v->cn[2] * (sAmbientColor[2] / 255.0f),
|
v->cn[2] * (gLEAmbientColor[2] / 255.0f),
|
||||||
};
|
};
|
||||||
le_tone_map(out, vtxAmbient, color, weight);
|
le_tone_map(out, vtxAmbient, color, weight);
|
||||||
}
|
}
|
||||||
|
|
@ -149,7 +149,7 @@ void le_calculate_lighting_color(Vec3f pos, OUT Color out, f32 lightIntensitySca
|
||||||
}
|
}
|
||||||
|
|
||||||
// tone map and output
|
// tone map and output
|
||||||
le_tone_map(out, sAmbientColor, color, weight);
|
le_tone_map(out, gLEAmbientColor, color, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar) {
|
void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color out, f32 lightIntensityScalar) {
|
||||||
|
|
@ -168,7 +168,7 @@ void le_calculate_lighting_color_with_normal(Vec3f pos, Vec3f normal, OUT Color
|
||||||
}
|
}
|
||||||
|
|
||||||
// tone map and output
|
// tone map and output
|
||||||
le_tone_map(out, sAmbientColor, color, weight);
|
le_tone_map(out, gLEAmbientColor, color, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out) {
|
void le_calculate_lighting_dir(Vec3f pos, OUT Vec3f out) {
|
||||||
|
|
@ -241,7 +241,7 @@ s32 le_get_light_count(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_set_ambient_color(u8 r, u8 g, u8 b) {
|
void le_set_ambient_color(u8 r, u8 g, u8 b) {
|
||||||
color_set(sAmbientColor, r, g, b);
|
color_set(gLEAmbientColor, r, g, b);
|
||||||
sEnabled = true;
|
sEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,16 +297,16 @@ void le_clear(void) {
|
||||||
}
|
}
|
||||||
hmap_clear(sLights);
|
hmap_clear(sLights);
|
||||||
sLightID = 0;
|
sLightID = 0;
|
||||||
sAmbientColor[0] = 127;
|
gLEAmbientColor[0] = 127;
|
||||||
sAmbientColor[1] = 127;
|
gLEAmbientColor[1] = 127;
|
||||||
sAmbientColor[2] = 127;
|
gLEAmbientColor[2] = 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
void le_shutdown(void) {
|
void le_shutdown(void) {
|
||||||
if (sLights == NULL) { return; }
|
if (sLights == NULL) { return; }
|
||||||
|
|
||||||
sEnabled = false;
|
sEnabled = false;
|
||||||
sMode = LE_MODE_AFFECT_ALL_SHADED;
|
sMode = LE_MODE_AFFECT_ALL_SHADED_AND_COLORED;
|
||||||
sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
sToneMapping = LE_TONE_MAPPING_WEIGHTED;
|
||||||
le_clear();
|
le_clear();
|
||||||
hmap_destroy(sLights);
|
hmap_destroy(sLights);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ struct LELight
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LEMode {
|
enum LEMode {
|
||||||
|
LE_MODE_AFFECT_ALL_SHADED_AND_COLORED,
|
||||||
LE_MODE_AFFECT_ALL_SHADED,
|
LE_MODE_AFFECT_ALL_SHADED,
|
||||||
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE,
|
LE_MODE_AFFECT_ONLY_GEOMETRY_MODE,
|
||||||
};
|
};
|
||||||
|
|
@ -28,6 +29,8 @@ enum LEToneMapping {
|
||||||
LE_TONE_MAPPING_REINHARD,
|
LE_TONE_MAPPING_REINHARD,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern Color gLEAmbientColor;
|
||||||
|
|
||||||
/* |description|Sets the lighting engine mode to `mode`|descriptionEnd|*/
|
/* |description|Sets the lighting engine mode to `mode`|descriptionEnd|*/
|
||||||
void le_set_mode(enum LEMode mode);
|
void le_set_mode(enum LEMode mode);
|
||||||
/* |description|Gets the lighting engine mode|descriptionEnd|*/
|
/* |description|Gets the lighting engine mode|descriptionEnd|*/
|
||||||
|
|
|
||||||
|
|
@ -724,7 +724,6 @@ static OPTIMIZE_O3 void gfx_local_to_world_space(OUT Vec3f pos, OUT Vec3f normal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, const Vtx *vertices, bool luaVertexColor) {
|
||||||
if (!vertices) { return; }
|
if (!vertices) { return; }
|
||||||
|
|
||||||
|
|
@ -779,6 +778,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16;
|
short U = v->tc[0] * rsp.texture_scaling_factor.s >> 16;
|
||||||
short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16;
|
short V = v->tc[1] * rsp.texture_scaling_factor.t >> 16;
|
||||||
|
|
||||||
|
// are we on affect all shaded surfaces mode and on a vertex colorable surface
|
||||||
|
bool affectAllVertexColored = (le_get_mode() == LE_MODE_AFFECT_ALL_SHADED_AND_COLORED && luaVertexColor);
|
||||||
|
|
||||||
if (rsp.geometry_mode & G_LIGHTING) {
|
if (rsp.geometry_mode & G_LIGHTING) {
|
||||||
if (rsp.lights_changed) {
|
if (rsp.lights_changed) {
|
||||||
bool applyLightingDir = !(rsp.geometry_mode & G_TEXTURE_GEN);
|
bool applyLightingDir = !(rsp.geometry_mode & G_TEXTURE_GEN);
|
||||||
|
|
@ -861,8 +863,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
V = (int32_t)((doty / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.t);
|
V = (int32_t)((doty / 127.0f + 1.0f) / 4.0f * rsp.texture_scaling_factor.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (le_is_enabled() && ((le_get_mode() == LE_MODE_AFFECT_ALL_SHADED) || (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT))) {
|
// if lighting engine is enabled and either we want to affect all shaded surfaces or the lighting engine geometry mode is on
|
||||||
Color color;
|
if (le_is_enabled() && ((le_get_mode() != LE_MODE_AFFECT_ONLY_GEOMETRY_MODE) || (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT))) {
|
||||||
|
Color color = { gLEAmbientColor[0], gLEAmbientColor[1], gLEAmbientColor[2] };
|
||||||
CTX_BEGIN(CTX_LIGHTING);
|
CTX_BEGIN(CTX_LIGHTING);
|
||||||
|
|
||||||
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
||||||
|
|
@ -879,8 +882,9 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
d->color.g *= color[1] / 255.0f;
|
d->color.g *= color[1] / 255.0f;
|
||||||
d->color.b *= color[2] / 255.0f;
|
d->color.b *= color[2] / 255.0f;
|
||||||
}
|
}
|
||||||
} else if (le_is_enabled() && (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT)) {
|
// if lighting engine is enabled and we should affect all vertex colored surfaces or the lighting engine geometry mode is on
|
||||||
Color color;
|
} else if (le_is_enabled() && (affectAllVertexColored || (rsp.geometry_mode & G_LIGHTING_ENGINE_EXT))) {
|
||||||
|
Color color = { gLEAmbientColor[0], gLEAmbientColor[1], gLEAmbientColor[2] };
|
||||||
CTX_BEGIN(CTX_LIGHTING);
|
CTX_BEGIN(CTX_LIGHTING);
|
||||||
|
|
||||||
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
Vec3f vpos = { v->ob[0], v->ob[1], v->ob[2] };
|
||||||
|
|
@ -888,10 +892,24 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
// transform vpos to world space
|
// transform vpos to world space
|
||||||
gfx_local_to_world_space(vpos, NULL);
|
gfx_local_to_world_space(vpos, NULL);
|
||||||
|
|
||||||
|
// do multiplication based lighting instead of additive based lighting if we're not using the lighting engine geometry mode,
|
||||||
|
// this is my compromise for retaining vertex colors vs lighting up darker surfaces.
|
||||||
|
// if retaining color is the most important like on a red coin, don't use the lighting engine geometry mode.
|
||||||
|
// if lighting up darker surfaces like in a map with prebaked lighting is the most important, use the lighting engine geometry mode.
|
||||||
|
if (affectAllVertexColored && !(rsp.geometry_mode & G_LIGHTING_ENGINE_EXT)) {
|
||||||
|
le_calculate_lighting_color(vpos, color, 1.0f);
|
||||||
|
} else {
|
||||||
le_calculate_vertex_lighting((Vtx_t*)v, vpos, color);
|
le_calculate_vertex_lighting((Vtx_t*)v, vpos, color);
|
||||||
|
}
|
||||||
|
|
||||||
CTX_END(CTX_LIGHTING);
|
CTX_END(CTX_LIGHTING);
|
||||||
|
|
||||||
|
// combine the colors
|
||||||
|
if (affectAllVertexColored && !(rsp.geometry_mode & G_LIGHTING_ENGINE_EXT)) {
|
||||||
|
d->color.r = (v->cn[0] * color[0] / 255.0f) * vertexColorCached[0];
|
||||||
|
d->color.g = (v->cn[1] * color[1] / 255.0f) * vertexColorCached[1];
|
||||||
|
d->color.b = (v->cn[2] * color[2] / 255.0f) * vertexColorCached[2];
|
||||||
|
} else {
|
||||||
if (luaVertexColor) {
|
if (luaVertexColor) {
|
||||||
d->color.r = color[0] * vertexColorCached[0];
|
d->color.r = color[0] * vertexColorCached[0];
|
||||||
d->color.g = color[1] * vertexColorCached[1];
|
d->color.g = color[1] * vertexColorCached[1];
|
||||||
|
|
@ -901,6 +919,7 @@ static void OPTIMIZE_O3 gfx_sp_vertex(size_t n_vertices, size_t dest_index, cons
|
||||||
d->color.g = color[1];
|
d->color.g = color[1];
|
||||||
d->color.b = color[2];
|
d->color.b = color[2];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(rsp.geometry_mode & G_LIGHT_MAP_EXT) && luaVertexColor) {
|
if (!(rsp.geometry_mode & G_LIGHT_MAP_EXT) && luaVertexColor) {
|
||||||
d->color.r = v->cn[0] * vertexColorCached[0];
|
d->color.r = v->cn[0] * vertexColorCached[0];
|
||||||
|
|
|
||||||
|
|
@ -1515,6 +1515,7 @@ char gSmluaConstants[] = ""
|
||||||
"G_SETSCISSOR=0xed\n"
|
"G_SETSCISSOR=0xed\n"
|
||||||
"G_TEXRECTFLIP=0xe5\n"
|
"G_TEXRECTFLIP=0xe5\n"
|
||||||
"G_TEXRECT=0xe4\n"
|
"G_TEXRECT=0xe4\n"
|
||||||
|
"G_VTX_EXT=0x11\n"
|
||||||
"BACKGROUND_OCEAN_SKY=0\n"
|
"BACKGROUND_OCEAN_SKY=0\n"
|
||||||
"BACKGROUND_FLAMING_SKY=1\n"
|
"BACKGROUND_FLAMING_SKY=1\n"
|
||||||
"BACKGROUND_UNDERWATER_CITY=2\n"
|
"BACKGROUND_UNDERWATER_CITY=2\n"
|
||||||
|
|
@ -1777,8 +1778,9 @@ char gSmluaConstants[] = ""
|
||||||
"HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n"
|
"HUD_DISPLAY_FLAG_EMPHASIZE_POWER=0x8000\n"
|
||||||
"HUD_DISPLAY_NONE=0x0000\n"
|
"HUD_DISPLAY_NONE=0x0000\n"
|
||||||
"HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n"
|
"HUD_DISPLAY_DEFAULT=HUD_DISPLAY_FLAG_LIVES | HUD_DISPLAY_FLAG_COIN_COUNT | HUD_DISPLAY_FLAG_STAR_COUNT | HUD_DISPLAY_FLAG_CAMERA_AND_POWER | HUD_DISPLAY_FLAG_CAMERA | HUD_DISPLAY_FLAG_POWER | HUD_DISPLAY_FLAG_KEYS | HUD_DISPLAY_FLAG_UNKNOWN_0020\n"
|
||||||
"LE_MODE_AFFECT_ALL_SHADED=0\n"
|
"LE_MODE_AFFECT_ALL_SHADED_AND_COLORED=0\n"
|
||||||
"LE_MODE_AFFECT_ONLY_GEOMETRY_MODE=1\n"
|
"LE_MODE_AFFECT_ALL_SHADED=1\n"
|
||||||
|
"LE_MODE_AFFECT_ONLY_GEOMETRY_MODE=2\n"
|
||||||
"LE_TONE_MAPPING_TOTAL_WEIGHTED=0\n"
|
"LE_TONE_MAPPING_TOTAL_WEIGHTED=0\n"
|
||||||
"LE_TONE_MAPPING_WEIGHTED=1\n"
|
"LE_TONE_MAPPING_WEIGHTED=1\n"
|
||||||
"LE_TONE_MAPPING_CLAMP=2\n"
|
"LE_TONE_MAPPING_CLAMP=2\n"
|
||||||
|
|
|
||||||
|
|
@ -223,7 +223,7 @@ Gfx *gfx_get_display_list(Gfx *cmd) {
|
||||||
Vtx *gfx_get_vertex_buffer(Gfx *cmd) {
|
Vtx *gfx_get_vertex_buffer(Gfx *cmd) {
|
||||||
if (!cmd) { return NULL; }
|
if (!cmd) { return NULL; }
|
||||||
u32 op = GFX_OP(cmd);
|
u32 op = GFX_OP(cmd);
|
||||||
if (op != G_VTX) { return NULL; }
|
if (op != G_VTX && op != G_VTX_EXT) { return NULL; }
|
||||||
if (cmd->words.w1 == 0) { return NULL; }
|
if (cmd->words.w1 == 0) { return NULL; }
|
||||||
|
|
||||||
return (Vtx *) cmd->words.w1;
|
return (Vtx *) cmd->words.w1;
|
||||||
|
|
@ -232,7 +232,7 @@ Vtx *gfx_get_vertex_buffer(Gfx *cmd) {
|
||||||
u16 gfx_get_vertex_count(Gfx *cmd) {
|
u16 gfx_get_vertex_count(Gfx *cmd) {
|
||||||
if (!cmd) { return 0; }
|
if (!cmd) { return 0; }
|
||||||
u32 op = GFX_OP(cmd);
|
u32 op = GFX_OP(cmd);
|
||||||
if (op != G_VTX) { return 0; }
|
if (op != G_VTX && op != G_VTX_EXT) { return 0; }
|
||||||
if (cmd->words.w1 == 0) { return 0; }
|
if (cmd->words.w1 == 0) { return 0; }
|
||||||
|
|
||||||
return C0(cmd, 12, 8);
|
return C0(cmd, 12, 8);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue