Overview
The draw_model_execute hook is called when the game renders 3D models, allowing you to override materials, create chams (colored overlays), and apply custom visual effects to player models and weapons.
This hook is called at virtual table index 21 of the i_model_render interface.
Hook Signature
void __fastcall draw_model_execute_detour (
void* ecx ,
void* edx ,
void* context ,
void* state ,
sdk :: model_render_info & info ,
math :: matrix_3x4 * custom_bone_to_world
)
Parameters
ECX register (fastcall convention) - pointer to the interface
EDX register (fastcall convention) - not used
Information about the model being rendered, including model pointer and entity index
Custom bone transformation matrices, or nullptr to use default
When Itβs Called
This hook is invoked every time a 3D model is rendered, including:
Player models
Weapon models
World objects
Particle effects
Common Use Cases
Identifying Model Types
Filter models by checking the model name:
bool model_is_player = strstr ( info . model -> name , _ ( "models/player" ));
bool model_is_weapon = strstr ( info . model -> name , _ ( "weapons/v_" ));
Creating Custom Materials
Create and cache custom materials for visual effects:
static sdk ::i_material * animated_wireframe{};
static sdk ::i_material * material_regular{};
static sdk ::i_material * material_flat{};
if ( ! animated_wireframe) {
// Create VMT file
std :: ofstream ( _ ( "csgo/materials/animated_wireframe.vmt" )) << _ ( R"#("UnlitGeneric" {
"$basetexture" "models/inventory_items/dreamhack_trophies/dreamhack_star_blur"
"$wireframe" "1"
"$alpha" "0.6"
"$additive" "1"
"$ignorez" "1"
"proxies" {
"texturescroll" {
"texturescrollvar" "$basetexturetransform"
"texturescrollrate" "0.2"
"texturescrollangle" "90"
}
}
})#" );
}
animated_wireframe = g_interfaces . material_system -> find_material ( _ ( "animated_wireframe" ));
material_regular = g_interfaces . material_system -> find_material ( _ ( "debug/debugambientcube" ));
material_flat = g_interfaces . material_system -> find_material ( _ ( "debug/debugdrawflat" ));
Player Model Chams
Apply colored overlays to player models:
if (model_is_player && info . entity_index >= 0 && info . entity_index <= 64 ) {
material_regular -> color_modulate ( 99 / 255. f , 0 / 255. f , 114 / 255. f );
material_regular -> set_material_var_flag ( sdk ::MATERIAL_VAR_IGNOREZ, true );
g_interfaces . model_render -> forced_material_override (material_regular);
draw_model_execute_hook . call_original < void > (
ecx, edx, context, state, info, custom_bone_to_world
);
g_interfaces . model_render -> forced_material_override ( nullptr );
}
Lag Compensation Visualization
Render backtrack positions for lag compensation:
if (model_is_player && info . entity_index >= 0 && info . entity_index <= 64 ) {
static auto unlag_pointer = g_convars [ _ ( "sv_maxunlag" )];
auto sv_maxunlag_ticks = sdk :: time_to_ticks ( unlag_pointer -> get_float ());
for ( int i = 0 ; i < sv_maxunlag_ticks; i ++ ) {
auto current_record = & g_lagcomp . heap_records [ info . entity_index ][i];
// Render with gradient color based on age
const int green = static_cast < int > ((i + 1 ) * 3 * 2.55 f );
material_regular -> color_modulate (
( 255 - green) / 255. f ,
green / 255. f ,
0.7058 f
);
material_regular -> alpha_modulate ( 0.7 f );
// Draw using backtrack bone matrix
draw_model_execute_hook . call_original < void > (
ecx, edx, context, state, info, current_record -> bone_matrix
);
}
}
Weapon Chams
Apply animated materials to viewmodel weapons:
if (model_is_weapon) {
animated_wireframe -> color_modulate ( 0 / 255. f , 255 / 255. f , 255 / 255. f );
animated_wireframe -> set_material_var_flag ( sdk ::MATERIAL_VAR_IGNOREZ, false );
g_interfaces . model_render -> forced_material_override (animated_wireframe);
draw_model_execute_hook . call_original < void > (
ecx, edx, context, state, info, custom_bone_to_world
);
g_interfaces . model_render -> forced_material_override ( nullptr );
}
Always reset material overrides after rendering: g_interfaces . model_render -> forced_material_override ( nullptr );
Failing to do so will cause all subsequent models to use your custom material.
Material Flags
Common material flags you can modify:
MATERIAL_VAR_IGNOREZ - Render through walls (ignores depth buffer)
MATERIAL_VAR_WIREFRAME - Render as wireframe
MATERIAL_VAR_FLAT - Flat shading
MATERIAL_VAR_ADDITIVE - Additive blending
Implementation Example
draw_model_execute.h
draw_model_execute.cpp
CREATE_HOOK_HELPER (
draw_model_execute_hook,
void (__fastcall)( void * , void * , void * , void * ,
sdk ::model_render_info & , math ::matrix_3x4 * )
);
static void __fastcall draw_model_execute_detour (
void* ecx ,
void* edx ,
void* context ,
void* state ,
sdk :: model_render_info & info ,
math :: matrix_3x4 * custom_bone_to_world
);
Source Files
Header: globals/hooks/draw_model_execute/draw_model_execute.h:16-30
Implementation: globals/hooks/draw_model_execute/draw_model_execute.cpp:6-99
Initialization
void init ()
{
hooks :: draw_model_execute_hook . create (
virtual_func :: get ( g_interfaces . model_render , 21 ),
draw_model_execute_detour,
_ ( "draw_model_execute_detour" )
);
}
See Also