Add color space option for texture export
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"] },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"] },
|
||||
{ "name": "occ", "channels": ["occ", "occ", "occ", "1.0"] },
|
||||
{ "name": "rough", "channels": ["rough", "rough", "rough", "1.0"] },
|
||||
{ "name": "metal", "channels": ["metal", "metal", "metal", "1.0"] }
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "occ", "channels": ["occ", "occ", "occ", "1.0"], "color_space": "linear" },
|
||||
{ "name": "rough", "channels": ["rough", "rough", "rough", "1.0"], "color_space": "linear" },
|
||||
{ "name": "metal", "channels": ["metal", "metal", "metal", "1.0"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "", "channels": ["base_r", "base_g", "base_b", "1.0"] },
|
||||
{ "name": "normal", "channels": ["nor_r", "nor_g", "nor_b", "1.0"] },
|
||||
{ "name": "mer", "channels": ["metal", "emis", "rough", "1.0"] }
|
||||
{ "name": "", "channels": ["base_r", "base_g", "base_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "normal", "channels": ["nor_r", "nor_g", "nor_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "mer", "channels": ["metal", "emis", "rough", "1.0"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"] },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "0.0", "1.0"] },
|
||||
{ "name": "sh", "channels": ["metal", "rough", "0.0", "1.0"] },
|
||||
{ "name": "occ", "channels": ["occ", "0.0", "0.0", "1.0"] }
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "0.0", "1.0"], "color_space": "linear" },
|
||||
{ "name": "sh", "channels": ["metal", "rough", "0.0", "1.0"], "color_space": "linear" },
|
||||
{ "name": "occ", "channels": ["occ", "0.0", "0.0", "1.0"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"] },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"] },
|
||||
{ "name": "mos", "channels": ["metal", "occ", "1.0", "smooth"] },
|
||||
{ "name": "height", "channels": ["0.0", "height", "0.0", "1.0"] }
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "mos", "channels": ["metal", "occ", "1.0", "smooth"], "color_space": "linear" },
|
||||
{ "name": "height", "channels": ["0.0", "height", "0.0", "1.0"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"] },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"] },
|
||||
{ "name": "orm", "channels": ["occ", "rough", "metal", "1.0"] }
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "nor_b", "1.0"], "color_space": "linear" },
|
||||
{ "name": "orm", "channels": ["occ", "rough", "metal", "1.0"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"textures": [
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "rough"] },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "smooth", "metal"] }
|
||||
{ "name": "base", "channels": ["base_r", "base_g", "base_b", "rough"], "color_space": "linear" },
|
||||
{ "name": "nor", "channels": ["nor_r", "nor_g", "smooth", "metal"], "color_space": "linear" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import arm.Enums;
|
||||
|
||||
class ExportTexture {
|
||||
|
||||
static inline var gamma = 1.0 / 2.2;
|
||||
|
||||
public static function run(path: String, bakeMaterial = false) {
|
||||
#if arm_debug
|
||||
var timer = iron.system.Time.realTime();
|
||||
@@ -267,48 +269,48 @@ class ExportTexture {
|
||||
var c = t.channels;
|
||||
var tex_name = t.name != "" ? "_" + t.name : "";
|
||||
var singleChannel = c[0] == c[1] && c[1] == c[2] && c[3] == "1.0";
|
||||
if (c[0] == "base_r" && c[1] == "base_g" && c[2] == "base_b" && c[3] == "1.0") {
|
||||
if (c[0] == "base_r" && c[1] == "base_g" && c[2] == "base_b" && c[3] == "1.0" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint, 1);
|
||||
}
|
||||
else if (c[0] == "nor_r" && c[1] == "nor_g" && c[2] == "nor_b" && c[3] == "1.0") {
|
||||
else if (c[0] == "nor_r" && c[1] == "nor_g" && c[2] == "nor_b" && c[3] == "1.0" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_nor, 1);
|
||||
}
|
||||
else if (c[0] == "occ" && c[1] == "rough" && c[2] == "metal" && c[3] == "1.0") {
|
||||
else if (c[0] == "occ" && c[1] == "rough" && c[2] == "metal" && c[3] == "1.0" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_pack, 1);
|
||||
}
|
||||
else if (singleChannel && c[0] == "occ") {
|
||||
else if (singleChannel && c[0] == "occ" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_pack, 2, 0);
|
||||
}
|
||||
else if (singleChannel && c[0] == "rough") {
|
||||
else if (singleChannel && c[0] == "rough" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_pack, 2, 1);
|
||||
}
|
||||
else if (singleChannel && c[0] == "metal") {
|
||||
else if (singleChannel && c[0] == "metal" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_pack, 2, 2);
|
||||
}
|
||||
else if (singleChannel && c[0] == "height") {
|
||||
else if (singleChannel && c[0] == "height" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint_pack, 2, 3);
|
||||
}
|
||||
else if (singleChannel && c[0] == "opac") {
|
||||
else if (singleChannel && c[0] == "opac" && t.color_space == "linear") {
|
||||
writeTexture(path + Path.sep + f + tex_name + ext, pixpaint, 2, 3);
|
||||
}
|
||||
else {
|
||||
if (pix == null) pix = Bytes.alloc(textureSizeX * textureSizeY * 4 * Std.int(bits / 8));
|
||||
for (i in 0...4) {
|
||||
var c = t.channels[i];
|
||||
if (c == "base_r") copyChannel(pixpaint, 0, pix, i); // copyChannelGamma
|
||||
else if (c == "base_g") copyChannel(pixpaint, 1, pix, i); // copyChannelGamma
|
||||
else if (c == "base_b") copyChannel(pixpaint, 2, pix, i); // copyChannelGamma
|
||||
else if (c == "height") copyChannel(pixpaint_pack, 3, pix, i);
|
||||
else if (c == "metal") copyChannel(pixpaint_pack, 2, pix, i);
|
||||
else if (c == "nor_r") copyChannel(pixpaint_nor, 0, pix, i);
|
||||
else if (c == "nor_g") copyChannel(pixpaint_nor, 1, pix, i);
|
||||
else if (c == "nor_b") copyChannel(pixpaint_nor, 2, pix, i);
|
||||
else if (c == "occ") copyChannel(pixpaint_pack, 0, pix, i);
|
||||
else if (c == "opac") copyChannel(pixpaint, 3, pix, i);
|
||||
else if (c == "rough") copyChannel(pixpaint_pack, 1, pix, i);
|
||||
else if (c == "smooth") copyChannelInv(pixpaint_pack, 1, pix, i);
|
||||
else if (c == "emis") extractChannel(pixpaint_nor, 3, pix, i, 255);
|
||||
else if (c == "subs") extractChannel(pixpaint_nor, 3, pix, i, 254);
|
||||
if (c == "base_r") copyChannel(pixpaint, 0, pix, i, t.color_space == "linear");
|
||||
else if (c == "base_g") copyChannel(pixpaint, 1, pix, i, t.color_space == "linear");
|
||||
else if (c == "base_b") copyChannel(pixpaint, 2, pix, i, t.color_space == "linear");
|
||||
else if (c == "height") copyChannel(pixpaint_pack, 3, pix, i, t.color_space == "linear");
|
||||
else if (c == "metal") copyChannel(pixpaint_pack, 2, pix, i, t.color_space == "linear");
|
||||
else if (c == "nor_r") copyChannel(pixpaint_nor, 0, pix, i, t.color_space == "linear");
|
||||
else if (c == "nor_g") copyChannel(pixpaint_nor, 1, pix, i, t.color_space == "linear");
|
||||
else if (c == "nor_b") copyChannel(pixpaint_nor, 2, pix, i, t.color_space == "linear");
|
||||
else if (c == "occ") copyChannel(pixpaint_pack, 0, pix, i, t.color_space == "linear");
|
||||
else if (c == "opac") copyChannel(pixpaint, 3, pix, i, t.color_space == "linear");
|
||||
else if (c == "rough") copyChannel(pixpaint_pack, 1, pix, i, t.color_space == "linear");
|
||||
else if (c == "smooth") copyChannelInv(pixpaint_pack, 1, pix, i, t.color_space == "linear");
|
||||
else if (c == "emis") extractChannel(pixpaint_nor, 3, pix, i, 255, t.color_space == "linear");
|
||||
else if (c == "subs") extractChannel(pixpaint_nor, 3, pix, i, 254, t.color_space == "linear");
|
||||
else if (c == "0.0") setChannel(0, pix, i);
|
||||
else if (c == "1.0") setChannel(255, pix, i);
|
||||
}
|
||||
@@ -369,34 +371,37 @@ class ExportTexture {
|
||||
Krom.fileSaveBytes(file, out.getBytes().getData(), out.getBytes().length);
|
||||
}
|
||||
|
||||
static function copyChannel(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int) {
|
||||
static function copyChannel(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int, linear = true) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, from.get(i * 4 + fromChannel));
|
||||
}
|
||||
if (!linear) toSrgb(to, toChannel);
|
||||
}
|
||||
|
||||
static inline var gamma = 1.0 / 2.2;
|
||||
static function copyChannelGamma(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, Std.int(Math.pow(from.get(i * 4 + fromChannel) / 255, gamma) * 255));
|
||||
}
|
||||
}
|
||||
|
||||
static function copyChannelInv(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int) {
|
||||
static function copyChannelInv(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int, linear = true) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, 255 - from.get(i * 4 + fromChannel));
|
||||
}
|
||||
if (!linear) toSrgb(to, toChannel);
|
||||
}
|
||||
|
||||
static function setChannel(value: Int, to: Bytes, toChannel: Int) {
|
||||
static function extractChannel(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int, mask: Int, linear = true) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, from.get(i * 4 + fromChannel) == mask ? 255 : 0);
|
||||
}
|
||||
if (!linear) toSrgb(to, toChannel);
|
||||
}
|
||||
|
||||
static function setChannel(value: Int, to: Bytes, toChannel: Int, linear = true) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, value);
|
||||
}
|
||||
if (!linear) toSrgb(to, toChannel);
|
||||
}
|
||||
|
||||
static function extractChannel(from: Bytes, fromChannel: Int, to: Bytes, toChannel: Int, mask: Int) {
|
||||
static function toSrgb(to: Bytes, toChannel: Int) {
|
||||
for (i in 0...Std.int(to.length / 4)) {
|
||||
to.set(i * 4 + toChannel, from.get(i * 4 + fromChannel) == mask ? 255 : 0);
|
||||
to.set(i * 4 + toChannel, Std.int(Math.pow(to.get(i * 4 + toChannel) / 255, gamma) * 255));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -408,4 +413,5 @@ typedef TExportPreset = {
|
||||
typedef TExportPresetTexture = {
|
||||
public var name: String;
|
||||
public var channels: Array<String>;
|
||||
public var color_space: String;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ class BoxExport {
|
||||
public static var files: Array<String> = null;
|
||||
public static var preset: TExportPreset = null;
|
||||
static var channels = ["base_r", "base_g", "base_b", "height", "metal", "nor_r", "nor_g", "nor_b", "occ", "opac", "rough", "smooth", "emis", "subs", "0.0", "1.0"];
|
||||
static var colorSpaces = ["linear", "srgb"];
|
||||
|
||||
public static function showTextures() {
|
||||
UIBox.showCustom(function(ui: Zui) {
|
||||
@@ -32,7 +33,7 @@ class BoxExport {
|
||||
tabPresets(ui);
|
||||
tabAtlases(ui);
|
||||
|
||||
}, 500, 310);
|
||||
}, 540, 310);
|
||||
}
|
||||
|
||||
public static function showBakeMaterial() {
|
||||
@@ -47,7 +48,7 @@ class BoxExport {
|
||||
tabExportTextures(ui, tr("Bake to Textures"), true);
|
||||
tabPresets(ui);
|
||||
|
||||
}, 500, 310);
|
||||
}, 540, 310);
|
||||
}
|
||||
|
||||
static function tabExportTextures(ui: Zui, title: String, bakeMaterial = false) {
|
||||
@@ -158,16 +159,17 @@ class BoxExport {
|
||||
|
||||
// Texture list
|
||||
ui.separator(10, false);
|
||||
ui.row([0.2, 0.2, 0.2, 0.2, 0.2]);
|
||||
ui.row([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
|
||||
ui.text(tr("Texture"));
|
||||
ui.text(tr("R"));
|
||||
ui.text(tr("G"));
|
||||
ui.text(tr("B"));
|
||||
ui.text(tr("A"));
|
||||
ui.text(tr("Color Space"));
|
||||
ui.changed = false;
|
||||
for (i in 0...preset.textures.length) {
|
||||
var t = preset.textures[i];
|
||||
ui.row([0.2, 0.2, 0.2, 0.2, 0.2]);
|
||||
ui.row([1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6, 1 / 6]);
|
||||
var htex = hpreset.nest(i);
|
||||
htex.text = t.name;
|
||||
t.name = ui.textInput(htex);
|
||||
@@ -199,6 +201,11 @@ class BoxExport {
|
||||
if (hb.changed) t.channels[2] = channels[hb.position];
|
||||
ui.combo(ha, channels, tr("A"));
|
||||
if (ha.changed) t.channels[3] = channels[ha.position];
|
||||
|
||||
var hspace = htex.nest(4);
|
||||
hspace.position = colorSpaces.indexOf(t.color_space);
|
||||
ui.combo(hspace, colorSpaces, tr("Color Space"));
|
||||
if (hspace.changed) t.color_space = colorSpaces[hspace.position];
|
||||
}
|
||||
|
||||
if (ui.changed) {
|
||||
@@ -207,7 +214,7 @@ class BoxExport {
|
||||
|
||||
ui.row([1 / 8]);
|
||||
if (ui.button(tr("Add"))) {
|
||||
preset.textures.push({name: "base", channels: ["base_r", "base_g", "base_b", "1.0"]});
|
||||
preset.textures.push({name: "base", channels: ["base_r", "base_g", "base_b", "1.0"], color_space: "linear"});
|
||||
@:privateAccess hpreset.children = null;
|
||||
savePreset();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user