Move runtime material parser

This commit is contained in:
unknown 2019-06-21 17:26:19 +02:00
parent 5410566a29
commit ec179489af
5 changed files with 47 additions and 2885 deletions

File diff suppressed because it is too large Load diff

View file

@ -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;
}

View file

@ -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);
}
";
}

View file

@ -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;
}
}

View file

@ -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>;
}