什么是跨IB渲染?
部分游戏中,身体和衣服使用了不同的Shader进行渲染,使用不同渲染的部分一般不在同一个IB中,导致材质和光照效果不同,在部分情况下,如果我们想让某个部分使用另一个部分的光照和材质Shader进行渲染,就需要用到跨IB渲染技术。
这个名字是我自己随便起的,没有英文对应的技术名词。
实现方法
首先把最终的Mod的ini先贴过来,方便随时参考:
;MARK:Constants----------------------------------------------------------
[Constants]
global $active0
global $active1
global $active2
global persist $swapkey0 = 0
global persist $swapkey1 = 1
;MARK:Present----------------------------------------------------------
[Present]
post $active0 = 0
post $active1 = 0
post $active2 = 0
;MARK:Key----------------------------------------------------------
[KeySwap_0]
condition = $active0 == 1
key = f7
type = cycle
$swapkey0 = 0,1,
;MARK:Key----------------------------------------------------------
[KeySwap_1]
condition = $active0 == 1
key = f8
type = cycle
$swapkey1 = 0,1,
;MARK:TextureOverrideVertexLimitRaise----------------------------------------------------------
[TextureOverride_6b3c1103_丝袜_VertexLimitRaise]
hash = 0ba52f8d
override_byte_stride = 40
override_vertex_count = 1025
uav_byte_stride = 4
;MARK:TextureOverrideVertexLimitRaise----------------------------------------------------------
[TextureOverride_81d8e71a_衣服_VertexLimitRaise]
hash = 1f516443
override_byte_stride = 40
override_vertex_count = 36397
uav_byte_stride = 4
;MARK:TextureOverrideVertexLimitRaise----------------------------------------------------------
[TextureOverride_298dc3b2_腿和脖子_VertexLimitRaise]
hash = 175c6c67
override_byte_stride = 40
override_vertex_count = 1051
uav_byte_stride = 4
;MARK:TextureOverrideVB----------------------------------------------------------
; 6b3c1103 ----------------------------
[TextureOverride_VB_6b3c1103_丝袜_Position]
hash = 9ca19154
cs-cb0 = Resource_6b3c1103_VertexLimit
cs-t0 = Resource6b3c1103Position
cs-t1 = Resource6b3c1103Blend
handling = skip
dispatch = 18,1,1
$active0 = 1
[TextureOverride_VB_6b3c1103_丝袜_Texcoord]
hash = 62585f16
vb1 = Resource6b3c1103Texcoord
[TextureOverride_VB_6b3c1103_丝袜_Blend]
hash = 13c142be
;MARK:TextureOverrideVB----------------------------------------------------------
; 81d8e71a ----------------------------
[TextureOverride_VB_81d8e71a_衣服_Position]
hash = 07f702b9
cs-cb0 = Resource_81d8e71a_VertexLimit
cs-t0 = Resource81d8e71aPosition
cs-t1 = Resource81d8e71aBlend
handling = skip
dispatch = 570,1,1
$active1 = 1
[TextureOverride_VB_81d8e71a_衣服_Texcoord]
hash = d4615e17
vb1 = Resource81d8e71aTexcoord
[TextureOverride_VB_81d8e71a_衣服_Blend]
hash = c123de45
;MARK:TextureOverrideVB----------------------------------------------------------
; 298dc3b2 ----------------------------
[TextureOverride_VB_298dc3b2_腿和脖子_Position]
hash = e3ca0283
cs-cb0 = Resource_298dc3b2_VertexLimit
cs-t0 = Resource298dc3b2Position
cs-t1 = Resource298dc3b2Blend
handling = skip
dispatch = 18,1,1
$active2 = 1
[TextureOverride_VB_298dc3b2_腿和脖子_Texcoord]
hash = c3af7d47
vb1 = Resource298dc3b2Texcoord
[TextureOverride_VB_298dc3b2_腿和脖子_Blend]
hash = 60cc2063
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_6b3c1103_丝袜_Component1]
hash = 6b3c1103
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_6b3c1103_Component1
if $swapkey0 == 1
; [mesh:6b3c1103-1-丝袜.001] [vertex_count:1025]
drawindexed = 5517,0,0
endif
[Resource_VB0]
[Resource_VB1]
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_81d8e71a_衣服_Component1]
hash = 81d8e71a
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_81d8e71a_Component1
if $swapkey1 == 1
; [mesh:81d8e71a-1-水印] [vertex_count:27152]
drawindexed = 38829,0,0
endif
; [mesh:81d8e71a-1-衣服.001] [vertex_count:6687]
drawindexed = 31557,38829,0
Resource_VB0 = ref vb0
Resource_VB1 = ref vb1
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_298dc3b2_腿和脖子_Component1]
hash = 298dc3b2
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_298dc3b2_Component1
ps-t8 = Resource_298dc3b2_1_d4b0a178_Slot_DiffuseMap
; [mesh:298dc3b2-1-腿和脖子.001] [vertex_count:1051]
drawindexed = 5517,0,0
ib = Resource_81d8e71a_Component1
vb0 = Resource_VB0
vb1 = Resource_VB1
; [mesh:81d8e71a-1-身体跨IB] [vertex_count:2558]
drawindexed = 13836,70386,0
;MARK:ResourceBuffer----------------------------------------------------------
[Resource_6b3c1103_VertexLimit]
type = Buffer
format = R32G32B32A32_UINT
data = 1025 0 0 0
;MARK:ResourceBuffer----------------------------------------------------------
[Resource6b3c1103Position]
type = ByteAddressBuffer
stride = 40
filename = Buffer/6b3c1103-Position.buf
[Resource6b3c1103Texcoord]
type = Buffer
stride = 8
filename = Buffer/6b3c1103-Texcoord.buf
[Resource6b3c1103Blend]
type = ByteAddressBuffer
stride = 32
filename = Buffer/6b3c1103-Blend.buf
[Resource_6b3c1103_Component1]
type = Buffer
format = DXGI_FORMAT_R32_UINT
filename = Buffer/6b3c1103-Component1.buf
;MARK:ResourceBuffer----------------------------------------------------------
[Resource_81d8e71a_VertexLimit]
type = Buffer
format = R32G32B32A32_UINT
data = 36397 0 0 0
;MARK:ResourceBuffer----------------------------------------------------------
[Resource81d8e71aPosition]
type = ByteAddressBuffer
stride = 40
filename = Buffer/81d8e71a-Position.buf
[Resource81d8e71aTexcoord]
type = Buffer
stride = 8
filename = Buffer/81d8e71a-Texcoord.buf
[Resource81d8e71aBlend]
type = ByteAddressBuffer
stride = 32
filename = Buffer/81d8e71a-Blend.buf
[Resource_81d8e71a_Component1]
type = Buffer
format = DXGI_FORMAT_R32_UINT
filename = Buffer/81d8e71a-Component1.buf
;MARK:ResourceBuffer----------------------------------------------------------
[Resource_298dc3b2_VertexLimit]
type = Buffer
format = R32G32B32A32_UINT
data = 1051 0 0 0
;MARK:ResourceBuffer----------------------------------------------------------
[Resource298dc3b2Position]
type = ByteAddressBuffer
stride = 40
filename = Buffer/298dc3b2-Position.buf
[Resource298dc3b2Texcoord]
type = Buffer
stride = 8
filename = Buffer/298dc3b2-Texcoord.buf
[Resource298dc3b2Blend]
type = ByteAddressBuffer
stride = 32
filename = Buffer/298dc3b2-Blend.buf
[Resource_298dc3b2_Component1]
type = Buffer
format = DXGI_FORMAT_R32_UINT
filename = Buffer/298dc3b2-Component1.buf
;MARK:ResourceTexture----------------------------------------------------------
[Resource_298dc3b2_1_d4b0a178_Slot_DiffuseMap]
filename = Texture/298dc3b2_1_d4b0a178_Slot_DiffuseMap.dds
;MARK:VertexShaderCheck----------------------------------------------------------
[ShaderOverride_a3c5c0c308ddeb69]
hash = a3c5c0c308ddeb69
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_e0f9ed199a2a5226]
hash = e0f9ed199a2a5226
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_98d23592a35efad9]
hash = 98d23592a35efad9
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_1757673cfe604ebe]
hash = 1757673cfe604ebe
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_2030c989673a6153]
hash = 2030c989673a6153
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_50bca0018babfea7]
hash = 50bca0018babfea7
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_3a66ac7f1cda3dd7]
hash = 3a66ac7f1cda3dd7
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_b57c0b15f73f5439]
hash = b57c0b15f73f5439
if $costume_mods
checktextureoverride = ib
endif
[ShaderOverride_e81384063af12b94]
hash = e81384063af12b94
if $costume_mods
checktextureoverride = ib
endif
;sha256=180ab2c539fc9db7795401fdf5af7c4fb102d09b97ce65a7c809e8ebaa681718
这里有很多内容是用不到的,我们去掉部分无效内容,只关注核心的几行。
[TextureOverride_VB_6b3c1103_丝袜_Texcoord]
hash = 62585f16
vb1 = Resource6b3c1103Texcoord
[TextureOverride_VB_81d8e71a_衣服_Texcoord]
hash = d4615e17
vb1 = Resource81d8e71aTexcoord
[TextureOverride_VB_298dc3b2_腿和脖子_Texcoord]
hash = c3af7d47
vb1 = Resource298dc3b2Texcoord
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_6b3c1103_丝袜_Component1]
hash = 6b3c1103
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_6b3c1103_Component1
if $swapkey0 == 1
; [mesh:6b3c1103-1-丝袜.001] [vertex_count:1025]
drawindexed = 5517,0,0
endif
[Resource_VB0]
[Resource_VB1]
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_81d8e71a_衣服_Component1]
hash = 81d8e71a
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_81d8e71a_Component1
if $swapkey1 == 1
; [mesh:81d8e71a-1-水印] [vertex_count:27152]
drawindexed = 38829,0,0
endif
; [mesh:81d8e71a-1-衣服.001] [vertex_count:6687]
drawindexed = 31557,38829,0
Resource_VB0 = ref vb0
Resource_VB1 = ref vb1
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_298dc3b2_腿和脖子_Component1]
hash = 298dc3b2
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_298dc3b2_Component1
ps-t8 = Resource_298dc3b2_1_d4b0a178_Slot_DiffuseMap
; [mesh:298dc3b2-1-腿和脖子.001] [vertex_count:1051]
drawindexed = 5517,0,0
ib = Resource_81d8e71a_Component1
vb0 = Resource_VB0
vb1 = Resource_VB1
; [mesh:81d8e71a-1-身体跨IB] [vertex_count:2558]
drawindexed = 13836,70386,0
首先我们知道
TextureOverride_IB_81d8e71a_衣服_Component1
它是复制一部分衣服的部分
TextureOverride_IB_298dc3b2_腿和脖子_Component1
它负责身体的部分
那么如果要实现跨IB渲染,我们就需要在身体的部分,把我们用衣服部分传递权重制作的身体模型给渲染出来。
所以首先,我们会在衣服的部分备份vb0和vb1:
[Resource_VB0]
[Resource_VB1]
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_81d8e71a_衣服_Component1]
hash = 81d8e71a
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_81d8e71a_Component1
if $swapkey1 == 1
; [mesh:81d8e71a-1-水印] [vertex_count:27152]
drawindexed = 38829,0,0
endif
; [mesh:81d8e71a-1-衣服.001] [vertex_count:6687]
drawindexed = 31557,38829,0
Resource_VB0 = ref vb0
Resource_VB1 = ref vb1
这里的
[Resource_VB0]
[Resource_VB1]
就是声明资源 这里的
Resource_VB0 = ref vb0
Resource_VB1 = ref vb1
就是备份资源
备份完成资源后,要在身体的部分DrawIndexed出来,在DrawIndexed之前,需要替换IB、VB0、VB1,如下:
;MARK:TextureOverrideIB----------------------------------------------------------
[TextureOverride_IB_298dc3b2_腿和脖子_Component1]
hash = 298dc3b2
match_first_index = 0
checktextureoverride = vb1
handling = skip
ib = Resource_298dc3b2_Component1
ps-t8 = Resource_298dc3b2_1_d4b0a178_Slot_DiffuseMap
; [mesh:298dc3b2-1-腿和脖子.001] [vertex_count:1051]
drawindexed = 5517,0,0
ib = Resource_81d8e71a_Component1
vb0 = Resource_VB0
vb1 = Resource_VB1
; [mesh:81d8e71a-1-身体跨IB] [vertex_count:2558]
drawindexed = 13836,70386,0
这里的代码是我们额外加上的,加在身体部分正常drawindexed完成之后:
ib = Resource_81d8e71a_Component1
vb0 = Resource_VB0
vb1 = Resource_VB1
; [mesh:81d8e71a-1-身体跨IB] [vertex_count:2558]
drawindexed = 13836,70386,0
这里的
; [mesh:81d8e71a-1-身体跨IB] [vertex_count:2558]
drawindexed = 13836,70386,0
就是原本正常生成完Mod后,是在衣服部分drawindexed的,我们挪过来了。
到这里跨IB渲染就完成了,我们成功的把身体模型用衣服的权重来传递,并且在衣服的部位上生成Mod,最后使用跨IB渲染技术,在身体部位绘制,以达到衣服部位生成的mod使用身体材质渲染的效果。
每个游戏的跨IB方法,都要随机应变,甚至每种shader的跨IB方法都不一样,没有完全相同的方法适用于所有场景,理解其核心原理就好。
比如有些是在VB0的替换部分draw完成后copy So0的,比如有些除了copy vb0之外,还需要copy cs-t0等等来修正坐标系,具体Mod具体分析即可,如果不懂的话,首选方案还是找别人做好的跨IB渲染Mod来参考原理。