97色伦色在线综合视频,无玛专区,18videosex性欧美黑色,日韩黄色电影免费在线观看,国产精品伦理一区二区三区,在线视频欧美日韩,亚洲欧美在线中文字幕不卡

網(wǎng)站建設(shè)php教程佛山公司建網(wǎng)站

鶴壁市浩天電氣有限公司 2026/01/24 14:05:03
網(wǎng)站建設(shè)php教程,佛山公司建網(wǎng)站,開發(fā)公司成本部職責(zé)崗位職責(zé)和流程,微信企業(yè)網(wǎng)站上一篇#xff1a;材質(zhì)系統(tǒng) | 下一篇#xff1a;資源系統(tǒng) | 返回目錄 #x1f4da; 快速導(dǎo)航 #x1f4cb; 目錄 引言學(xué)習(xí)目標(biāo)幾何體概念幾何體數(shù)據(jù)結(jié)構(gòu)幾何體系統(tǒng)架構(gòu)幾何體配置與創(chuàng)建程序化幾何體生成渲染器集成渲染包系統(tǒng)使用示例常見問(wèn)題練習(xí)與挑戰(zhàn)下一步 #x1f4d…上一篇材質(zhì)系統(tǒng) | 下一篇資源系統(tǒng) | 返回目錄 快速導(dǎo)航 目錄引言學(xué)習(xí)目標(biāo)幾何體概念幾何體數(shù)據(jù)結(jié)構(gòu)幾何體系統(tǒng)架構(gòu)幾何體配置與創(chuàng)建程序化幾何體生成渲染器集成渲染包系統(tǒng)使用示例常見問(wèn)題練習(xí)與挑戰(zhàn)下一步 引言在前面的教程中我們實(shí)現(xiàn)了紋理系統(tǒng)和材質(zhì)系統(tǒng)能夠定義和管理物體的外觀。但是要渲染一個(gè)3D物體我們還需要幾何體數(shù)據(jù)頂點(diǎn)位置、紋理坐標(biāo)、索引等。目前我們的渲染代碼中頂點(diǎn)數(shù)據(jù)是硬編碼的vertex_3d verts[4];verts[0].positionvec3(-0.5,-0.5,0);// ...u32 indices[6]{0,1,2,0,3,1};這種方式有諸多問(wèn)題難以復(fù)用- 相同形狀的物體需要重復(fù)定義無(wú)法管理- 不知道加載了哪些幾何體內(nèi)存浪費(fèi)- 重復(fù)的幾何體占用多份內(nèi)存缺乏抽象- 幾何體和材質(zhì)沒(méi)有關(guān)聯(lián)幾何體系統(tǒng)解決了這些問(wèn)題提供了幾何體的創(chuàng)建和管理引用計(jì)數(shù)和自動(dòng)釋放與材質(zhì)系統(tǒng)的集成程序化幾何體生成 學(xué)習(xí)目標(biāo)目標(biāo)描述 理解幾何體概念掌握頂點(diǎn)、索引、材質(zhì)的關(guān)系 實(shí)現(xiàn)幾何體系統(tǒng)使用與紋理/材質(zhì)相同的模式 程序化生成創(chuàng)建平面、立方體等基礎(chǔ)形狀 渲染包設(shè)計(jì)批量提交幾何體到渲染器 系統(tǒng)集成連接幾何體、材質(zhì)、渲染器幾何體概念什么是幾何體幾何體Geometry是3D物體的形狀定義包含幾何體 頂點(diǎn)數(shù)據(jù) 索引數(shù)據(jù) 材質(zhì) 頂點(diǎn)數(shù)據(jù) vertex[0] {position: (x, y, z), texcoord: (u, v)} vertex[1] {position: (x, y, z), texcoord: (u, v)} ... 索引數(shù)據(jù) indices [0, 1, 2, 0, 2, 3] // 定義三角形 材質(zhì) 指向material*的引用幾何體 vs 網(wǎng)格 vs 模型模型Model ┌────────────────────────┐ │ 人物角色 │ ├────────────────────────┤ │ 網(wǎng)格0: 頭部 │ 多個(gè)網(wǎng)格組成 │ 網(wǎng)格1: 身體 │ │ 網(wǎng)格2: 武器 │ └────────────────────────┘ 網(wǎng)格Mesh ┌────────────────────────┐ │ 頭部網(wǎng)格 │ 一個(gè)邏輯單元 ├────────────────────────┤ │ 幾何體0: LOD 0 (高精度)│ 不同LOD級(jí)別 │ 幾何體1: LOD 1 (中精度)│ │ 幾何體2: LOD 2 (低精度)│ └────────────────────────┘ 幾何體Geometry ┌────────────────────────┐ │ 頂點(diǎn)緩沖區(qū) │ GPU資源 │ 索引緩沖區(qū) │ │ 材質(zhì)引用 │ └────────────────────────┘在Kohi引擎中Geometry是最基礎(chǔ)的可渲染單元。幾何體數(shù)據(jù)流導(dǎo)出加載geometry_config創(chuàng)建上傳繪制3D建模軟件.obj/.fbx文件頂點(diǎn)/索引數(shù)組幾何體系統(tǒng)geometry對(duì)象GPU緩沖區(qū)屏幕輸出幾何體數(shù)據(jù)結(jié)構(gòu)幾何體結(jié)構(gòu)engine/src/resources/resource_types.h#defineGEOMETRY_NAME_MAX_LENGTH256/** * brief 幾何體世界中的實(shí)際幾何形狀 * 通常但不總是與材質(zhì)配對(duì) */typedefstructgeometry{u32 id;// 幾何體ID系統(tǒng)索引u32 internal_id;// 渲染器內(nèi)部IDGPU資源u32 generation;// 版本號(hào)charname[GEOMETRY_NAME_MAX_LENGTH];// 幾何體名稱material*material;// 關(guān)聯(lián)的材質(zhì)}geometry;幾何體配置engine/src/systems/geometry_system.h/** * brief 幾何體配置用于創(chuàng)建幾何體 */typedefstructgeometry_config{u32 vertex_count;// 頂點(diǎn)數(shù)量vertex_3d*vertices;// 頂點(diǎn)數(shù)組u32 index_count;// 索引數(shù)量u32*indices;// 索引數(shù)組charname[GEOMETRY_NAME_MAX_LENGTH];// 幾何體名稱charmaterial_name[MATERIAL_NAME_MAX_LENGTH];// 材質(zhì)名稱}geometry_config;頂點(diǎn)結(jié)構(gòu)回顧typedefstructvertex_3d{vec3 position;// 位置 (x, y, z)vec2 texcoord;// 紋理坐標(biāo) (u, v)}vertex_3d;數(shù)據(jù)關(guān)系geometry plane_01 ├─ id: 5 ├─ internal_id: 12 (Vulkan頂點(diǎn)緩沖區(qū)偏移) ├─ name: plane_01 └─ material → material wood ├─ diffuse_colour: (0.6, 0.4, 0.2, 1.0) └─ diffuse_map → texture wood_diffuse └─ GPU紋理資源 渲染時(shí) 1. 從geometry獲取material 2. 從material獲取diffuse_colour和diffuse_map 3. 使用geometry.internal_id繪制頂點(diǎn)數(shù)據(jù)幾何體系統(tǒng)架構(gòu)幾何體系統(tǒng)的設(shè)計(jì)延續(xù)了紋理和材質(zhì)系統(tǒng)的模式。系統(tǒng)狀態(tài)engine/src/systems/geometry_system.c/** * brief 幾何體引用信息 */typedefstructgeometry_reference{u64 reference_count;// 引用計(jì)數(shù)geometry geometry;// 幾何體數(shù)據(jù)直接嵌入而非指針b8 auto_release;// 是否自動(dòng)釋放}geometry_reference;/** * brief 幾何體系統(tǒng)狀態(tài) */typedefstructgeometry_system_state{geometry_system_config config;// 配置geometry default_geometry;// 默認(rèn)幾何體四邊形// 已注冊(cè)幾何體數(shù)組geometry_reference*registered_geometries;}geometry_system_state;staticgeometry_system_state*state_ptr0;配置結(jié)構(gòu)typedefstructgeometry_system_config{/** * brief 最大幾何體數(shù)量 * 注意應(yīng)該遠(yuǎn)大于靜態(tài)網(wǎng)格數(shù)量因?yàn)槊總€(gè)網(wǎng)格可能有多個(gè)幾何體LOD等 */u32 max_geometry_count;}geometry_system_config;與紋理/材質(zhì)系統(tǒng)的差異紋理系統(tǒng) ┌──────────────────────────────┐ │ texture_reference[] │ │ - reference_count │ │ - handle (索引到texture[]) │ 間接引用 │ - auto_release │ └──────────────────────────────┘ ┌──────────────────────────────┐ │ texture[] │ 單獨(dú)數(shù)組 │ - 紋理數(shù)據(jù) │ └──────────────────────────────┘ 幾何體系統(tǒng) ┌──────────────────────────────┐ │ geometry_reference[] │ │ - reference_count │ │ - geometry (直接嵌入) │ 直接嵌入 │ - auto_release │ └──────────────────────────────┘為什么直接嵌入簡(jiǎn)化查找不需要二次索引減少內(nèi)存碎片數(shù)據(jù)連續(xù)存儲(chǔ)幾何體數(shù)據(jù)較小不像紋理有大量像素?cái)?shù)據(jù)系統(tǒng)內(nèi)存布局Geometry System內(nèi)存布局 ┌────────────────────────────────────────┐ │ geometry_system_state (結(jié)構(gòu)體) │ ├────────────────────────────────────────┤ │ registered_geometries[4096] (數(shù)組) │ │ - geometry_reference 0 │ │ - reference_count │ │ - geometry (嵌入) │ │ - auto_release │ │ - geometry_reference 1 │ │ - ... │ │ - geometry_reference 4095 │ └────────────────────────────────────────┘ 注意沒(méi)有哈希表 - 紋理/材質(zhì)系統(tǒng)使用名稱查找 - 幾何體系統(tǒng)使用ID直接索引幾何體配置與創(chuàng)建系統(tǒng)初始化b8geometry_system_initialize(u64*memory_requirement,void*state,geometry_system_config config){if(config.max_geometry_count0){KFATAL(geometry_system_initialize - config.max_geometry_count must be 0.);returnfalse;}// 計(jì)算內(nèi)存需求u64 struct_requirementsizeof(geometry_system_state);u64 array_requirementsizeof(geometry_reference)*config.max_geometry_count;*memory_requirementstruct_requirementarray_requirement;if(!state){returntrue;// 第一次調(diào)用返回內(nèi)存需求}state_ptrstate;state_ptr-configconfig;// 設(shè)置數(shù)組指針void*array_blockstatestruct_requirement;state_ptr-registered_geometriesarray_block;// 初始化所有幾何體為無(wú)效u32 countstate_ptr-config.max_geometry_count;for(u32 i0;icount;i){state_ptr-registered_geometries[i].geometry.idINVALID_ID;state_ptr-registered_geometries[i].geometry.internal_idINVALID_ID;state_ptr-registered_geometries[i].geometry.generationINVALID_ID;}// 創(chuàng)建默認(rèn)幾何體if(!create_default_geometry(state_ptr)){KFATAL(Failed to create default geometry.);returnfalse;}returntrue;}從配置獲取幾何體/** * brief 從配置創(chuàng)建并獲取幾何體 * param config 幾何體配置 * param auto_release 引用計(jì)數(shù)歸零時(shí)是否自動(dòng)釋放 * return 幾何體指針失敗返回NULL */geometry*geometry_system_acquire_from_config(geometry_config config,b8 auto_release){geometry*g0;// 查找空閑槽位for(u32 i0;istate_ptr-config.max_geometry_count;i){if(state_ptr-registered_geometries[i].geometry.idINVALID_ID){// 找到空閑槽位state_ptr-registered_geometries[i].auto_releaseauto_release;state_ptr-registered_geometries[i].reference_count1;gstate_ptr-registered_geometries[i].geometry;g-idi;// ID就是數(shù)組索引break;}}if(!g){KERROR(Unable to obtain free slot for geometry. Adjust configuration.);return0;}// 創(chuàng)建幾何體if(!create_geometry(state_ptr,config,g)){KERROR(Failed to create geometry.);return0;}returng;}通過(guò)ID獲取幾何體/** * brief 通過(guò)ID獲取現(xiàn)有幾何體 * param id 幾何體ID * return 幾何體指針失敗返回NULL */geometry*geometry_system_acquire_by_id(u32 id){if(id!INVALID_IDstate_ptr-registered_geometries[id].geometry.id!INVALID_ID){state_ptr-registered_geometries[id].reference_count;returnstate_ptr-registered_geometries[id].geometry;}KERROR(geometry_system_acquire_by_id cannot load invalid geometry id.);return0;}釋放幾何體/** * brief 釋放幾何體引用 * param geometry 要釋放的幾何體 */voidgeometry_system_release(geometry*geometry){if(geometrygeometry-id!INVALID_ID){geometry_reference*refstate_ptr-registered_geometries[geometry-id];u32 idgeometry-id;if(ref-geometry.idgeometry-id){if(ref-reference_count0){ref-reference_count--;}// 引用計(jì)數(shù)歸零且auto_releasetrue時(shí)銷毀if(ref-reference_count1ref-auto_release){destroy_geometry(state_ptr,ref-geometry);ref-reference_count0;ref-auto_releasefalse;}}else{KFATAL(Geometry id mismatch. Check registration logic.);}return;}KWARN(geometry_system_release cannot release invalid geometry id.);}幾何體創(chuàng)建與銷毀/** * brief 創(chuàng)建幾何體 */b8create_geometry(geometry_system_state*state,geometry_config config,geometry*g){// 將幾何體發(fā)送到渲染器上傳到GPUif(!renderer_create_geometry(g,config.vertex_count,config.vertices,config.index_count,config.indices)){// 創(chuàng)建失敗無(wú)效化條目state-registered_geometries[g-id].reference_count0;state-registered_geometries[g-id].auto_releasefalse;g-idINVALID_ID;g-generationINVALID_ID;g-internal_idINVALID_ID;returnfalse;}// 獲取材質(zhì)if(string_length(config.material_name)0){g-materialmaterial_system_acquire(config.material_name);if(!g-material){g-materialmaterial_system_get_default();}}returntrue;}/** * brief 銷毀幾何體 */voiddestroy_geometry(geometry_system_state*state,geometry*g){// 銷毀渲染器資源renderer_destroy_geometry(g);g-internal_idINVALID_ID;g-generationINVALID_ID;g-idINVALID_ID;string_empty(g-name);// 釋放材質(zhì)引用if(g-materialstring_length(g-material-name)0){material_system_release(g-material-name);g-material0;}}默認(rèn)幾何體b8create_default_geometry(geometry_system_state*state){vertex_3d verts[4];kzero_memory(verts,sizeof(vertex_3d)*4);constf32 f10.0f;// 創(chuàng)建一個(gè)四邊形// 布局// 0────3// │ │// 2────1verts[0].position.x-0.5*f;verts[0].position.y-0.5*f;verts[0].texcoord.x0.0f;verts[0].texcoord.y0.0f;verts[1].position.x0.5*f;verts[1].position.y0.5*f;verts[1].texcoord.x1.0f;verts[1].texcoord.y1.0f;verts[2].position.x-0.5*f;verts[2].position.y0.5*f;verts[2].texcoord.x0.0f;verts[2].texcoord.y1.0f;verts[3].position.x0.5*f;verts[3].position.y-0.5*f;verts[3].texcoord.x1.0f;verts[3].texcoord.y0.0f;u32 indices[6]{0,1,2,0,3,1};// 上傳到GPUif(!renderer_create_geometry(state-default_geometry,4,verts,6,indices)){KFATAL(Failed to create default geometry.);returnfalse;}// 獲取默認(rèn)材質(zhì)state-default_geometry.materialmaterial_system_get_default();returntrue;}程序化幾何體生成幾何體系統(tǒng)提供了程序化生成基礎(chǔ)形狀的功能。平面生成器/** * brief 生成平面幾何體配置 * param width 平面寬度 * param height 平面高度 * param x_segment_count X軸分段數(shù) * param y_segment_count Y軸分段數(shù) * param tile_x X軸紋理平鋪次數(shù) * param tile_y Y軸紋理平鋪次數(shù) * param name 幾何體名稱 * param material_name 材質(zhì)名稱 * return 幾何體配置 */geometry_configgeometry_system_generate_plane_config(f32 width,f32 height,u32 x_segment_count,u32 y_segment_count,f32 tile_x,f32 tile_y,constchar*name,constchar*material_name){// 參數(shù)驗(yàn)證if(width0){KWARN(Width must be nonzero. Defaulting to one.);width1.0f;}if(height0){KWARN(Height must be nonzero. Defaulting to one.);height1.0f;}if(x_segment_count1){KWARN(x_segment_count must be positive. Defaulting to one.);x_segment_count1;}if(y_segment_count1){KWARN(y_segment_count must be positive. Defaulting to one.);y_segment_count1;}if(tile_x0){KWARN(tile_x must be nonzero. Defaulting to one.);tile_x1.0f;}if(tile_y0){KWARN(tile_y must be nonzero. Defaulting to one.);tile_y1.0f;}geometry_config config;// 計(jì)算頂點(diǎn)和索引數(shù)量// 每個(gè)分段需要4個(gè)頂點(diǎn)和6個(gè)索引2個(gè)三角形config.vertex_countx_segment_count*y_segment_count*4;config.verticeskallocate(sizeof(vertex_3d)*config.vertex_count,MEMORY_TAG_ARRAY);config.index_countx_segment_count*y_segment_count*6;config.indiceskallocate(sizeof(u32)*config.index_count,MEMORY_TAG_ARRAY);// 計(jì)算分段尺寸f32 seg_widthwidth/x_segment_count;f32 seg_heightheight/y_segment_count;f32 half_widthwidth*0.5f;f32 half_heightheight*0.5f;// 生成每個(gè)分段for(u32 y0;yy_segment_count;y){for(u32 x0;xx_segment_count;x){// 計(jì)算分段邊界f32 min_x(x*seg_width)-half_width;f32 min_y(y*seg_height)-half_height;f32 max_xmin_xseg_width;f32 max_ymin_yseg_height;// 計(jì)算UV坐標(biāo)f32 min_uvx(x/(f32)x_segment_count)*tile_x;f32 min_uvy(y/(f32)y_segment_count)*tile_y;f32 max_uvx((x1)/(f32)x_segment_count)*tile_x;f32 max_uvy((y1)/(f32)y_segment_count)*tile_y;// 頂點(diǎn)偏移u32 v_offset((y*x_segment_count)x)*4;vertex_3d*v0config.vertices[v_offset0];vertex_3d*v1config.vertices[v_offset1];vertex_3d*v2config.vertices[v_offset2];vertex_3d*v3config.vertices[v_offset3];// 生成4個(gè)頂點(diǎn)逆時(shí)針// v0──v3// │ │// v2──v1v0-position.xmin_x;v0-position.ymin_y;v0-texcoord.xmin_uvx;v0-texcoord.ymin_uvy;v1-position.xmax_x;v1-position.ymax_y;v1-texcoord.xmax_uvx;v1-texcoord.ymax_uvy;v2-position.xmin_x;v2-position.ymax_y;v2-texcoord.xmin_uvx;v2-texcoord.ymax_uvy;v3-position.xmax_x;v3-position.ymin_y;v3-texcoord.xmax_uvx;v3-texcoord.ymin_uvy;// 生成6個(gè)索引2個(gè)三角形u32 i_offset((y*x_segment_count)x)*6;config.indices[i_offset0]v_offset0;// 三角形1config.indices[i_offset1]v_offset1;config.indices[i_offset2]v_offset2;config.indices[i_offset3]v_offset0;// 三角形2config.indices[i_offset4]v_offset3;config.indices[i_offset5]v_offset1;}}// 設(shè)置名稱if(namestring_length(name)0){string_ncopy(config.name,name,GEOMETRY_NAME_MAX_LENGTH);}else{string_ncopy(config.name,DEFAULT_GEOMETRY_NAME,GEOMETRY_NAME_MAX_LENGTH);}// 設(shè)置材質(zhì)名稱if(material_namestring_length(material_name)0){string_ncopy(config.material_name,material_name,MATERIAL_NAME_MAX_LENGTH);}else{string_ncopy(config.material_name,DEFAULT_MATERIAL_NAME,MATERIAL_NAME_MAX_LENGTH);}returnconfig;}平面生成示意圖1x1分段平面最簡(jiǎn)單情況 v0────v3 │ ╱ │ │╱ │ v2────v1 頂點(diǎn)v0, v1, v2, v3 索引0,1,2, 0,3,1 2x2分段平面 v0──v3──v6──v9 │ ╱ │ ╱ │ ╱ │ v2──v5──v8──v11 │ ╱ │ ╱ │ ╱ │ v1──v4──v7──v10 │ ╱ │ ╱ │ ╱ │ v0──v3──v6──v9 4個(gè)分段 16個(gè)頂點(diǎn)24個(gè)索引 紋理平鋪tile_x2, tile_y2 UV坐標(biāo)會(huì)超過(guò)[0,1]范圍觸發(fā)紋理重復(fù) ┌───┬───┐ │ T │ T │ T 紋理 ├───┼───┤ │ T │ T │ └───┴───┘ 渲染器集成渲染器接口更新engine/src/renderer/renderer_frontend.h// 幾何體操作b8renderer_create_geometry(geometry*geometry,u32 vertex_count,constvertex_3d*vertices,u32 index_count,constu32*indices);voidrenderer_destroy_geometry(geometry*geometry);Vulkan后端實(shí)現(xiàn)幾何體在Vulkan中對(duì)應(yīng)頂點(diǎn)和索引緩沖區(qū)的偏移engine/src/renderer/vulkan/vulkan_backend.cb8vulkan_renderer_create_geometry(geometry*geometry,u32 vertex_count,constvertex_3d*vertices,u32 index_count,constu32*indices){if(!vertex_count||!vertices){KERROR(vulkan_renderer_create_geometry requires vertex data.);returnfalse;}// 檢查是否有索引數(shù)據(jù)b8 is_indexedindex_count0indices;// 為幾何體分配內(nèi)部ID緩沖區(qū)偏移geometry-internal_idcontext.geometry_vertex_offset;// 上傳頂點(diǎn)數(shù)據(jù)u32 sizesizeof(vertex_3d)*vertex_count;if(!upload_data_range(context,context.device.graphics_command_pool,0,context.device.graphics_queue,context.object_vertex_buffer,context.geometry_vertex_offset,size,vertices)){KERROR(Failed to upload geometry vertices.);returnfalse;}context.geometry_vertex_offsetvertex_count;// 上傳索引數(shù)據(jù)if(is_indexed){sizesizeof(u32)*index_count;if(!upload_data_range(context,context.device.graphics_command_pool,0,context.device.graphics_queue,context.object_index_buffer,context.geometry_index_offset,size,indices)){KERROR(Failed to upload geometry indices.);returnfalse;}context.geometry_index_offsetindex_count;}returntrue;}voidvulkan_renderer_destroy_geometry(geometry*geometry){if(geometrygeometry-internal_id!INVALID_ID){// TODO: 回收頂點(diǎn)/索引緩沖區(qū)空間// 當(dāng)前實(shí)現(xiàn)不回收只增長(zhǎng)geometry-internal_idINVALID_ID;}}注意當(dāng)前實(shí)現(xiàn)使用單個(gè)大緩沖區(qū)頂點(diǎn)和索引數(shù)據(jù)追加式上傳。這是一個(gè)簡(jiǎn)化實(shí)現(xiàn)生產(chǎn)環(huán)境應(yīng)該支持緩沖區(qū)回收和碎片整理。渲染包系統(tǒng)為了高效渲染多個(gè)幾何體我們引入**渲染包Render Packet**概念。渲染包結(jié)構(gòu)engine/src/renderer/renderer_types.inl/** * brief 幾何體渲染數(shù)據(jù) */typedefstructgeometry_render_data{mat4 model;// 模型變換矩陣geometry*geometry;// 幾何體指針}geometry_render_data;/** * brief 渲染包一幀中要渲染的所有數(shù)據(jù) */typedefstructrender_packet{f32 delta_time;// 幀間隔時(shí)間u32 geometry_count;// 幾何體數(shù)量geometry_render_data*geometries;// 幾何體數(shù)組}render_packet;渲染包使用流程游戲邏輯渲染器Vulkan后端準(zhǔn)備render_packet添加幾何體到packetgeometries[i] {model, geometry}loop[每個(gè)可見對(duì)象]renderer_draw_frame(packet)begin_frame()update_global_state(proj, view)draw_geometry(geom_data)更新材質(zhì)UBOvkCmdDrawIndexed()loop[每個(gè)幾何體]end_frame()vkQueueSubmit()游戲邏輯渲染器Vulkan后端更新渲染循環(huán)engine/src/renderer/renderer_frontend.cb8renderer_draw_frame(render_packet*packet){if(renderer_begin_frame(packet-delta_time)){// 更新全局狀態(tài)state_ptr-backend.update_global_state(state_ptr-projection,state_ptr-view,vec3_zero(),vec4_one(),0);// 繪制所有幾何體for(u32 i0;ipacket-geometry_count;i){state_ptr-backend.draw_geometry(packet-geometries[i]);}// 結(jié)束幀b8 resultrenderer_end_frame(packet-delta_time);if(!result){KERROR(renderer_end_frame failed.);returnfalse;}}returntrue;}后端繪制函數(shù)voidvulkan_renderer_draw_geometry(geometry_render_data data){// 更新材質(zhì)著色器vulkan_material_shader_set_model(context,context.material_shader,data.model);vulkan_material_shader_apply_material(context,context.material_shader,data.geometry-material);// 綁定頂點(diǎn)和索引緩沖區(qū)VkDeviceSize offsets[1]{data.geometry-internal_id*sizeof(vertex_3d)};vkCmdBindVertexBuffers(command_buffer,0,1,context.object_vertex_buffer.handle,offsets);if(data.geometry-index_count0){vkCmdBindIndexBuffer(command_buffer,context.object_index_buffer.handle,data.geometry-internal_id*sizeof(u32),VK_INDEX_TYPE_UINT32);vkCmdDrawIndexed(command_buffer,data.geometry-index_count,1,0,0,0);}else{vkCmdDraw(command_buffer,data.geometry-vertex_count,1,0,0);}}使用示例示例1創(chuàng)建簡(jiǎn)單幾何體voidcreate_simple_quad(){// 生成平面配置geometry_config configgeometry_system_generate_plane_config(10.0f,10.0f,// 寬度、高度1,1,// 1x1分段1.0f,1.0f,// 紋理平鋪1次my_quad,// 幾何體名稱wood// 材質(zhì)名稱);// 獲取幾何體geometry*quadgeometry_system_acquire_from_config(config,true);// 使用幾何體...// 釋放geometry_system_release(quad);// 清理配置中分配的內(nèi)存kfree(config.vertices,sizeof(vertex_3d)*config.vertex_count,MEMORY_TAG_ARRAY);kfree(config.indices,sizeof(u32)*config.index_count,MEMORY_TAG_ARRAY);}示例2渲染多個(gè)幾何體voidrender_scene(render_packet*packet){packet-geometry_count3;packet-geometrieskallocate(sizeof(geometry_render_data)*3,MEMORY_TAG_ARRAY);// 地板packet-geometries[0].geometryfloor_geometry;packet-geometries[0].modelmat4_translation(vec3(0,-1,0));// 墻壁1packet-geometries[1].geometrywall_geometry;packet-geometries[1].modelmat4_translation(vec3(-5,0,0));// 墻壁2packet-geometries[2].geometrywall_geometry;packet-geometries[2].modelmat4_translation(vec3(5,0,0));renderer_draw_frame(packet);kfree(packet-geometries,sizeof(geometry_render_data)*3,MEMORY_TAG_ARRAY);}示例3程序化生成地形voidcreate_terrain(){// 生成大平面作為地形geometry_config configgeometry_system_generate_plane_config(100.0f,100.0f,// 100x100單位10,10,// 10x10分段100個(gè)四邊形10.0f,10.0f,// 紋理平鋪10次terrain,grass);geometry*terraingeometry_system_acquire_from_config(config,false);// 常駐不釋放// 清理kfree(config.vertices,sizeof(vertex_3d)*config.vertex_count,MEMORY_TAG_ARRAY);kfree(config.indices,sizeof(u32)*config.index_count,MEMORY_TAG_ARRAY);}示例4共享幾何體// 創(chuàng)建一個(gè)立方體幾何體geometry*cube_geomcreate_cube_geometry();// 多個(gè)對(duì)象共享同一幾何體但使用不同變換voidrender_cubes(render_packet*packet){packet-geometry_count10;packet-geometrieskallocate(sizeof(geometry_render_data)*10,MEMORY_TAG_ARRAY);for(u32 i0;i10;i){packet-geometries[i].geometrycube_geom;// 共享幾何體packet-geometries[i].modelmat4_translation(vec3(i*2,0,0));// 不同位置}renderer_draw_frame(packet);}? 常見問(wèn)題? 幾何體和材質(zhì)是如何關(guān)聯(lián)的幾何體結(jié)構(gòu)中有一個(gè)material*指針typedefstructgeometry{// ...material*material;}geometry;在創(chuàng)建幾何體時(shí)如果config中指定了材質(zhì)名稱系統(tǒng)會(huì)自動(dòng)獲取材質(zhì)if(string_length(config.material_name)0){g-materialmaterial_system_acquire(config.material_name);}渲染時(shí)從幾何體獲取材質(zhì)voiddraw_geometry(geometry_render_data data){material*matdata.geometry-material;// 使用材質(zhì)的顏色和紋理...}? 為什么幾何體系統(tǒng)沒(méi)有哈希表設(shè)計(jì)差異紋理/材質(zhì)系統(tǒng)通過(guò)名稱查找“wood”, metal等需要哈希表name → handle → resource幾何體系統(tǒng)通過(guò)ID直接索引數(shù)組訪問(wèn)registered_geometries[id]原因幾何體通常不需要名稱查找?guī)缀误w經(jīng)常動(dòng)態(tài)創(chuàng)建程序化生成ID直接對(duì)應(yīng)數(shù)組索引更高效如果需要名稱查找可以自己維護(hù)一個(gè)映射hashtable geometry_name_to_id;u32 idhashtable_get(geometry_name_to_id,my_quad);geometry*ggeometry_system_acquire_by_id(id);? generate_plane_config為什么分配內(nèi)存因?yàn)轫旤c(diǎn)和索引數(shù)組的大小是動(dòng)態(tài)的config.vertex_countx_segment_count*y_segment_count*4;config.verticeskallocate(sizeof(vertex_3d)*config.vertex_count,...);調(diào)用者負(fù)責(zé)釋放geometry_config configgeometry_system_generate_plane_config(...);geometry*ggeometry_system_acquire_from_config(config,true);// 幾何體已上傳到GPU可以釋放CPU內(nèi)存kfree(config.vertices,...);kfree(config.indices,...);為什么不在系統(tǒng)內(nèi)部釋放調(diào)用者可能需要修改配置調(diào)用者可能復(fù)用配置創(chuàng)建多個(gè)幾何體遵循誰(shuí)分配誰(shuí)釋放原則? internal_id是什么internal_id是幾何體在GPU緩沖區(qū)中的偏移// 創(chuàng)建時(shí)geometry-internal_idcontext.geometry_vertex_offset;// 如0, 4, 8, ...// 繪制時(shí)VkDeviceSize offsetgeometry-internal_id*sizeof(vertex_3d);vkCmdBindVertexBuffers(...,offset);示例頂點(diǎn)緩沖區(qū) ┌──────────┬──────────┬──────────┐ │ Quad (4) │ Cube (8) │Plane (16)│ ├──────────┼──────────┼──────────┤ │ Offset │ Offset │ Offset │ │ 0 │ 4 │ 12 │ └──────────┴──────────┴──────────┘ ↑ ↑ ↑ internal_id internal_id internal_id? 如何支持多個(gè)LOD級(jí)別LODLevel of Detail可以通過(guò)創(chuàng)建多個(gè)幾何體實(shí)現(xiàn)typedefstructmesh{geometry*lod0;// 高精度geometry*lod1;// 中精度geometry*lod2;// 低精度}mesh;geometry*select_lod(mesh*m,f32 distance){if(distance10.0f)returnm-lod0;if(distance50.0f)returnm-lod1;returnm-lod2;}// 渲染時(shí)geometry*geomselect_lod(my_mesh,camera_distance);render_data.geometrygeom; 練習(xí)與挑戰(zhàn)練習(xí)1實(shí)現(xiàn)立方體生成器創(chuàng)建一個(gè)函數(shù)生成立方體幾何體geometry_configgeometry_system_generate_cube_config(f32 size,constchar*name,constchar*material_name);查看提示立方體有6個(gè)面每個(gè)面是2個(gè)三角形4頂點(diǎn)6索引// 總共24個(gè)頂點(diǎn)36個(gè)索引config.vertex_count24;config.index_count36;// 前面vertices[0-3]...indices[0-5]{0,1,2,0,2,3};// 后面vertices[4-7]...indices[6-11]{4,5,6,4,6,7};// ... 其他4個(gè)面練習(xí)2頂點(diǎn)去重generate_plane_config生成了重復(fù)頂點(diǎn)。實(shí)現(xiàn)一個(gè)函數(shù)去重voiddeduplicate_vertices(geometry_config*config);查看提示遍歷所有頂點(diǎn)查找重復(fù)的頂點(diǎn)position和texcoord都相同建立舊索引到新索引的映射重新映射索引數(shù)組創(chuàng)建新的頂點(diǎn)數(shù)組for(u32 i0;iold_vertex_count;i){b8 foundfalse;for(u32 j0;jnew_vertex_count;j){if(vertices_equal(old_vertices[i],new_vertices[j])){index_map[i]j;foundtrue;break;}}if(!found){new_vertices[new_vertex_count]old_vertices[i];index_map[i]new_vertex_count;}}// 重新映射索引for(u32 i0;iindex_count;i){indices[i]index_map[indices[i]];}練習(xí)3從OBJ文件加載幾何體實(shí)現(xiàn)一個(gè)簡(jiǎn)單的OBJ加載器b8load_obj_file(constchar*path,geometry_config*out_config);查看提示OBJ格式示例v 0.0 0.0 0.0 # 頂點(diǎn)位置 vt 0.0 0.0 # 紋理坐標(biāo) f 1/1 2/2 3/3 # 面索引從1開始解析步驟逐行讀取文件識(shí)別v,vt,f開頭的行提取數(shù)值并存儲(chǔ)構(gòu)建geometry_config 下一步在本教程中我們實(shí)現(xiàn)了完整的幾何體系統(tǒng)? 幾何體數(shù)據(jù)結(jié)構(gòu)頂點(diǎn)索引材質(zhì)? 幾何體系統(tǒng)引用計(jì)數(shù)ID索引? 程序化生成平面生成器? 渲染包系統(tǒng)批量提交? 與材質(zhì)系統(tǒng)集成幾何體系統(tǒng)是渲染管線的最后一塊拼圖?,F(xiàn)在我們有了紋理系統(tǒng)管理圖像數(shù)據(jù)材質(zhì)系統(tǒng)管理外觀屬性幾何體系統(tǒng)管理形狀數(shù)據(jù)下一步我們可以實(shí)現(xiàn)資源系統(tǒng)- 統(tǒng)一管理所有資源類型場(chǎng)景系統(tǒng)- 組織場(chǎng)景中的對(duì)象模型加載器- 從文件加載3D模型實(shí)例化渲染- 高效渲染大量相同幾何體結(jié)語(yǔ)恭喜你完成了本教程幾何體系統(tǒng)讓我們可以高效管理和渲染3D形狀。通過(guò)程序化生成、引用計(jì)數(shù)、渲染包等機(jī)制我們構(gòu)建了一個(gè)靈活且高效的幾何體管理系統(tǒng)。結(jié)合之前的紋理和材質(zhì)系統(tǒng)Kohi引擎現(xiàn)在已經(jīng)具備了渲染復(fù)雜3D場(chǎng)景的基礎(chǔ)能力。關(guān)鍵要點(diǎn)回顧幾何體 頂點(diǎn) 索引 材質(zhì)ID索引比名稱查找更適合幾何體程序化生成可以創(chuàng)建基礎(chǔ)形狀渲染包支持批量提交幾何體引用計(jì)數(shù)自動(dòng)管理資源生命周期隨著系統(tǒng)的成熟可以添加更多高級(jí)特性骨骼動(dòng)畫、變形目標(biāo)、GPU實(shí)例化、LOD系統(tǒng)等。如果你有任何問(wèn)題或建議歡迎在GitHub上提出issue。關(guān)注公眾號(hào)獲取更多引擎開發(fā)資訊覺(jué)得有幫助請(qǐng)作者喝杯咖啡 作者: 上手實(shí)驗(yàn)室 項(xiàng)目地址: https://github.com/travisvroman/kohi上一篇材質(zhì)系統(tǒng) | 下一篇資源系統(tǒng)
版權(quán)聲明: 本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)聯(lián)系我們進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

設(shè)計(jì)一個(gè)網(wǎng)站的步驟夏天做哪個(gè)網(wǎng)站能致富

設(shè)計(jì)一個(gè)網(wǎng)站的步驟,夏天做哪個(gè)網(wǎng)站能致富,國(guó)際設(shè)計(jì)網(wǎng),建設(shè)商城類網(wǎng)站多少錢背景 本課題聚焦公眾健康飲食個(gè)性化、科學(xué)化的需求#xff0c;設(shè)計(jì)開發(fā)基于Hadoop的健康飲食推薦系統(tǒng)。項(xiàng)目以Hadoop生

2026/01/23 12:56:02

一般設(shè)計(jì)網(wǎng)站頁(yè)面用什么軟件做企業(yè)管理公司

一般設(shè)計(jì)網(wǎng)站頁(yè)面用什么軟件做,企業(yè)管理公司,瀏覽器游戲網(wǎng)址,seo網(wǎng)站優(yōu)化培訓(xùn)多少價(jià)格第一章#xff1a;大模型自動(dòng)化新紀(jì)元的開啟人工智能正邁入一個(gè)由大規(guī)模語(yǔ)言模型驅(qū)動(dòng)的自動(dòng)化新時(shí)代。這些模型不僅能夠

2026/01/23 10:15:01

網(wǎng)站建設(shè)珠江摩爾建設(shè)網(wǎng)站報(bào)價(jià)單

網(wǎng)站建設(shè)珠江摩爾,建設(shè)網(wǎng)站報(bào)價(jià)單,前端做用vue做后臺(tái)多還是做網(wǎng)站多,品牌網(wǎng)站建設(shè)優(yōu)化公司哪家好你是否曾經(jīng)遇到過(guò)這樣的情況#xff1a;看到一個(gè)精彩的B站視頻想要收藏#xff0c;卻發(fā)現(xiàn)無(wú)法離線觀看#

2026/01/22 22:44:01

營(yíng)銷手機(jī)網(wǎng)站制作網(wǎng)站建設(shè) 鎮(zhèn)江

營(yíng)銷手機(jī)網(wǎng)站制作,網(wǎng)站建設(shè) 鎮(zhèn)江,廣州做網(wǎng)站公司哪家好,各大網(wǎng)站開發(fā)的區(qū)塊鏈PaddlePaddle鏡像與隱私計(jì)算技術(shù)的融合路徑 在金融風(fēng)控模型訓(xùn)練中#xff0c;一家銀行想提升反欺詐能力#xff0

2026/01/21 17:35:01