NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

TextureCompositor.py (20826B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\TextureCompositor\TextureCompositor.py
      2 from contextlib import contextmanager
      3 import trinity
      4 import blue
      5 import log
      6 RUN_RENDER_JOB, RETURN_RENDER_JOB = range(2)
      7 DIFFUSE_MAP, SPECULAR_MAP, NORMAL_MAP, MASK_MAP = range(4)
      8 MAPS = (DIFFUSE_MAP,
      9  SPECULAR_MAP,
     10  NORMAL_MAP,
     11  MASK_MAP)
     12 MAPNAMES = ('DiffuseMap', 'SpecularMap', 'NormalMap', 'CutMaskMap')
     13 EFFECT_LOCATION = 'res:/Graphics/Effect/Utility/Compositing'
     14 COMPOSITE_SHADER_PATHS = ['AlphaFill.fx',
     15  'BlitIntoAlpha1.fx',
     16  'BlitIntoAlpha2.fx',
     17  'BlitIntoAlphaWithZones.fx',
     18  'BlitUVOffset.fx',
     19  'ColorCopyblit.fx',
     20  'ColorCopyblitToGamma.fx',
     21  'ColorFill.fx',
     22  'ColorizedBlit.fx',
     23  'ColorizedBlit_AlphaTest.fx',
     24  'ColorizedCopyBlit.fx',
     25  'Copyblit.fx',
     26  'ExpandOpaque.fx',
     27  'ExpandOpaqueNoMask.fx',
     28  'MaskedNormalBlit.fx',
     29  'PatternBlit.fx',
     30  'SimpleBlit.fx',
     31  'SphericalCircleBlit.fx',
     32  'TwistNormalBlit.fx']
     33 COMPRESS_DXT1 = trinity.TR2DXT_COMPRESS_SQUISH_DXT1
     34 COMPRESS_DXT5 = trinity.TR2DXT_COMPRESS_SQUISH_DXT5
     35 COMPRESS_DXT5n = trinity.TR2DXT_COMPRESS_RT_DXT5N
     36 
     37 class TextureLoadingError(Exception):
     38     pass
     39 
     40 
     41 def _GetEffectsToCache():
     42     effects = []
     43     for each in COMPOSITE_SHADER_PATHS:
     44         effect = trinity.Tr2Effect()
     45         effect.effectFilePath = EFFECT_LOCATION + '/' + each
     46         effects.append(effect)
     47 
     48     return effects
     49 
     50 
     51 def _CreateParameter(paramType, paramName, paramValue):
     52     param = paramType
     53     param.name = paramName
     54     if isinstance(paramValue, list):
     55         paramValue = tuple(paramValue)
     56     param.value = paramValue
     57     return param
     58 
     59 
     60 def _AppendParameter(effect, paramName, paramValue):
     61     try:
     62         value = tuple(paramValue)
     63     except TypeError:
     64         value = (paramValue,)
     65 
     66     value += (0.0,) * (4 - len(value))
     67     effect.constParameters.append((paramName, value))
     68 
     69 
     70 @contextmanager
     71 def _UpdateEffect(effect):
     72     effect.StartUpdate()
     73     try:
     74         yield
     75     finally:
     76         effect.EndUpdate()
     77 
     78 
     79 class TextureCompositor(object):
     80     cachedEffects = None
     81 
     82     def __init__(self, renderTarget = None, resData = None, targetWidth = 0):
     83         self.renderJob = None
     84         self.renderTarget = renderTarget
     85         self.targetWidth = targetWidth
     86         self.resData = resData
     87         self._texturesWithCutouts = []
     88         self._texturesByResourceID = {}
     89         self._resourcesToLoad = []
     90         if not TextureCompositor.cachedEffects:
     91             TextureCompositor.cachedEffects = _GetEffectsToCache()
     92 
     93     def _CreateResource(self, effect, paramName, resPath, cutoutName = None, mapType = ''):
     94         if not resPath:
     95             raise Exception('Invalid resource passed to texture compositor!')
     96         elif isinstance(resPath, basestring):
     97             resPath = str(resPath)
     98             if self.targetWidth > 0 and self.resData:
     99                 resDataEntry = self.resData.GetEntryByFullResPath(resPath)
    100                 if resDataEntry:
    101                     resPath = resDataEntry.GetMapResolutonMatch(resPath, self.targetWidth)
    102             paramRes = blue.resMan.GetResource(resPath)
    103         elif isinstance(resPath, trinity.TriTextureRes):
    104             paramRes = resPath
    105         elif hasattr(resPath, 'resource'):
    106             paramRes = resPath.resource
    107         else:
    108             raise Exception('Invalid resource passed to texture compositor!')
    109         if paramRes is None:
    110             raise Exception('Invalid resource passed to texture compositor!')
    111         param = trinity.TriTextureParameter()
    112         param.name = paramName
    113         param.SetResource(paramRes)
    114         item = (paramRes,
    115          effect,
    116          cutoutName,
    117          mapType)
    118         if cutoutName:
    119             self._texturesWithCutouts.append(item)
    120         self._texturesByResourceID[id(paramRes)] = item
    121         if paramRes not in self._resourcesToLoad:
    122             self._resourcesToLoad.append(paramRes)
    123         return param
    124 
    125     def _AppendResource(self, effect, paramName, resPath, cutoutName = None, mapType = ''):
    126         effect.resources.append(self._CreateResource(effect, paramName, resPath, cutoutName, mapType))
    127 
    128     def _MakeEffect(self, effectName):
    129         effect = trinity.Tr2Effect()
    130         effect.effectFilePath = '{0}/{1}.fx'.format(EFFECT_LOCATION, effectName)
    131         self._resourcesToLoad.append(effect.effectResource)
    132         return effect
    133 
    134     def Start(self, clear = True):
    135         self.renderJob = trinity.CreateRenderJob('Texture Compositing')
    136         self.renderJob.PushRenderTarget(self.renderTarget)
    137         self.renderJob.PushDepthStencil(None)
    138         if clear:
    139             cl = self.renderJob.Clear((0.0, 1.0, 0.0, 0.0), 1.0)
    140             cl.isDepthCleared = False
    141         self.renderJob.SetStdRndStates(trinity.RM_FULLSCREEN)
    142 
    143     def _WaitForLoads(self):
    144         while any((not x.isPrepared for x in self._resourcesToLoad)):
    145             blue.synchro.Yield()
    146 
    147         not_good = [ not x.isGood for x in self._resourcesToLoad ]
    148         if any(not_good):
    149             for idx, state in enumerate(not_good):
    150                 if state:
    151                     x = self._resourcesToLoad[idx]
    152                     errpath = '(Effect Resource)'
    153                     if hasattr(x, 'path'):
    154                         errpath = x.path
    155                     log.LogError('TextureCompositor:: Texture load failed %s' % errpath)
    156                     raise TextureLoadingError('TextureCompositor:: Texture load failed %s' % errpath)
    157 
    158     def _AddCutoutParameters(self):
    159         lastFx = None
    160         for resource, effect, name, _ in self._texturesWithCutouts:
    161             cutout = (resource.cutoutX,
    162              resource.cutoutY,
    163              resource.cutoutWidth,
    164              resource.cutoutHeight)
    165             if lastFx != effect:
    166                 if lastFx:
    167                     lastFx.EndUpdate()
    168                 lastFx = effect
    169                 lastFx.StartUpdate()
    170             _AppendParameter(lastFx, name, cutout)
    171 
    172         if lastFx:
    173             lastFx.EndUpdate()
    174 
    175     def _AddTextureTypeParameters(self):
    176         for step in self.renderJob.steps:
    177             if isinstance(step, trinity.TriStepRenderEffect):
    178                 step.effect.StartUpdate()
    179                 for res in step.effect.resources:
    180                     mapFormat = res.resource.format
    181                     if mapFormat == trinity.PIXEL_FORMAT.R8_UNORM:
    182                         _AppendParameter(step.effect, res.name.lower() + '_L8', 1.0)
    183                     elif mapFormat == trinity.PIXEL_FORMAT.R8G8_UNORM:
    184                         _AppendParameter(step.effect, res.name.lower() + '_L8A8', 1.0)
    185                     r = self._texturesByResourceID.get(id(res.resource))
    186                     if r:
    187                         mapName = r[3]
    188                         if mapName == 'N' and mapFormat == trinity.PIXEL_FORMAT.R8G8_UNORM:
    189                             _AppendParameter(step.effect, res.name.lower() + '_blitAsNormal', 1.0)
    190 
    191                 step.effect.EndUpdate()
    192 
    193     def Finalize(self, textureToCopyTo = None, compressionSettings = None, mapType = None):
    194         self._WaitForLoads()
    195         doCompression = compressionSettings and compressionSettings.compressTextures and compressionSettings.AllowCompress(mapType)
    196         if doCompression:
    197             textureToCopyTo = None
    198         self._AddCutoutParameters()
    199         self._AddTextureTypeParameters()
    200         self.renderJob.PopDepthStencil()
    201         self.renderJob.PopRenderTarget()
    202         self.renderJob.GenerateMipMaps(self.renderTarget)
    203         if textureToCopyTo is not None:
    204             self.renderJob.CopyRenderTarget(textureToCopyTo, self.renderTarget)
    205         self.renderJob.ScheduleChained()
    206         try:
    207             self.renderJob.WaitForFinish()
    208         except Exception:
    209             self.renderJob.CancelChained()
    210             raise
    211 
    212         self._texturesWithCutouts = []
    213         self._texturesByResourceID.clear()
    214         if self.renderJob.status != trinity.RJ_DONE:
    215             return
    216         if not doCompression:
    217             if textureToCopyTo is not None:
    218                 while not textureToCopyTo.isPrepared:
    219                     blue.synchro.Yield()
    220 
    221                 if not textureToCopyTo.isGood:
    222                     log.LogError('TextureCompositor:: Texture %s failed to load properly' % textureToCopyTo.name)
    223                     raise TextureLoadingError('TextureCompositor:: Texture %s failed to load properly' % textureToCopyTo.name)
    224                 return textureToCopyTo
    225             tex = trinity.TriTextureRes()
    226             tex.CreateAndCopyFromRenderTarget(self.renderTarget)
    227             while not tex.isPrepared:
    228                 blue.synchro.Yield()
    229 
    230             if not tex.isGood:
    231                 log.LogError('TextureCompositor:: Texture %s failed to load properly' % tex.name)
    232                 raise TextureLoadingError('TextureCompositor:: Texture %s failed to load properly' % tex.name)
    233             return tex
    234         hostBitmap = trinity.Tr2HostBitmap(self.renderTarget)
    235         tex = trinity.TriTextureRes()
    236         compressionFormat = COMPRESS_DXT5n if mapType is NORMAL_MAP else COMPRESS_DXT5
    237         hostBitmap.Compress(compressionFormat, compressionSettings.qualityLevel, tex)
    238         while not tex.isPrepared:
    239             blue.synchro.Yield()
    240 
    241         if not tex.isGood:
    242             log.LogError('TextureCompositor:: Texture %s failed to load properly' % tex.name)
    243             raise TextureLoadingError('TextureCompositor:: Texture %s failed to load properly' % tex.name)
    244         return tex
    245 
    246     def _CompositeTexture(self, effect, subrect = None):
    247         vp = trinity.TriViewport()
    248         if subrect:
    249             vp.x = subrect[0]
    250             vp.y = subrect[1]
    251             vp.width = subrect[2] - subrect[0]
    252             vp.height = subrect[3] - subrect[1]
    253         else:
    254             vp.x = 0
    255             vp.y = 0
    256             vp.width = self.renderTarget.width
    257             vp.height = self.renderTarget.height
    258         self.renderJob.SetViewport(vp)
    259         self.renderJob.RenderEffect(effect)
    260 
    261     def CopyBlitTexture(self, path, subrect = None, srcRect = None, isNormalMap = False, alphaMultiplier = 1.0):
    262         effect = self._MakeEffect('Copyblit')
    263         with _UpdateEffect(effect):
    264             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV', mapType='N' if isNormalMap else '')
    265             if srcRect:
    266                 _AppendParameter(effect, 'SourceUVs', srcRect)
    267             _AppendParameter(effect, 'AlphaMultiplier', alphaMultiplier)
    268         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    269         self._CompositeTexture(effect, subrect)
    270 
    271     def MaskedNormalBlitTexture(self, path, strength, subrect = None, srcRect = None):
    272         effect = self._MakeEffect('MaskedNormalBlit')
    273         with _UpdateEffect(effect):
    274             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV')
    275             _AppendParameter(effect, 'Strength', strength)
    276             if srcRect:
    277                 _AppendParameter(effect, 'SourceUVs', srcRect)
    278         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    279         self._CompositeTexture(effect, subrect)
    280 
    281     def TwistNormalBlitTexture(self, path, strength, subrect = None, srcRect = None):
    282         effect = self._MakeEffect('TwistNormalBlit')
    283         with _UpdateEffect(effect):
    284             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV')
    285             _AppendParameter(effect, 'Strength', strength)
    286             if srcRect:
    287                 _AppendParameter(effect, 'SourceUVs', srcRect)
    288         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    289         self._CompositeTexture(effect, subrect)
    290 
    291     def SubtractAlphaFromAlpha(self, path, subrect = None, srcRect = None):
    292         effect = self._MakeEffect('BlitIntoAlpha1')
    293         with _UpdateEffect(effect):
    294             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV')
    295             if srcRect:
    296                 _AppendParameter(effect, 'SourceUVs', srcRect)
    297         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_REVSUBTRACT)
    298         self._CompositeTexture(effect, subrect)
    299 
    300     def BlitTextureIntoAlphaWithMask(self, path, mask, subrect = None, srcRect = None):
    301         effect = self._MakeEffect('BlitIntoAlpha1')
    302         with _UpdateEffect(effect):
    303             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV')
    304             if srcRect:
    305                 _AppendParameter(effect, 'SourceUVs', srcRect)
    306         effect2 = self._MakeEffect('BlitIntoAlpha2')
    307         with _UpdateEffect(effect2):
    308             self._AppendResource(effect2, 'Texture', path, 'TextureReverseUV')
    309             self._AppendResource(effect2, 'MaskMap', mask, 'MaskReverseUV')
    310             if srcRect:
    311                 _AppendParameter(effect2, 'SourceUVs', srcRect)
    312         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_REVSUBTRACT)
    313         self._CompositeTexture(effect, subrect)
    314         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    315         self._CompositeTexture(effect2, subrect)
    316 
    317     def BlitAlphaIntoAlphaWithMask(self, path, mask, subrect = None, srcRect = None):
    318         effect = self._MakeEffect('BlitIntoAlpha1')
    319         with _UpdateEffect(effect):
    320             self._AppendResource(effect, 'Texture', mask, 'TextureReverseUV')
    321             if srcRect:
    322                 _AppendParameter(effect, 'SourceUVs', srcRect)
    323         effect2 = self._MakeEffect('BlitIntoAlpha2')
    324         with _UpdateEffect(effect2):
    325             self._AppendResource(effect2, 'Texture', path, 'TextureReverseUV')
    326             self._AppendResource(effect2, 'MaskMap', mask, 'MaskReverseUV')
    327             if srcRect:
    328                 _AppendParameter(effect2, 'SourceUVs', srcRect)
    329         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_REVSUBTRACT)
    330         self._CompositeTexture(effect, subrect)
    331         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    332         self._CompositeTexture(effect2, subrect)
    333 
    334     def BlitAlphaIntoAlphaWithMaskAndZones(self, path, mask, zone, values, subrect = None, srcRect = None):
    335         effect = self._MakeEffect('BlitIntoAlpha1')
    336         with _UpdateEffect(effect):
    337             self._AppendResource(effect, 'Texture', mask, 'TextureReverseUV')
    338             if srcRect:
    339                 _AppendParameter(effect, 'SourceUVs', srcRect)
    340         effect2 = self._MakeEffect('BlitIntoAlphaWithZones')
    341         with _UpdateEffect(effect2):
    342             self._AppendResource(effect2, 'Texture', path, 'TextureReverseUV')
    343             self._AppendResource(effect2, 'MaskMap', mask, 'MaskReverseUV')
    344             self._AppendResource(effect2, 'ZoneMap', zone, 'ZoneReverseUV')
    345             if srcRect:
    346                 _AppendParameter(effect2, 'SourceUVs', srcRect)
    347             _AppendParameter(effect2, 'Color1', values)
    348         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_REVSUBTRACT)
    349         self._CompositeTexture(effect, subrect)
    350         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    351         self._CompositeTexture(effect2, subrect)
    352 
    353     def BlitTexture(self, path, maskPath, weight, subrect = None, addAlpha = False, skipAlpha = False, srcRect = None, multAlpha = False, isNormalMap = False):
    354         effect = self._MakeEffect('SimpleBlit')
    355         with _UpdateEffect(effect):
    356             self._AppendResource(effect, 'Texture', path, 'TextureReverseUV', mapType='N' if isNormalMap else '')
    357             self._AppendResource(effect, 'MaskMap', maskPath, 'MaskReverseUV')
    358             _AppendParameter(effect, 'Strength', weight)
    359             if multAlpha:
    360                 _AppendParameter(effect, 'MultAlpha', 1.0)
    361             if srcRect:
    362                 _AppendParameter(effect, 'SourceUVs', srcRect)
    363         if skipAlpha:
    364             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ZERO)
    365         else:
    366             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ONE)
    367         if addAlpha:
    368             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ONE)
    369         else:
    370             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ZERO)
    371         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    372         self._CompositeTexture(effect, subrect)
    373 
    374     def ColorizedBlitTexture(self, detail, zone, overlay, color1, color2, color3, subrect = None, addAlpha = False, skipAlpha = False, useAlphaTest = False, srcRect = None, weight = 1.0, mask = None):
    375         if useAlphaTest:
    376             effect = self._MakeEffect('ColorizedBlit_AlphaTest')
    377         else:
    378             effect = self._MakeEffect('ColorizedBlit')
    379         with _UpdateEffect(effect):
    380             self._AppendResource(effect, 'DetailMap', detail, 'DetailReverseUV')
    381             self._AppendResource(effect, 'ZoneMap', zone, 'ZoneReverseUV')
    382             self._AppendResource(effect, 'OverlayMap', overlay, 'OverlayReverseUV')
    383             if mask:
    384                 self._AppendResource(effect, 'MaskMap', mask, 'MaskReverseUV2')
    385             _AppendParameter(effect, 'Strength', weight)
    386             _AppendParameter(effect, 'Color1', color1)
    387             _AppendParameter(effect, 'Color2', color2)
    388             _AppendParameter(effect, 'Color3', color3)
    389             if srcRect:
    390                 _AppendParameter(effect, 'SourceUVs', srcRect)
    391             if mask:
    392                 _AppendParameter(effect, 'UseMask', 1.0)
    393         if skipAlpha:
    394             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ZERO)
    395         else:
    396             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ONE)
    397         if addAlpha:
    398             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ONE)
    399         else:
    400             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ZERO)
    401         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    402         self._CompositeTexture(effect, subrect)
    403 
    404     def ColorizedCopyBlitTexture(self, detail, zone, overlay, color1, color2, color3, subrect = None, srcRect = None, weight = 1.0):
    405         effect = self._MakeEffect('ColorizedCopyBlit')
    406         with _UpdateEffect(effect):
    407             self._AppendResource(effect, 'DetailMap', detail, 'DetailReverseUV')
    408             self._AppendResource(effect, 'ZoneMap', zone, 'ZoneReverseUV')
    409             self._AppendResource(effect, 'OverlayMap', overlay, 'OverlayReverseUV')
    410             _AppendParameter(effect, 'Strength', weight)
    411             _AppendParameter(effect, 'Color1', color1)
    412             _AppendParameter(effect, 'Color2', color2)
    413             _AppendParameter(effect, 'Color3', color3)
    414             if srcRect:
    415                 _AppendParameter(effect, 'SourceUVs', srcRect)
    416         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    417         self._CompositeTexture(effect, subrect)
    418 
    419     def PatternBlitTexture(self, pattern, detail, zone, overlay, patterncolor1, patterncolor2, patterncolor3, color2, color3, subrect = None, patternTransform = (0, 0, 8, 8), patternRotation = 0.0, addAlpha = False, skipAlpha = False, srcRect = None):
    420         effect = self._MakeEffect('PatternBlit')
    421         with _UpdateEffect(effect):
    422             self._AppendResource(effect, 'PatternMap', pattern, 'PatternReverseUV')
    423             self._AppendResource(effect, 'DetailMap', detail, 'DetailReverseUV')
    424             self._AppendResource(effect, 'ZoneMap', zone, 'ZoneReverseUV')
    425             self._AppendResource(effect, 'OverlayMap', overlay, 'OverlayReverseUV')
    426             _AppendParameter(effect, 'PatternColor1', patterncolor1)
    427             _AppendParameter(effect, 'PatternColor2', patterncolor2)
    428             _AppendParameter(effect, 'PatternColor3', patterncolor3)
    429             _AppendParameter(effect, 'PatternTransform', patternTransform)
    430             _AppendParameter(effect, 'PatternRotation', patternRotation)
    431             _AppendParameter(effect, 'Color2', color2)
    432             _AppendParameter(effect, 'Color3', color3)
    433             if srcRect:
    434                 _AppendParameter(effect, 'SourceUVs', srcRect)
    435         if skipAlpha:
    436             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ZERO)
    437         else:
    438             self.renderJob.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ONE)
    439         if addAlpha:
    440             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ONE)
    441         else:
    442             self.renderJob.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ZERO)
    443         self.renderJob.SetRenderState(trinity.D3DRS_BLENDOPALPHA, trinity.TRIBLENDOP_ADD)
    444         self._CompositeTexture(effect, subrect)