MSL fixes

This commit is contained in:
Lubos Lenco
2020-05-14 14:05:28 +02:00
parent e7e8c41672
commit e6afdbbf58
3 changed files with 187 additions and 179 deletions
@@ -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);
}
";
@@ -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<float> 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';
+17 -31
View File
@@ -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);