Just a heads up: ZLZ is still being improved from time to time. The current version is now able to setup most Korman 0.12 modifers (ladders, audio, swimming, grass...), and has tons of bugfixes. I'll keep updating it whenever new versions of Korman are released (although I'll probably lag behind a bit
).
The download link now always points to the latest version on the Git repo (actually it has been the case for a while now). I just updated the Wiki entry to give new instructions on how to install it.
A few of the latest improvements from roughly ~1 month ago:
- Show Spoiler
- multi animations, loop markers, sound volume anim. Still far from perfect, but should make reexporting easier.
- grass shader
- decals (print & receive)
- projected lights
- material pass index, render pass, face sorting
- import existing lightmaps as a Korman pre-baked LM
- improvements to cubemaps/dynamicenvmap/dynamiccammap
- improvements to how textures are imported in general, support for HD textures
Some details about texture formats and HD textures:
- Show Spoiler
- When an Age is exported, source textures are compressed using a destructive format: DDS (DirectDraw Surface). This means they are optimized for in-game use, but get some additional compression artifacts which cannot be removed. They might also be resized to a smaller size than the source image.
- Because of this, each time you import then export an Age/texture, the quality of image textures decreases.
- From now on, ZLZ allows you to specify the "MOUL source textures" folder before import. What is this ? It's the location of the MOUL source assets. When encountering a texture in the PRPs, ZLZ will instead use the original texture that Cyan released. This means that textures will have less compression artifacts when re-exported, on top of being higher-resolution.
- If this folder is not specified, ZLZ will instead use the texture found in the PRP "as is", which means it's in DDS format and already lower quality. When re-exporting, Korman will usually re-compress the image again, further worsening the compression artifacts. Some 3D game engines can however use DDS images without recompressing them, although it's getting less and less common.
- If you really dislike the DDS format, you can instead ask ZLZ to extract textures as PNG. PNG is more compatible and lossless, but will still contain the DDS artifacts and takes more disk space.
- DDS files can be viewed with the great XnView. Gimp also has plugins to handle DDS files, if you want to edit an image. When editing a DDS file, do not save it as DDS again - you would only add to the compression. Use a lossless format like PNG instead.
If you already have an Age imported with ZLZ, and want to use Cyan's higher-res source textures instead, you might try out this script... (this might be of interest to you, Doobes)
- Show Spoiler
To use the script:
- (As usual, make a backup of your file, just in case.)
- Unpack all textures from your file beforehand, again, just in case.
- Copy and paste the following script in a Blender text file.
- In the code, change the "sourcePath" variable to the "tga" folder from the "moul-assets" repository on your computer.
- Toggle Blender's console so you can check the progress, then run the script. It can take a minute or two.
- Make sure there are no errors printed in the console.
- As a bonus, this correctly setups texture detail blending, which will now be visible in Uru (the downside is it won't be visible in the editor anymore, but at least now it exports correctly).
- Code: Select all
import os, bpy
from pathlib import Path
# CHANGE this to the path to the "sources\textures\tga" in the "moul-assets" repository !
sourcePath = r"C:\somewhere\moul-assets\sources\textures"
# find the textures using each image
imgTextures = {} # Blender image: [textures using this image]
for tex in bpy.data.textures:
if tex.type == "IMAGE":
l = imgTextures.get(tex.image)
if l is None:
l = []
imgTextures[tex.image] = l
l.append(tex)
print("----------------------------------")
for img in bpy.data.images:
file = os.path.splitext(os.path.basename(bpy.path.abspath(img.filepath)))[0]
detailsStart = file.find('@')
if detailsStart != -1:
print("Has detail blending: " + file)
# paramsString = file[detailsStart + 1:].split('&');
# uh oh, actually, I forgot ZLZ completely screws up texture names...
# Fortunately everything following the @ is fixed-length, so we can find a workaround
details = file[detailsStart + 1:]
paramsString = [
details[:2], # mixMethod
details[3:7].replace('_', '.'), # dropoffStart
details[8:12].replace('_', '.'), # dropoffStop
details[13:17].replace('_', '.'), # maxDetail
details[18:22].replace('_', '.'), # minDetail
]
if len(paramsString) != 5:
print("WARNING: texture '{0}' blending: invalid number of arguments.".format(file))
continue
# eg name: dsntRockWallDark*0#0@al&0.00&0.10&0.60&0.00
mixMethod = paramsString[0]
dropoffStart = float(paramsString[1])
dropoffStop = float(paramsString[2])
maxDetail = float(paramsString[3])
minDetail = float(paramsString[4])
textures = imgTextures.get(img)
if textures is not None:
for tex in textures:
tex.plasma_layer.is_detail_map = True
tex.plasma_layer.detail_fade_start = dropoffStart * 100
tex.plasma_layer.detail_fade_stop = dropoffStop * 100
tex.plasma_layer.detail_opacity_start = maxDetail * 100
tex.plasma_layer.detail_opacity_stop = minDetail * 100
file = file[:detailsStart]
# screw the _0_0 suffix
i = file.rfind('_')
if i != -1 and file[i+1:].isdigit():
j = file.rfind('_', 0, i)
if j != -1 and file[j+1:i].isdigit():
file = file[:j]
found = False
fileTga = file + ".tga"
path = Path(sourcePath)
for matching in path.rglob(fileTga):
found = True
img.filepath = str(matching)
print("Replaced: " + file)
break
if not found:
print("Not found: " + file)
Hmm, that should be all. ZLZ still isn't perfect, so as usual don't hesitate to report bugs. I'm glad to see people use it every now and then
Have fun !