Files
LNXSDK/leenkx/blender/lnx/material/make_attrib.py

213 lines
4.8 KiB
Python
Raw Normal View History

2025-01-22 16:18:30 +01:00
from typing import Optional
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.cycles as cycles
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.mat_state as mat_state
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.make_skin as make_skin
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.make_particle as make_particle
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.make_inst as make_inst
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.make_tess as make_tess
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.material.make_morph_target as make_morph_target
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
from lnx.material.shader import Shader, ShaderContext
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
import lnx.utils
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if lnx.is_reload(__name__):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
cycles = lnx.reload_module(cycles)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
mat_state = lnx.reload_module(mat_state)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_skin = lnx.reload_module(make_skin)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_particle = lnx.reload_module(make_particle)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_inst = lnx.reload_module(make_inst)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_tess = lnx.reload_module(make_tess)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_morph_target = lnx.reload_module(make_morph_target)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
lnx.material.shader = lnx.reload_module(lnx.material.shader)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
from lnx.material.shader import Shader, ShaderContext
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
lnx.utils = lnx.reload_module(lnx.utils)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
else:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
lnx.enable_reload(__name__)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
def write_vertpos(vert):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
billboard = mat_state.material.lnx_billboard
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
particle = mat_state.material.lnx_particle_flag
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
# Particles
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if particle:
2026-05-12 23:54:06 -07:00
if lnx.utils.get_rp().lnx_particles == 'GPU':
2025-01-22 16:18:30 +01:00
make_particle.write(vert, particle_info=cycles.particle_info)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
# Billboards
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if billboard == 'spherical':
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 WV', '_worldViewMatrix')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 P', '_projectionMatrix')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write('gl_Position = P * (WV * vec4(0.0, 0.0, spos.z, 1.0) + vec4(spos.x, spos.y, 0.0, 0.0));')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
else:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write('gl_Position = WVP * spos;')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
else:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
# Billboards
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if billboard == 'spherical':
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixSphere')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
elif billboard == 'cylindrical':
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrixCylinder')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
else: # off
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('mat4 WVP', '_worldViewProjectionMatrix')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write('gl_Position = WVP * spos;')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
def write_norpos(con_mesh: ShaderContext, vert: Shader, declare=False, write_nor=True):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
is_bone = con_mesh.is_elem('bone')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
is_morph = con_mesh.is_elem('morph')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if is_morph:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_morph_target.morph_pos(vert)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if is_bone:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_skin.skin_pos(vert)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if write_nor:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
prep = 'vec3 ' if declare else ''
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if is_morph:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_morph_target.morph_nor(vert, is_bone, prep)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if is_bone:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_skin.skin_nor(vert, is_morph, prep)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if not is_morph and not is_bone:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write_attrib(prep + 'wnormal = normalize(N * vec3(nor.xy, pos.w));')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if con_mesh.is_elem('ipos'):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_inst.inst_pos(con_mesh, vert)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
def write_tex_coords(con_mesh: ShaderContext, vert: Shader, frag: Shader, tese: Optional[Shader]):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
rpdat = lnx.utils.get_rp()
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if con_mesh.is_elem('tex'):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_out('vec2 texCoord')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if mat_state.material.lnx_tilesheet_flag:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if mat_state.material.lnx_particle_flag and rpdat.lnx_particles == 'On':
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_particle.write_tilesheet(vert)
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
else:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('vec2 tilesheetOffset', '_tilesheetOffset')
2026-05-12 23:54:06 -07:00
vert.add_uniform('vec2 tilesheetFlip', '_tilesheetFlip')
vert.add_uniform('vec2 tilesheetTiles', '_tilesheetTiles')
vert.write_attrib('vec2 tileSize = vec2(1.0 / tilesheetTiles.x, 1.0 / tilesheetTiles.y);')
vert.write_attrib('vec2 tileUV = tex * texUnpack;')
vert.write_attrib('tileUV.x = mix(tileUV.x, tileSize.x - tileUV.x, tilesheetFlip.x);')
vert.write_attrib('tileUV.y = mix(tileUV.y, tileSize.y - tileUV.y, tilesheetFlip.y);')
vert.write_attrib('texCoord = tileUV + tilesheetOffset;')
2025-01-22 16:18:30 +01:00
else:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write_attrib('texCoord = tex * texUnpack;')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if tese is not None:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
tese.write_pre = True
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_tess.interpolate(tese, 'texCoord', 2, declare_out=frag.contains('texCoord'))
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
tese.write_pre = False
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if con_mesh.is_elem('tex1'):
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_out('vec2 texCoord1')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.add_uniform('float texUnpack', link='_texUnpack')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
vert.write_attrib('texCoord1 = tex1 * texUnpack;')
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
if tese is not None:
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
tese.write_pre = True
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
make_tess.interpolate(tese, 'texCoord1', 2, declare_out=frag.contains('texCoord1'))
2026-05-12 23:54:06 -07:00
2025-01-22 16:18:30 +01:00
tese.write_pre = False
2026-05-12 23:54:06 -07:00