From e6afdbbf5820e066f6eeb0e534a12e87dae3b701 Mon Sep 17 00:00:00 2001 From: Lubos Lenco Date: Thu, 14 May 2020 14:05:28 +0200 Subject: [PATCH] MSL fixes --- .../Sources/arm/node/MaterialFunctions.hx | 231 ++++++++++-------- .../Sources/arm/node/MaterialShader.hx | 87 +++---- Shaders/std/ltc.glsl | 48 ++-- 3 files changed, 187 insertions(+), 179 deletions(-) diff --git a/Libraries/nodelib/Sources/arm/node/MaterialFunctions.hx b/Libraries/nodelib/Sources/arm/node/MaterialFunctions.hx index cb0014da..b6324eae 100644 --- a/Libraries/nodelib/Sources/arm/node/MaterialFunctions.hx +++ b/Libraries/nodelib/Sources/arm/node/MaterialFunctions.hx @@ -313,8 +313,9 @@ void createBasis(vec3 normal, out vec3 tangent, out vec3 binormal) { } "; - public static var str_shIrradiance = " -vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) { + public static var str_shIrradiance = +#if kha_metal +"vec3 shIrradiance(const vec3 nor, constant vec4 shirr[7]) { const float c1 = 0.429043; const float c2 = 0.511664; const float c3 = 0.743125; @@ -343,6 +344,37 @@ vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) { ); } "; +#else +"vec3 shIrradiance(const vec3 nor, const vec4 shirr[7]) { + const float c1 = 0.429043; + const float c2 = 0.511664; + const float c3 = 0.743125; + const float c4 = 0.886227; + const float c5 = 0.247708; + vec3 cl00 = vec3(shirr[0].x, shirr[0].y, shirr[0].z); + vec3 cl1m1 = vec3(shirr[0].w, shirr[1].x, shirr[1].y); + vec3 cl10 = vec3(shirr[1].z, shirr[1].w, shirr[2].x); + vec3 cl11 = vec3(shirr[2].y, shirr[2].z, shirr[2].w); + vec3 cl2m2 = vec3(shirr[3].x, shirr[3].y, shirr[3].z); + vec3 cl2m1 = vec3(shirr[3].w, shirr[4].x, shirr[4].y); + vec3 cl20 = vec3(shirr[4].z, shirr[4].w, shirr[5].x); + vec3 cl21 = vec3(shirr[5].y, shirr[5].z, shirr[5].w); + vec3 cl22 = vec3(shirr[6].x, shirr[6].y, shirr[6].z); + return ( + c1 * cl22 * (nor.y * nor.y - (-nor.z) * (-nor.z)) + + c3 * cl20 * nor.x * nor.x + + c4 * cl00 - + c5 * cl20 + + 2.0 * c1 * cl2m2 * nor.y * (-nor.z) + + 2.0 * c1 * cl21 * nor.y * nor.x + + 2.0 * c1 * cl2m1 * (-nor.z) * nor.x + + 2.0 * c2 * cl11 * nor.y + + 2.0 * c2 * cl1m1 * (-nor.z) + + 2.0 * c2 * cl10 * nor.x + ); +} +"; +#end public static var str_envMapEquirect = " vec2 envMapEquirect(const vec3 normal) { @@ -363,115 +395,104 @@ float integrateEdge(vec3 v1, vec3 v2) { float res = cross(v1, v2).z * ((theta > 0.001) ? theta / sin(theta) : 1.0); return res; } -int clipQuadToHorizon(inout vec3 L[5]) { - int n = 0; - int config = 0; - if (L[0].z > 0.0) config += 1; - if (L[1].z > 0.0) config += 2; - if (L[2].z > 0.0) config += 4; - if (L[3].z > 0.0) config += 8; - if (config == 0) {} - else if (config == 1) { // V1 clip V2 V3 V4 - n = 3; - L[1] = -L[1].z * L[0] + L[0].z * L[1]; - L[2] = -L[3].z * L[0] + L[0].z * L[3]; - } - else if (config == 2) { // V2 clip V1 V3 V4 - n = 3; - L[0] = -L[0].z * L[1] + L[1].z * L[0]; - L[2] = -L[2].z * L[1] + L[1].z * L[2]; - } - else if (config == 3) { // V1 V2 clip V3 V4 - n = 4; - L[2] = -L[2].z * L[1] + L[1].z * L[2]; - L[3] = -L[3].z * L[0] + L[0].z * L[3]; - } - else if (config == 4) { // V3 clip V1 V2 V4 - n = 3; - L[0] = -L[3].z * L[2] + L[2].z * L[3]; - L[1] = -L[1].z * L[2] + L[2].z * L[1]; - } - else if (config == 5) { // V1 V3 clip V2 V4) impossible - n = 0; - } - else if (config == 6) { // V2 V3 clip V1 V4 - n = 4; - L[0] = -L[0].z * L[1] + L[1].z * L[0]; - L[3] = -L[3].z * L[2] + L[2].z * L[3]; - } - else if (config == 7) { // V1 V2 V3 clip V4 - n = 5; - L[4] = -L[3].z * L[0] + L[0].z * L[3]; - L[3] = -L[3].z * L[2] + L[2].z * L[3]; - } - else if (config == 8) { // V4 clip V1 V2 V3 - n = 3; - L[0] = -L[0].z * L[3] + L[3].z * L[0]; - L[1] = -L[2].z * L[3] + L[3].z * L[2]; - L[2] = L[3]; - } - else if (config == 9) { // V1 V4 clip V2 V3 - n = 4; - L[1] = -L[1].z * L[0] + L[0].z * L[1]; - L[2] = -L[2].z * L[3] + L[3].z * L[2]; - } - else if (config == 10) { // V2 V4 clip V1 V3) impossible - n = 0; - } - else if (config == 11) { // V1 V2 V4 clip V3 - n = 5; - L[4] = L[3]; - L[3] = -L[2].z * L[3] + L[3].z * L[2]; - L[2] = -L[2].z * L[1] + L[1].z * L[2]; - } - else if (config == 12) { // V3 V4 clip V1 V2 - n = 4; - L[1] = -L[1].z * L[2] + L[2].z * L[1]; - L[0] = -L[0].z * L[3] + L[3].z * L[0]; - } - else if (config == 13) { // V1 V3 V4 clip V2 - n = 5; - L[4] = L[3]; - L[3] = L[2]; - L[2] = -L[1].z * L[2] + L[2].z * L[1]; - L[1] = -L[1].z * L[0] + L[0].z * L[1]; - } - else if (config == 14) { // V2 V3 V4 clip V1 - n = 5; - L[4] = -L[0].z * L[3] + L[3].z * L[0]; - L[0] = -L[0].z * L[1] + L[1].z * L[0]; - } - else if (config == 15) { // V1 V2 V3 V4 - n = 4; - } - if (n == 3) L[3] = L[0]; - if (n == 4) L[4] = L[0]; - return n; -} float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { vec3 T1, T2; T1 = normalize(V - N * dotNV); T2 = cross(N, T1); - Minv = mul(transpose(mat3(T1, T2, N)), Minv); - vec3 L[5]; - L[0] = mul(points0 - P, Minv); - L[1] = mul(points1 - P, Minv); - L[2] = mul(points2 - P, Minv); - L[3] = mul(points3 - P, Minv); - L[4] = vec3(0.0, 0.0, 0.0); - int n = clipQuadToHorizon(L); + Minv = Minv * transpose(mat3(T1, T2, N)); + vec3 L0 = Minv * (points0 - P); + vec3 L1 = Minv * (points1 - P); + vec3 L2 = Minv * (points2 - P); + vec3 L3 = Minv * (points3 - P); + vec3 L4 = vec3(0.0); + int n = 0; + int config = 0; + if (L0.z > 0.0) config += 1; + if (L1.z > 0.0) config += 2; + if (L2.z > 0.0) config += 4; + if (L3.z > 0.0) config += 8; + if (config == 0) {} + else if (config == 1) { + n = 3; + L1 = -L1.z * L0 + L0.z * L1; + L2 = -L3.z * L0 + L0.z * L3; + } + else if (config == 2) { + n = 3; + L0 = -L0.z * L1 + L1.z * L0; + L2 = -L2.z * L1 + L1.z * L2; + } + else if (config == 3) { + n = 4; + L2 = -L2.z * L1 + L1.z * L2; + L3 = -L3.z * L0 + L0.z * L3; + } + else if (config == 4) { + n = 3; + L0 = -L3.z * L2 + L2.z * L3; + L1 = -L1.z * L2 + L2.z * L1; + } + else if (config == 5) { n = 0; } + else if (config == 6) { + n = 4; + L0 = -L0.z * L1 + L1.z * L0; + L3 = -L3.z * L2 + L2.z * L3; + } + else if (config == 7) { + n = 5; + L4 = -L3.z * L0 + L0.z * L3; + L3 = -L3.z * L2 + L2.z * L3; + } + else if (config == 8) { + n = 3; + L0 = -L0.z * L3 + L3.z * L0; + L1 = -L2.z * L3 + L3.z * L2; + L2 = L3; + } + else if (config == 9) { + n = 4; + L1 = -L1.z * L0 + L0.z * L1; + L2 = -L2.z * L3 + L3.z * L2; + } + else if (config == 10) { n = 0; } + else if (config == 11) { + n = 5; + L4 = L3; + L3 = -L2.z * L3 + L3.z * L2; + L2 = -L2.z * L1 + L1.z * L2; + } + else if (config == 12) { + n = 4; + L1 = -L1.z * L2 + L2.z * L1; + L0 = -L0.z * L3 + L3.z * L0; + } + else if (config == 13) { + n = 5; + L4 = L3; + L3 = L2; + L2 = -L1.z * L2 + L2.z * L1; + L1 = -L1.z * L0 + L0.z * L1; + } + else if (config == 14) { + n = 5; + L4 = -L0.z * L3 + L3.z * L0; + L0 = -L0.z * L1 + L1.z * L0; + } + else if (config == 15) { n = 4; } if (n == 0) return 0.0; - L[0] = normalize(L[0]); - L[1] = normalize(L[1]); - L[2] = normalize(L[2]); - L[3] = normalize(L[3]); - L[4] = normalize(L[4]); + if (n == 3) L3 = L0; + if (n == 4) L4 = L0; + L0 = normalize(L0); + L1 = normalize(L1); + L2 = normalize(L2); + L3 = normalize(L3); + L4 = normalize(L4); float sum = 0.0; - sum += integrateEdge(L[0], L[1]); - sum += integrateEdge(L[1], L[2]); - sum += integrateEdge(L[2], L[3]); - if (n >= 4) sum += integrateEdge(L[3], L[4]); - if (n == 5) sum += integrateEdge(L[4], L[0]); + sum += integrateEdge(L0, L1); + sum += integrateEdge(L1, L2); + sum += integrateEdge(L2, L3); + if (n >= 4) sum += integrateEdge(L3, L4); + if (n == 5) sum += integrateEdge(L4, L0); return max(0.0, -sum); } "; diff --git a/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx b/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx index 09c011ae..606b8018 100644 --- a/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx +++ b/Libraries/shaderlib/Sources/arm/node/MaterialShader.hx @@ -453,21 +453,17 @@ class MaterialShader { s += main_end; // Write output structure - if (shader_type == 'vert') { + if (outs.length > 0 || 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'; + if (shader_type == 'vert') { + 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'; + else { if (num > 0) { for (i in 0...num) { s += 'stage_output.fragColor[$i] = fragColor[$i];\n'; @@ -476,8 +472,8 @@ class MaterialShader { else { s += 'stage_output.fragColor = fragColor;\n'; } - s += 'return stage_output;\n'; } + s += 'return stage_output;\n'; } s += '}\n'; @@ -494,7 +490,7 @@ class MaterialShader { s += '#define textureShared(tex, coord) tex.sample($sharedSampler, coord)\n'; s += '#define textureLod(tex, coord, lod) tex.sample(tex ## _sampler, coord, level(lod))\n'; s += '#define textureLodShared(tex, coord, lod) tex.sample($sharedSampler, coord, level(lod))\n'; - s += '#define texelFetch(tex, coord, lod) tex.read(float3(coord.xy, level(lod)))\n'; + s += '#define texelFetch(tex, coord, lod) tex.read(uint2(coord), uint(lod))\n'; s += 'uint2 _getDimensions(texture2d tex, uint lod) { return uint2(tex.get_width(lod), tex.get_height(lod)); }\n'; s += '#define textureSize _getDimensions\n'; s += '#define mod(a, b) (a % b)\n'; @@ -522,7 +518,7 @@ class MaterialShader { // Input structure var index = 0; - if (ins.length > 0) { + //if (ins.length > 0) { s += 'struct main_in {\n'; index = 0; ins.sort(function(a, b): Int { @@ -541,17 +537,8 @@ class MaterialShader { index++; } } - // Built-ins - if (shader_type == 'vert' && main.indexOf("gl_VertexID") >= 0) { - s += 'uint gl_VertexID [[vertex_id]];\n'; - ins.push('uint gl_VertexID'); - } - if (shader_type == 'vert' && main.indexOf("gl_InstanceID") >= 0) { - s += 'uint gl_InstanceID [[instance_id]];\n'; - ins.push('uint gl_InstanceID'); - } s += '};\n'; - } + //} // Output structure var num = 0; @@ -606,15 +593,15 @@ class MaterialShader { s += f + '\n'; } - // Begin main + // Begin main declaration s += '#undef texture\n'; s += shader_type == 'vert' ? 'vertex ' : 'fragment '; - s += outs.length > 0 ? 'main_out ' : 'void '; + s += (outs.length > 0 || shader_type == 'vert') ? 'main_out ' : 'void '; s += 'my_main('; - if (ins.length > 0) { + //if (ins.length > 0) { s += 'main_in in [[stage_in]]'; - } + //} if (uniforms.length > 0) { var bufi = shader_type == 'vert' ? 1 : 0; s += ', constant main_uniforms& uniforms [[buffer($bufi)]]'; @@ -642,6 +629,15 @@ class MaterialShader { // s += ', sampler $sharedSampler [[sampler(${samplers.length})]]'; //} + // Built-ins + if (shader_type == 'vert' && main.indexOf("gl_VertexID") >= 0) { + s += ', uint gl_VertexID [[vertex_id]]'; + } + if (shader_type == 'vert' && main.indexOf("gl_InstanceID") >= 0) { + s += ', uint gl_InstanceID [[instance_id]]'; + } + + // End main declaration s += ') {\n'; s += '#define texture(tex, coord) tex.sample(tex ## _sampler, coord)\n'; @@ -654,7 +650,14 @@ class MaterialShader { for (a in uniforms) { if (!StringTools.startsWith(a, 'sampler')) { var b = a.split(" ")[1]; // Remove type 'vec4 ' - s += '$a = uniforms.$b;\n'; + if (b.indexOf("[") >= 0) { + b = b.substring(0, b.indexOf("[")); + var type = a.split(" ")[0]; + s += 'constant $type *$b = uniforms.$b;\n'; + } + else { + s += '$a = uniforms.$b;\n'; + } } } @@ -679,19 +682,17 @@ class MaterialShader { s += main_end; // Write output structure - if (shader_type == 'vert') { + if (outs.length > 0 || shader_type == 'vert') { s += 'main_out out = {};\n'; - s += 'gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n'; - s += 'out.svpos = gl_Position;\n'; - for (a in outs) { - var b = a.split(" ")[1]; // Remove type 'vec4 ' - s += 'out.$b = $b;\n'; + if (shader_type == 'vert') { + s += 'gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;\n'; + s += 'out.svpos = gl_Position;\n'; + for (a in outs) { + var b = a.split(" ")[1]; // Remove type 'vec4 ' + s += 'out.$b = $b;\n'; + } } - s += 'return out;\n'; - } - else { - if (outs.length > 0) { - s += 'main_out out = {};\n'; + else { if (num > 0) { for (i in 0...num) { s += 'out.fragColor_$i = fragColor[$i];\n'; @@ -700,8 +701,8 @@ class MaterialShader { else { s += 'out.fragColor = fragColor;\n'; } - s += 'return out;\n'; } + s += 'return out;\n'; } s += '}\n'; diff --git a/Shaders/std/ltc.glsl b/Shaders/std/ltc.glsl index 154a609c..56a79ca0 100644 --- a/Shaders/std/ltc.glsl +++ b/Shaders/std/ltc.glsl @@ -5,12 +5,6 @@ const float LUT_SIZE = 64.0; const float LUT_SCALE = (LUT_SIZE - 1.0) / LUT_SIZE; const float LUT_BIAS = 0.5 / LUT_SIZE; -vec3 L0; -vec3 L1; -vec3 L2; -vec3 L3; -vec3 L4; - float integrateEdge(vec3 v1, vec3 v2) { float cosTheta = dot(v1, v2); float theta = acos(cosTheta); @@ -18,7 +12,22 @@ float integrateEdge(vec3 v1, vec3 v2) { return res; } -int clipQuadToHorizon(/*inout vec3 L[5], out int n*/) { +float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { + // Construct orthonormal basis around N + vec3 T1, T2; + T1 = normalize(V - N * dotNV); + T2 = cross(N, T1); + + // Rotate area light in (T1, T2, R) basis + Minv = Minv * transpose(mat3(T1, T2, N)); + + // Polygon (allocate 5 vertices for clipping) + vec3 L0 = Minv * (points0 - P); + vec3 L1 = Minv * (points1 - P); + vec3 L2 = Minv * (points2 - P); + vec3 L3 = Minv * (points3 - P); + vec3 L4 = vec3(0.0); + int n = 0; // Detect clipping config int config = 0; @@ -105,32 +114,9 @@ int clipQuadToHorizon(/*inout vec3 L[5], out int n*/) { n = 4; } + if (n == 0) return 0.0; if (n == 3) L3 = L0; if (n == 4) L4 = L0; - return n; -} - -float ltcEvaluate(vec3 N, vec3 V, float dotNV, vec3 P, mat3 Minv, vec3 points0, vec3 points1, vec3 points2, vec3 points3) { - // Construct orthonormal basis around N - vec3 T1, T2; - T1 = normalize(V - N * dotNV); - T2 = cross(N, T1); - - // Rotate area light in (T1, T2, R) basis - Minv = Minv * transpose(mat3(T1, T2, N)); - - // Polygon (allocate 5 vertices for clipping) - // vec3 L[5]; - L0 = Minv * (points0 - P); - L1 = Minv * (points1 - P); - L2 = Minv * (points2 - P); - L3 = Minv * (points3 - P); - L4 = vec3(0.0); - - // int n; - int n = clipQuadToHorizon(/*L, n*/); - - if (n == 0) return 0.0; // Project onto sphere L0 = normalize(L0);