Move runtime material parser
This commit is contained in:
parent
5410566a29
commit
ec179489af
File diff suppressed because it is too large
Load diff
|
@ -1,64 +0,0 @@
|
|||
package armory.system;
|
||||
|
||||
typedef TNodeCanvas = {
|
||||
var name: String;
|
||||
var nodes: Array<TNode>;
|
||||
var links: Array<TNodeLink>;
|
||||
}
|
||||
|
||||
typedef TNode = {
|
||||
var id: Int;
|
||||
var name: String;
|
||||
var type: String;
|
||||
var x: Float;
|
||||
var y: Float;
|
||||
var inputs: Array<TNodeSocket>;
|
||||
var outputs: Array<TNodeSocket>;
|
||||
var buttons: Array<TNodeButton>;
|
||||
var color: Int;
|
||||
}
|
||||
|
||||
typedef TNodeSocket = {
|
||||
var id: Int;
|
||||
var node_id: Int;
|
||||
var name: String;
|
||||
var type: String;
|
||||
var color: Int;
|
||||
var default_value: Dynamic;
|
||||
@:optional var min: Null<Float>;
|
||||
@:optional var max: Null<Float>;
|
||||
}
|
||||
|
||||
typedef TNodeLink = {
|
||||
var id: Int;
|
||||
var from_id: Int;
|
||||
var from_socket: Int;
|
||||
var to_id: Int;
|
||||
var to_socket: Int;
|
||||
}
|
||||
|
||||
typedef TNodeButton = {
|
||||
var name: String;
|
||||
var type: String;
|
||||
@:optional var output: Null<Int>;
|
||||
@:optional var default_value: Dynamic;
|
||||
@:optional var data: Dynamic;
|
||||
@:optional var min: Null<Float>;
|
||||
@:optional var max: Null<Float>;
|
||||
}
|
||||
|
||||
typedef TMaterial = {
|
||||
var name:String;
|
||||
var canvas:TNodeCanvas;
|
||||
}
|
||||
|
||||
typedef TShaderOut = {
|
||||
var out_basecol:String;
|
||||
var out_roughness:String;
|
||||
var out_metallic:String;
|
||||
var out_occlusion:String;
|
||||
var out_opacity:String;
|
||||
var out_height:String;
|
||||
var out_emission:String;
|
||||
var out_subsurface:String;
|
||||
}
|
|
@ -1,277 +0,0 @@
|
|||
package armory.system;
|
||||
|
||||
class CyclesFunctions {
|
||||
|
||||
public static var str_tex_checker = "
|
||||
vec3 tex_checker(const vec3 co, const vec3 col1, const vec3 col2, const float scale) {
|
||||
// Prevent precision issues on unit coordinates
|
||||
vec3 p = (co + 0.000001 * 0.999999) * scale;
|
||||
float xi = abs(floor(p.x));
|
||||
float yi = abs(floor(p.y));
|
||||
float zi = abs(floor(p.z));
|
||||
bool check = ((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
|
||||
return check ? col1 : col2;
|
||||
}
|
||||
float tex_checker_f(const vec3 co, const float scale) {
|
||||
vec3 p = (co + 0.000001 * 0.999999) * scale;
|
||||
float xi = abs(floor(p.x));
|
||||
float yi = abs(floor(p.y));
|
||||
float zi = abs(floor(p.z));
|
||||
return float((mod(xi, 2.0) == mod(yi, 2.0)) == bool(mod(zi, 2.0)));
|
||||
}
|
||||
";
|
||||
|
||||
// Created by inigo quilez - iq/2013
|
||||
// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
||||
public static var str_tex_voronoi = "
|
||||
vec4 tex_voronoi(const vec3 x) {
|
||||
vec3 p = floor(x);
|
||||
vec3 f = fract(x);
|
||||
float id = 0.0;
|
||||
float res = 100.0;
|
||||
for (int k = -1; k <= 1; k++)
|
||||
for (int j = -1; j <= 1; j++)
|
||||
for (int i = -1; i <= 1; i++) {
|
||||
vec3 b = vec3(float(i), float(j), float(k));
|
||||
vec3 pb = p + b;
|
||||
vec3 r = vec3(b) - f + texture(snoise256, (pb.xy + vec2(3.0, 1.0) * pb.z + 0.5) / 256.0).xyz;
|
||||
float d = dot(r, r);
|
||||
if (d < res) {
|
||||
id = dot(p + b, vec3(1.0, 57.0, 113.0));
|
||||
res = d;
|
||||
}
|
||||
}
|
||||
vec3 col = 0.5 + 0.5 * cos(id * 0.35 + vec3(0.0, 1.0, 2.0));
|
||||
return vec4(col, sqrt(res));
|
||||
}
|
||||
";
|
||||
|
||||
// By Morgan McGuire @morgan3d, http://graphicscodex.com Reuse permitted under the BSD license.
|
||||
// https://www.shadertoy.com/view/4dS3Wd
|
||||
public static var str_tex_noise = "
|
||||
float hash(float n) { return fract(sin(n) * 1e4); }
|
||||
float tex_noise_f(vec3 x) {
|
||||
const vec3 step = vec3(110, 241, 171);
|
||||
vec3 i = floor(x);
|
||||
vec3 f = fract(x);
|
||||
float n = dot(i, step);
|
||||
vec3 u = f * f * (3.0 - 2.0 * f);
|
||||
return mix(mix(mix(hash(n + dot(step, vec3(0, 0, 0))), hash(n + dot(step, vec3(1, 0, 0))), u.x),
|
||||
mix(hash(n + dot(step, vec3(0, 1, 0))), hash(n + dot(step, vec3(1, 1, 0))), u.x), u.y),
|
||||
mix(mix(hash(n + dot(step, vec3(0, 0, 1))), hash(n + dot(step, vec3(1, 0, 1))), u.x),
|
||||
mix(hash(n + dot(step, vec3(0, 1, 1))), hash(n + dot(step, vec3(1, 1, 1))), u.x), u.y), u.z);
|
||||
}
|
||||
float tex_noise(vec3 p) {
|
||||
p *= 1.25;
|
||||
float f = 0.5 * tex_noise_f(p); p *= 2.01;
|
||||
f += 0.25 * tex_noise_f(p); p *= 2.02;
|
||||
f += 0.125 * tex_noise_f(p); p *= 2.03;
|
||||
f += 0.0625 * tex_noise_f(p);
|
||||
return 1.0 - f;
|
||||
}
|
||||
";
|
||||
|
||||
// Based on noise created by Nikita Miropolskiy, nikat/2013
|
||||
// Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
|
||||
public static var str_tex_musgrave = "
|
||||
vec3 random3(const vec3 c) {
|
||||
float j = 4096.0 * sin(dot(c, vec3(17.0, 59.4, 15.0)));
|
||||
vec3 r;
|
||||
r.z = fract(512.0 * j);
|
||||
j *= 0.125;
|
||||
r.x = fract(512.0 * j);
|
||||
j *= 0.125;
|
||||
r.y = fract(512.0 * j);
|
||||
return r - 0.5;
|
||||
}
|
||||
float tex_musgrave_f(const vec3 p) {
|
||||
const float F3 = 0.3333333;
|
||||
const float G3 = 0.1666667;
|
||||
vec3 s = floor(p + dot(p, vec3(F3, F3, F3)));
|
||||
vec3 x = p - s + dot(s, vec3(G3, G3, G3));
|
||||
vec3 e = step(vec3(0.0, 0.0, 0.0), x - x.yzx);
|
||||
vec3 i1 = e*(1.0 - e.zxy);
|
||||
vec3 i2 = 1.0 - e.zxy*(1.0 - e);
|
||||
vec3 x1 = x - i1 + G3;
|
||||
vec3 x2 = x - i2 + 2.0*G3;
|
||||
vec3 x3 = x - 1.0 + 3.0*G3;
|
||||
vec4 w, d;
|
||||
w.x = dot(x, x);
|
||||
w.y = dot(x1, x1);
|
||||
w.z = dot(x2, x2);
|
||||
w.w = dot(x3, x3);
|
||||
w = max(0.6 - w, 0.0);
|
||||
d.x = dot(random3(s), x);
|
||||
d.y = dot(random3(s + i1), x1);
|
||||
d.z = dot(random3(s + i2), x2);
|
||||
d.w = dot(random3(s + 1.0), x3);
|
||||
w *= w;
|
||||
w *= w;
|
||||
d *= w;
|
||||
return clamp(dot(d, vec4(52.0, 52.0, 52.0, 52.0)), 0.0, 1.0);
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_hue_sat = "
|
||||
vec3 hsv_to_rgb(const vec3 c) {
|
||||
const vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
|
||||
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
|
||||
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
|
||||
}
|
||||
vec3 rgb_to_hsv(const vec3 c) {
|
||||
const vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
|
||||
vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
|
||||
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
|
||||
|
||||
float d = q.x - min(q.w, q.y);
|
||||
float e = 1.0e-10;
|
||||
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
|
||||
}
|
||||
vec3 hue_sat(const vec3 col, const vec4 shift) {
|
||||
vec3 hsv = rgb_to_hsv(col);
|
||||
hsv.x += shift.x;
|
||||
hsv.y *= shift.y;
|
||||
hsv.z *= shift.z;
|
||||
return mix(hsv_to_rgb(hsv), col, shift.w);
|
||||
}
|
||||
";
|
||||
|
||||
// https://twitter.com/Donzanoid/status/903424376707657730
|
||||
public static var str_wavelength_to_rgb = "
|
||||
vec3 wavelength_to_rgb(const float t) {
|
||||
vec3 r = t * 2.1 - vec3(1.8, 1.14, 0.3);
|
||||
return 1.0 - r * r;
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_tex_magic = "
|
||||
vec3 tex_magic(const vec3 p) {
|
||||
float a = 1.0 - (sin(p.x) + sin(p.y));
|
||||
float b = 1.0 - sin(p.x - p.y);
|
||||
float c = 1.0 - sin(p.x + p.y);
|
||||
return vec3(a, b, c);
|
||||
}
|
||||
float tex_magic_f(const vec3 p) {
|
||||
vec3 c = tex_magic(p);
|
||||
return (c.x + c.y + c.z) / 3.0;
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_tex_brick = "
|
||||
vec3 tex_brick(vec3 p, const vec3 c1, const vec3 c2, const vec3 c3) {
|
||||
p /= vec3(0.9, 0.49, 0.49) / 2;
|
||||
if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
|
||||
p = fract(p);
|
||||
vec3 b = step(p, vec3(0.95, 0.9, 0.9));
|
||||
return mix(c3, c1, b.x * b.y * b.z);
|
||||
}
|
||||
float tex_brick_f(vec3 p) {
|
||||
p /= vec3(0.9, 0.49, 0.49) / 2;
|
||||
if (fract(p.y * 0.5) > 0.5) p.x += 0.5;
|
||||
p = fract(p);
|
||||
vec3 b = step(p, vec3(0.95, 0.9, 0.9));
|
||||
return mix(1.0, 0.0, b.x * b.y * b.z);
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_tex_wave = "
|
||||
float tex_wave_f(const vec3 p) {
|
||||
return 1.0 - sin((p.x + p.y) * 10.0);
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_brightcontrast = "
|
||||
vec3 brightcontrast(const vec3 col, const float bright, const float contr) {
|
||||
float a = 1.0 + contr;
|
||||
float b = bright - contr * 0.5;
|
||||
return max(a * col + b, 0.0);
|
||||
}
|
||||
";
|
||||
|
||||
//
|
||||
|
||||
public static var str_traceAO = "
|
||||
float traceConeAO(sampler3D voxels, const vec3 origin, vec3 dir, const float aperture, const float maxDist, const float offset) {
|
||||
const ivec3 voxelgiResolution = ivec3(256, 256, 256);
|
||||
const float voxelgiStep = 1.0;
|
||||
const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
|
||||
dir = normalize(dir);
|
||||
float sampleCol = 0.0;
|
||||
float dist = offset;
|
||||
float diam = dist * aperture;
|
||||
vec3 samplePos;
|
||||
while (sampleCol < 1.0 && dist < maxDist) {
|
||||
samplePos = dir * dist + origin;
|
||||
float mip = max(log2(diam * voxelgiResolution.x), 0);
|
||||
float mipSample = textureLod(voxels, samplePos * 0.5 + vec3(0.5, 0.5, 0.5), mip).r;
|
||||
sampleCol += (1 - sampleCol) * mipSample;
|
||||
dist += max(diam / 2, VOXEL_SIZE);
|
||||
diam = dist * aperture;
|
||||
}
|
||||
return sampleCol;
|
||||
}
|
||||
vec3 tangent(const vec3 n) {
|
||||
vec3 t1 = cross(n, vec3(0, 0, 1));
|
||||
vec3 t2 = cross(n, vec3(0, 1, 0));
|
||||
if (length(t1) > length(t2)) return normalize(t1);
|
||||
else return normalize(t2);
|
||||
}
|
||||
float traceAO(const vec3 origin, const vec3 normal, const float vrange, const float voffset) {
|
||||
const float angleMix = 0.5f;
|
||||
const float aperture = 0.55785173935;
|
||||
vec3 o1 = normalize(tangent(normal));
|
||||
vec3 o2 = normalize(cross(o1, normal));
|
||||
vec3 c1 = 0.5f * (o1 + o2);
|
||||
vec3 c2 = 0.5f * (o1 - o2);
|
||||
float MAX_DISTANCE = 1.73205080757 * 2.0 * vrange;
|
||||
const ivec3 voxelgiResolution = ivec3(256, 256, 256);
|
||||
const float voxelgiStep = 1.0;
|
||||
const float VOXEL_SIZE = (2.0 / voxelgiResolution.x) * voxelgiStep;
|
||||
float offset = 1.5 * VOXEL_SIZE * 2.5 * voffset;
|
||||
float col = traceConeAO(voxels, origin, normal, aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, o1, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, o2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, -c1, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, -c2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, -o1, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, -o2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, c1, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
col += traceConeAO(voxels, origin, mix(normal, c2, angleMix), aperture, MAX_DISTANCE, offset);
|
||||
return col / 9.0;
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_cotangentFrame = "
|
||||
mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 duv1, const vec2 duv2) {
|
||||
vec3 dp1 = dFdx(p);
|
||||
vec3 dp2 = dFdy(p);
|
||||
vec3 dp2perp = cross(dp2, n);
|
||||
vec3 dp1perp = cross(n, dp1);
|
||||
vec3 t = dp2perp * duv1.x + dp1perp * duv2.x;
|
||||
vec3 b = dp2perp * duv1.y + dp1perp * duv2.y;
|
||||
float invmax = inversesqrt(max(dot(t, t), dot(b, b)));
|
||||
return mat3(t * invmax, b * invmax, n);
|
||||
}
|
||||
mat3 cotangentFrame(const vec3 n, const vec3 p, const vec2 texCoord) {
|
||||
return cotangentFrame(n, p, dFdx(texCoord), dFdy(texCoord));
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_octahedronWrap = "
|
||||
vec2 octahedronWrap(const vec2 v) {
|
||||
return (1.0 - abs(v.yx)) * (vec2(v.x >= 0.0 ? 1.0 : -1.0, v.y >= 0.0 ? 1.0 : -1.0));
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_packFloat = "
|
||||
float packFloat(const float f1, const float f2) {
|
||||
return floor(f1 * 100.0) + min(f2, 1.0 - 1.0 / 100.0);
|
||||
}
|
||||
";
|
||||
|
||||
public static var str_packFloat2 = "
|
||||
float packFloat2(const float f1, const float f2) {
|
||||
return floor(f1 * 255.0) + min(f2, 1.0 - 1.0 / 100.0);
|
||||
}
|
||||
";
|
||||
}
|
|
@ -1,525 +0,0 @@
|
|||
package armory.system;
|
||||
|
||||
import iron.data.SceneFormat;
|
||||
import armory.system.CyclesFormat;
|
||||
|
||||
class CyclesShaderData {
|
||||
var material:TMaterial;
|
||||
|
||||
public function new(material:TMaterial) {
|
||||
this.material = material;
|
||||
}
|
||||
|
||||
public function add_context(props:Dynamic):CyclesShaderContext {
|
||||
return new CyclesShaderContext(material, props);
|
||||
}
|
||||
}
|
||||
|
||||
class CyclesShaderContext {
|
||||
public var vert:CyclesShader;
|
||||
public var frag:CyclesShader;
|
||||
public var geom:CyclesShader;
|
||||
public var tesc:CyclesShader;
|
||||
public var tese:CyclesShader;
|
||||
public var data:TShaderContext;
|
||||
var material:TMaterial;
|
||||
var constants:Array<TShaderConstant>;
|
||||
var tunits:Array<TTextureUnit>;
|
||||
|
||||
public function new(material:TMaterial, props:Dynamic) {
|
||||
this.material = material;
|
||||
data = {
|
||||
name: props.name,
|
||||
depth_write: props.depth_write,
|
||||
compare_mode: props.compare_mode,
|
||||
cull_mode: props.cull_mode,
|
||||
blend_source: props.blend_source,
|
||||
blend_destination: props.blend_destination,
|
||||
blend_operation: props.blend_operation,
|
||||
alpha_blend_source: props.alpha_blend_source,
|
||||
alpha_blend_destination: props.alpha_blend_destination,
|
||||
alpha_blend_operation: props.alpha_blend_operation,
|
||||
fragment_shader: '',
|
||||
vertex_shader: '',
|
||||
vertex_elements: Reflect.hasField(props, 'vertex_elements') ? props.vertex_elements : [ {name: "pos", data: 'short4norm'}, {name: "nor", data: 'short2norm'}]
|
||||
};
|
||||
|
||||
if (props.color_writes_red != null)
|
||||
data.color_writes_red = props.color_writes_red;
|
||||
if (props.color_writes_green != null)
|
||||
data.color_writes_green = props.color_writes_green;
|
||||
if (props.color_writes_blue != null)
|
||||
data.color_writes_blue = props.color_writes_blue;
|
||||
if (props.color_writes_alpha != null)
|
||||
data.color_writes_alpha = props.color_writes_alpha;
|
||||
|
||||
tunits = data.texture_units = [];
|
||||
constants = data.constants = [];
|
||||
}
|
||||
|
||||
public function add_elem(name:String, data_type:String) {
|
||||
for (e in data.vertex_elements) {
|
||||
if (e.name == name) return;
|
||||
}
|
||||
var elem:TVertexElement = { name: name, data: data_type };
|
||||
data.vertex_elements.push(elem);
|
||||
}
|
||||
|
||||
public function is_elem(name:String) {
|
||||
for (elem in data.vertex_elements)
|
||||
if (elem.name == name)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public function get_elem(name:String):TVertexElement {
|
||||
for (elem in data.vertex_elements) {
|
||||
#if cpp
|
||||
if (Reflect.field(elem, "name") == name)
|
||||
#else
|
||||
if (elem.name == name)
|
||||
#end {
|
||||
return elem;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function add_constant(ctype:String, name:String, link:String = null) {
|
||||
for (c in constants)
|
||||
if (c.name == name)
|
||||
return;
|
||||
|
||||
var c:TShaderConstant = { name: name, type: ctype };
|
||||
if (link != null)
|
||||
c.link = link;
|
||||
constants.push(c);
|
||||
}
|
||||
|
||||
public function add_texture_unit(ctype:String, name:String, link:String = null, is_image = false) {
|
||||
for (c in tunits)
|
||||
if (c.name == name)
|
||||
return;
|
||||
|
||||
var c:TTextureUnit = { name: name };
|
||||
if (link != null)
|
||||
c.link = link;
|
||||
if (is_image)
|
||||
c.is_image = is_image;
|
||||
tunits.push(c);
|
||||
}
|
||||
|
||||
public function make_vert() {
|
||||
data.vertex_shader = material.name + '_' + data.name + '.vert';
|
||||
vert = new CyclesShader(this, 'vert');
|
||||
return vert;
|
||||
}
|
||||
|
||||
public function make_frag() {
|
||||
data.fragment_shader = material.name + '_' + data.name + '.frag';
|
||||
frag = new CyclesShader(this, 'frag');
|
||||
return frag;
|
||||
}
|
||||
}
|
||||
|
||||
class CyclesShader {
|
||||
|
||||
public var context:CyclesShaderContext;
|
||||
var shader_type = '';
|
||||
var includes:Array<String> = [];
|
||||
public var ins:Array<String> = [];
|
||||
public var outs:Array<String> = [];
|
||||
var uniforms:Array<String> = [];
|
||||
var sharedSamplers:Array<String> = [];
|
||||
var functions = new Map<String, String>();
|
||||
public var main = '';
|
||||
public var main_init = '';
|
||||
public var main_end = '';
|
||||
public var main_normal = '';
|
||||
public var main_textures = '';
|
||||
public var main_attribs = '';
|
||||
var header = '';
|
||||
public var write_pre = false;
|
||||
public var write_normal = 0;
|
||||
public var write_textures = 0;
|
||||
var vstruct_as_vsin = true;
|
||||
var lock = false;
|
||||
|
||||
// References
|
||||
public var bposition = false;
|
||||
public var wposition = false;
|
||||
public var mposition = false;
|
||||
public var vposition = false;
|
||||
public var wvpposition = false;
|
||||
public var ndcpos = false;
|
||||
public var wtangent = false;
|
||||
public var vVec = false;
|
||||
public var vVecCam = false;
|
||||
public var n = false;
|
||||
public var nAttr = false;
|
||||
public var dotNV = false;
|
||||
public var invTBN = false;
|
||||
|
||||
public function new(context:CyclesShaderContext, shader_type:String) {
|
||||
this.context = context;
|
||||
this.shader_type = shader_type;
|
||||
}
|
||||
|
||||
public function add_include(s:String) {
|
||||
includes.push(s);
|
||||
}
|
||||
|
||||
public function add_in(s:String) {
|
||||
ins.push(s);
|
||||
}
|
||||
|
||||
public function add_out(s:String) {
|
||||
outs.push(s);
|
||||
}
|
||||
|
||||
public function add_uniform(s:String, link:String = null, included = false) {
|
||||
var ar = s.split(' ');
|
||||
// layout(RGBA8) image3D voxels
|
||||
var utype = ar[ar.length - 2];
|
||||
var uname = ar[ar.length - 1];
|
||||
if (StringTools.startsWith(utype, 'sampler') || StringTools.startsWith(utype, 'image') || StringTools.startsWith(utype, 'uimage')) {
|
||||
var is_image = (StringTools.startsWith(utype, 'image') || StringTools.startsWith(utype, 'uimage')) ? true : false;
|
||||
context.add_texture_unit(utype, uname, link, is_image);
|
||||
}
|
||||
else {
|
||||
// Prefer vec4[] for d3d to avoid padding
|
||||
if (ar[0] == 'float' && ar[1].indexOf('[') >= 0) {
|
||||
ar[0] = 'floats';
|
||||
ar[1] = ar[1].split('[')[0];
|
||||
}
|
||||
else if (ar[0] == 'vec4' && ar[1].indexOf('[') >= 0) {
|
||||
ar[0] = 'floats';
|
||||
ar[1] = ar[1].split('[')[0];
|
||||
}
|
||||
context.add_constant(ar[0], ar[1], link);
|
||||
}
|
||||
if (included == false && uniforms.indexOf(s) == -1) {
|
||||
uniforms.push(s);
|
||||
}
|
||||
}
|
||||
|
||||
public function add_shared_sampler(s:String) {
|
||||
if (sharedSamplers.indexOf(s) == -1) {
|
||||
sharedSamplers.push(s);
|
||||
var ar = s.split(' ');
|
||||
// layout(RGBA8) sampler2D tex
|
||||
var utype = ar[ar.length - 2];
|
||||
var uname = ar[ar.length - 1];
|
||||
context.add_texture_unit(utype, uname, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
public function add_function(s:String) {
|
||||
var fname = s.split('(')[0];
|
||||
if (functions.exists(fname)) return;
|
||||
functions.set(fname, s);
|
||||
}
|
||||
|
||||
public function contains(s:String):Bool {
|
||||
return main.indexOf(s) >= 0 ||
|
||||
main_init.indexOf(s) >= 0 ||
|
||||
main_normal.indexOf(s) >= 0 ||
|
||||
ins.indexOf(s) >= 0 ||
|
||||
main_textures.indexOf(s) >= 0 ||
|
||||
main_attribs.indexOf(s) >= 0;
|
||||
}
|
||||
|
||||
public function write_init(s:String) {
|
||||
main_init = s + '\n' + main_init;
|
||||
}
|
||||
|
||||
public function write(s:String) {
|
||||
if (lock) return;
|
||||
if (write_textures > 0) {
|
||||
main_textures += s + '\n';
|
||||
}
|
||||
else if (write_normal > 0) {
|
||||
main_normal += s + '\n';
|
||||
}
|
||||
else if (write_pre) {
|
||||
main_init += s + '\n';
|
||||
}
|
||||
else {
|
||||
main += s + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
public function write_header(s:String) {
|
||||
header += s + '\n';
|
||||
}
|
||||
|
||||
public function write_end(s:String) {
|
||||
main_end += s + '\n';
|
||||
}
|
||||
|
||||
public function write_attrib(s:String) {
|
||||
main_attribs += s + '\n';
|
||||
}
|
||||
|
||||
function dataSize(data:String):String {
|
||||
if (data == 'float1') return '1';
|
||||
else if (data == 'float2') return '2';
|
||||
else if (data == 'float3') return '3';
|
||||
else if (data == 'float4') return '4';
|
||||
else if (data == 'short2norm') return '2';
|
||||
else if (data == 'short4norm') return '4';
|
||||
else return '1';
|
||||
}
|
||||
|
||||
function vstruct_to_vsin() {
|
||||
// if self.shader_type != 'vert' or self.ins != [] or not self.vstruct_as_vsin: # Vertex structure as vertex shader input
|
||||
// return
|
||||
var vs = context.data.vertex_elements;
|
||||
for (e in vs) {
|
||||
add_in('vec' + dataSize(e.data) + ' ' + e.name);
|
||||
}
|
||||
}
|
||||
|
||||
public function get():String {
|
||||
|
||||
if (shader_type == 'vert' && vstruct_as_vsin) {
|
||||
vstruct_to_vsin();
|
||||
}
|
||||
|
||||
var sharedSampler = 'shared_sampler';
|
||||
if (sharedSamplers.length > 0) {
|
||||
sharedSampler = sharedSamplers[0].split(' ')[1] + '_sampler';
|
||||
}
|
||||
|
||||
#if kha_direct3d11
|
||||
var s = '#define HLSL\n';
|
||||
s += '#define sampler2D Texture2D\n';
|
||||
s += '#define sampler3D Texture3D\n';
|
||||
s += '#define texture(tex, coord) tex.Sample(tex ## _sampler, coord)\n';
|
||||
s += '#define textureShared(tex, coord) tex.Sample($sharedSampler, coord)\n';
|
||||
s += '#define textureOffset(tex, coord, offset) tex.Sample(tex ## _sampler, coord, offset)\n';
|
||||
s += '#define textureOffsetShared(tex, coord, offset) tex.Sample($sharedSampler, coord, offset)\n';
|
||||
s += '#define textureLod(tex, coord, lod) tex.SampleLevel(tex ## _sampler, coord, lod)\n';
|
||||
s += '#define textureLodShared(tex, coord, lod) tex.SampleLevel($sharedSampler, coord, lod)\n';
|
||||
s += '#define texelFetch(tex, coord, lod) tex.Load(float3(coord.xy, lod))\n';
|
||||
s += '#define mod(a, b) (a % b)\n';
|
||||
s += '#define vec2 float2\n';
|
||||
s += '#define vec3 float3\n';
|
||||
s += '#define vec4 float4\n';
|
||||
s += '#define ivec2 int2\n';
|
||||
s += '#define ivec3 int3\n';
|
||||
s += '#define ivec4 int4\n';
|
||||
s += '#define mat2 float2x2\n';
|
||||
s += '#define mat3 float3x3\n';
|
||||
s += '#define mat4 float4x4\n';
|
||||
s += '#define dFdx ddx\n';
|
||||
s += '#define dFdy ddy\n';
|
||||
s += '#define inversesqrt rsqrt\n';
|
||||
s += '#define fract frac\n';
|
||||
s += '#define mix lerp\n';
|
||||
|
||||
s += header;
|
||||
|
||||
var in_ext = '';
|
||||
var out_ext = '';
|
||||
|
||||
for (a in includes)
|
||||
s += '#include "' + a + '"\n';
|
||||
|
||||
// Input structure
|
||||
var index = 0;
|
||||
if (ins.length > 0) {
|
||||
s += 'struct SPIRV_Cross_Input {\n';
|
||||
index = 0;
|
||||
ins.sort(function(a, b):Int {
|
||||
// Sort inputs by name
|
||||
return a.substring(4) >= b.substring(4) ? 1 : -1;
|
||||
});
|
||||
for (a in ins) {
|
||||
s += '$a$in_ext : TEXCOORD$index;\n';
|
||||
index++;
|
||||
}
|
||||
// Built-ins
|
||||
if (shader_type == 'vert' && main.indexOf("gl_VertexID") >= 0) {
|
||||
s += 'uint gl_VertexID : SV_VertexID;\n';
|
||||
ins.push('uint gl_VertexID');
|
||||
}
|
||||
if (shader_type == 'vert' && main.indexOf("gl_InstanceID") >= 0) {
|
||||
s += 'uint gl_InstanceID : SV_InstanceID;\n';
|
||||
ins.push('uint gl_InstanceID');
|
||||
}
|
||||
s += '};\n';
|
||||
}
|
||||
|
||||
// Output structure
|
||||
var num = 0;
|
||||
if (outs.length > 0 || shader_type == 'vert') {
|
||||
s += 'struct SPIRV_Cross_Output {\n';
|
||||
outs.sort(function(a, b):Int {
|
||||
// Sort outputs by name
|
||||
return a.substring(4) >= b.substring(4) ? 1 : -1;
|
||||
});
|
||||
index = 0;
|
||||
if (shader_type == 'vert') {
|
||||
for (a in outs) {
|
||||
s += '$a$out_ext : TEXCOORD$index;\n';
|
||||
index++;
|
||||
}
|
||||
s += 'float4 svpos : SV_POSITION;\n';
|
||||
}
|
||||
else {
|
||||
var out = outs[0];
|
||||
// Multiple render targets
|
||||
if (out.charAt(out.length - 1) == ']') {
|
||||
num = Std.parseInt(out.charAt(out.length - 2));
|
||||
s += 'vec4 fragColor[$num] : SV_TARGET0;\n';
|
||||
}
|
||||
else {
|
||||
s += 'vec4 fragColor : SV_TARGET0;\n';
|
||||
}
|
||||
}
|
||||
s += '};\n';
|
||||
}
|
||||
|
||||
for (a in uniforms) {
|
||||
s += 'uniform ' + a + ';\n';
|
||||
#if kha_direct3d11
|
||||
if (StringTools.startsWith(a, 'sampler')) {
|
||||
s += 'SamplerState ' + a.split(' ')[1] + '_sampler;\n';
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
if (sharedSamplers.length > 0) {
|
||||
for (a in sharedSamplers) {
|
||||
s += 'uniform ' + a + ';\n';
|
||||
}
|
||||
#if kha_direct3d11
|
||||
s += 'SamplerState $sharedSampler;\n';
|
||||
#end
|
||||
}
|
||||
|
||||
for (f in functions) {
|
||||
s += f + '\n';
|
||||
}
|
||||
|
||||
// Begin main
|
||||
if (outs.length > 0 || shader_type == 'vert') {
|
||||
if (ins.length > 0) {
|
||||
s += 'SPIRV_Cross_Output main(SPIRV_Cross_Input stage_input) {\n';
|
||||
}
|
||||
else {
|
||||
s += 'SPIRV_Cross_Output main() {\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ins.length > 0) {
|
||||
s += 'void main(SPIRV_Cross_Input stage_input) {\n';
|
||||
}
|
||||
else {
|
||||
s += 'void main() {\n';
|
||||
}
|
||||
}
|
||||
|
||||
// Declare inputs
|
||||
for (a in ins) {
|
||||
var b = a.substring(5); // Remove type 'vec4 '
|
||||
s += '$a = stage_input.$b;\n';
|
||||
}
|
||||
|
||||
if (shader_type == 'vert') {
|
||||
s += 'vec4 gl_Position;\n';
|
||||
for (a in outs) {
|
||||
s += '$a;\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (outs.length > 0) {
|
||||
if (num > 0) s += 'vec4 fragColor[$num];\n';
|
||||
else s += 'vec4 fragColor;\n';
|
||||
}
|
||||
}
|
||||
|
||||
s += main_attribs;
|
||||
s += main_textures;
|
||||
s += main_normal;
|
||||
s += main_init;
|
||||
s += main;
|
||||
s += main_end;
|
||||
|
||||
// Write output structure
|
||||
if (shader_type == 'vert') {
|
||||
s += 'SPIRV_Cross_Output stage_output;\n';
|
||||
s += 'gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n';
|
||||
s += 'stage_output.svpos = gl_Position;\n';
|
||||
for (a in outs) {
|
||||
var b = a.substring(5); // Remove type 'vec4 '
|
||||
s += 'stage_output.$b = $b;\n';
|
||||
}
|
||||
|
||||
s += 'return stage_output;\n';
|
||||
|
||||
}
|
||||
else {
|
||||
if (outs.length > 0) {
|
||||
s += 'SPIRV_Cross_Output stage_output;\n';
|
||||
if (num > 0) {
|
||||
for (i in 0...num) {
|
||||
s += 'stage_output.fragColor[$i] = fragColor[$i];\n';
|
||||
}
|
||||
}
|
||||
else {
|
||||
s += 'stage_output.fragColor = fragColor;\n';
|
||||
}
|
||||
s += 'return stage_output;\n';
|
||||
}
|
||||
}
|
||||
s += '}\n';
|
||||
|
||||
#else // kha_opengl
|
||||
|
||||
#if kha_webgl
|
||||
var s = '#version 300 es\n';
|
||||
if (shader_type == 'frag') {
|
||||
s += 'precision mediump float;\n';
|
||||
s += 'precision mediump int;\n';
|
||||
}
|
||||
#else
|
||||
var s = '#version 330\n';
|
||||
#end
|
||||
|
||||
s += '#define mul(a, b) b * a\n';
|
||||
s += '#define textureShared texture\n';
|
||||
s += '#define textureOffsetShared textureOffset\n';
|
||||
s += '#define textureLodShared textureLod\n';
|
||||
s += header;
|
||||
|
||||
var in_ext = '';
|
||||
var out_ext = '';
|
||||
|
||||
for (a in includes)
|
||||
s += '#include "' + a + '"\n';
|
||||
for (a in ins)
|
||||
s += 'in $a$in_ext;\n';
|
||||
for (a in outs)
|
||||
s += 'out $a$out_ext;\n';
|
||||
for (a in uniforms)
|
||||
s += 'uniform ' + a + ';\n';
|
||||
for (a in sharedSamplers)
|
||||
s += 'uniform ' + a + ';\n';
|
||||
for (f in functions)
|
||||
s += f + '\n';
|
||||
s += 'void main() {\n';
|
||||
s += main_attribs;
|
||||
s += main_textures;
|
||||
s += main_normal;
|
||||
s += main_init;
|
||||
s += main;
|
||||
s += main_end;
|
||||
s += '}\n';
|
||||
|
||||
#end
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package armory.system;
|
||||
|
||||
import armory.logicnode.*;
|
||||
import armory.system.CyclesFormat;
|
||||
|
||||
class Logic {
|
||||
|
||||
|
@ -221,3 +220,50 @@ class Logic {
|
|||
return Type.createInstance(cname, args);
|
||||
}
|
||||
}
|
||||
|
||||
typedef TNodeCanvas = {
|
||||
var name: String;
|
||||
var nodes: Array<TNode>;
|
||||
var links: Array<TNodeLink>;
|
||||
}
|
||||
|
||||
typedef TNode = {
|
||||
var id: Int;
|
||||
var name: String;
|
||||
var type: String;
|
||||
var x: Float;
|
||||
var y: Float;
|
||||
var inputs: Array<TNodeSocket>;
|
||||
var outputs: Array<TNodeSocket>;
|
||||
var buttons: Array<TNodeButton>;
|
||||
var color: Int;
|
||||
}
|
||||
|
||||
typedef TNodeSocket = {
|
||||
var id: Int;
|
||||
var node_id: Int;
|
||||
var name: String;
|
||||
var type: String;
|
||||
var color: Int;
|
||||
var default_value: Dynamic;
|
||||
@:optional var min: Null<Float>;
|
||||
@:optional var max: Null<Float>;
|
||||
}
|
||||
|
||||
typedef TNodeLink = {
|
||||
var id: Int;
|
||||
var from_id: Int;
|
||||
var from_socket: Int;
|
||||
var to_id: Int;
|
||||
var to_socket: Int;
|
||||
}
|
||||
|
||||
typedef TNodeButton = {
|
||||
var name: String;
|
||||
var type: String;
|
||||
@:optional var output: Null<Int>;
|
||||
@:optional var default_value: Dynamic;
|
||||
@:optional var data: Dynamic;
|
||||
@:optional var min: Null<Float>;
|
||||
@:optional var max: Null<Float>;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue