benchmark/skinned-shadowed-pbr-fragment.wgsl:51:13 warning: use of deprecated language feature: the @stride attribute is deprecated; use a larger type if necessary lights : @stride(32) array; ^^^^^^ #include using namespace metal; template inline vec operator*(matrix lhs, packed_vec rhs) { return lhs * vec(rhs); } template inline vec operator*(packed_vec lhs, matrix rhs) { return vec(lhs) * rhs; } struct Camera { /* 0x0000 */ float4x4 projection; /* 0x0040 */ float4x4 inverseProjection; /* 0x0080 */ float4x4 view; /* 0x00c0 */ packed_float3 position; /* 0x00cc */ float time; /* 0x00d0 */ float2 outputSize; /* 0x00d8 */ float zNear; /* 0x00dc */ float zFar; }; struct ClusterLights { /* 0x0000 */ uint offset; /* 0x0004 */ uint count; }; struct tint_array_wrapper { /* 0x0000 */ ClusterLights arr[27648]; }; struct tint_array_wrapper_1 { /* 0x0000 */ uint arr[1769472]; }; struct ClusterLightGroup { /* 0x0000 */ uint offset; /* 0x0004 */ tint_array_wrapper lights; /* 0x36004 */ tint_array_wrapper_1 indices; }; struct Light { /* 0x0000 */ packed_float3 position; /* 0x000c */ float range; /* 0x0010 */ packed_float3 color; /* 0x001c */ float intensity; }; struct GlobalLights { /* 0x0000 */ packed_float3 ambient; /* 0x000c */ int8_t tint_pad[4]; /* 0x0010 */ packed_float3 dirColor; /* 0x001c */ float dirIntensity; /* 0x0020 */ packed_float3 dirDirection; /* 0x002c */ uint lightCount; /* 0x0030 */ Light lights[1]; }; struct LightShadowTable { /* 0x0000 */ int light[1]; }; struct tint_array_wrapper_2 { float2 arr[16]; }; struct ShadowProperties { /* 0x0000 */ float4 viewport; /* 0x0010 */ float4x4 viewProj; }; struct LightShadows { /* 0x0000 */ ShadowProperties properties[1]; }; struct VertexOutput { float4 position; float3 worldPos; float3 view; float2 texcoord; float2 texcoord2; float4 color; float4 instanceColor; float3 normal; float3 tangent; float3 bitangent; }; struct Material { /* 0x0000 */ float4 baseColorFactor; /* 0x0010 */ packed_float3 emissiveFactor; /* 0x001c */ float occlusionStrength; /* 0x0020 */ float2 metallicRoughnessFactor; /* 0x0028 */ float alphaCutoff; /* 0x002c */ int8_t tint_pad_1[4]; }; struct SurfaceInfo { float4 baseColor; float3 albedo; float metallic; float roughness; float3 normal; float3 f0; float ao; float3 emissive; float3 v; }; struct PuctualLight { uint lightType; float3 pointToLight; float range; float3 color; float intensity; }; struct FragmentOutput { float4 color; float4 emissive; }; struct tint_symbol_1 { float3 worldPos [[user(locn0)]]; float3 view [[user(locn1)]]; float2 texcoord [[user(locn2)]]; float2 texcoord2 [[user(locn3)]]; float4 color [[user(locn4)]]; float4 instanceColor [[user(locn5)]]; float3 normal [[user(locn6)]]; float3 tangent [[user(locn7)]]; float3 bitangent [[user(locn8)]]; }; struct tint_symbol_2 { float4 color [[color(0)]]; float4 emissive [[color(1)]]; }; constant float GAMMA = 2.200000048f; constant uint3 tileCount = uint3(32u, 18u, 48u); constant uint shadowSampleCount = 16u; constant float PI = 3.141592741f; constant uint LightType_Point = 0u; constant uint LightType_Spot = 1u; constant uint LightType_Directional = 2u; float3 linearTosRGB(float3 linear) { float const INV_GAMMA = (1.0f / GAMMA); return pow(linear, float3(INV_GAMMA)); } float3 sRGBToLinear(float3 srgb) { return pow(srgb, float3(GAMMA)); } float linearDepth(float depthSample, const constant Camera* const tint_symbol_4) { return (((*(tint_symbol_4)).zFar * (*(tint_symbol_4)).zNear) / fma(depthSample, ((*(tint_symbol_4)).zNear - (*(tint_symbol_4)).zFar), (*(tint_symbol_4)).zFar)); } uint3 getTile(float4 fragCoord, const constant Camera* const tint_symbol_5) { float const sliceScale = (float(tileCount[2]) / log2(((*(tint_symbol_5)).zFar / (*(tint_symbol_5)).zNear))); float const sliceBias = -(((float(tileCount[2]) * log2((*(tint_symbol_5)).zNear)) / log2(((*(tint_symbol_5)).zFar / (*(tint_symbol_5)).zNear)))); uint const zTile = uint(fmax(((log2(linearDepth(fragCoord[2], tint_symbol_5)) * sliceScale) + sliceBias), 0.0f)); return uint3(uint((fragCoord[0] / ((*(tint_symbol_5)).outputSize[0] / float(tileCount[0])))), uint((fragCoord[1] / ((*(tint_symbol_5)).outputSize[1] / float(tileCount[1])))), zTile); } uint getClusterIndex(float4 fragCoord, const constant Camera* const tint_symbol_6) { uint3 const tile = getTile(fragCoord, tint_symbol_6); return ((tile[0] + (tile[1] * tileCount[0])) + ((tile[2] * tileCount[0]) * tileCount[1])); } float dirLightVisibility(float3 worldPos, const device LightShadowTable* const tint_symbol_7, const device LightShadows* const tint_symbol_8, depth2d tint_symbol_9, sampler tint_symbol_10, thread tint_array_wrapper_2* const tint_symbol_11) { int const shadowIndex = (*(tint_symbol_7)).light[0u]; if ((shadowIndex == -1)) { return 1.0f; } float4 const viewport = (*(tint_symbol_8)).properties[shadowIndex].viewport; float4 const lightPos = ((*(tint_symbol_8)).properties[shadowIndex].viewProj * float4(worldPos, 1.0f)); float3 const shadowPos = float3((((float4(lightPos).xy / lightPos[3]) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos[2] / lightPos[3])); float2 const viewportPos = float2((float4(viewport).xy + (float3(shadowPos).xy * float4(viewport).zw))); float2 const texelSize = (1.0f / float2(int2(tint_symbol_9.get_width(0), tint_symbol_9.get_height(0)))); float4 const clampRect = float4((float4(viewport).xy - texelSize), ((float4(viewport).xy + float4(viewport).zw) + texelSize)); float visibility = 0.0f; for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { visibility = (visibility + tint_symbol_9.sample_compare(tint_symbol_10, clamp((viewportPos + ((*(tint_symbol_11)).arr[i] * texelSize)), float4(clampRect).xy, float4(clampRect).zw), (shadowPos[2] - 0.003f), level(0))); } return (visibility / float(shadowSampleCount)); } int getCubeFace(float3 v) { float3 const vAbs = fabs(v); if (((vAbs[2] >= vAbs[0]) && (vAbs[2] >= vAbs[1]))) { if ((v[2] < 0.0f)) { return 5; } return 4; } if ((vAbs[1] >= vAbs[0])) { if ((v[1] < 0.0f)) { return 3; } return 2; } if ((v[0] < 0.0f)) { return 1; } return 0; } float pointLightVisibility(uint lightIndex, float3 worldPos, float3 pointToLight, const device LightShadowTable* const tint_symbol_12, const device LightShadows* const tint_symbol_13, depth2d tint_symbol_14, sampler tint_symbol_15, thread tint_array_wrapper_2* const tint_symbol_16) { int shadowIndex = (*(tint_symbol_12)).light[(lightIndex + 1u)]; if ((shadowIndex == -1)) { return 1.0f; } shadowIndex = as_type((as_type(shadowIndex) + as_type(getCubeFace((pointToLight * -1.0f))))); float4 const viewport = (*(tint_symbol_13)).properties[shadowIndex].viewport; float4 const lightPos = ((*(tint_symbol_13)).properties[shadowIndex].viewProj * float4(worldPos, 1.0f)); float3 const shadowPos = float3((((float4(lightPos).xy / lightPos[3]) * float2(0.5f, -0.5f)) + float2(0.5f, 0.5f)), (lightPos[2] / lightPos[3])); float2 const viewportPos = float2((float4(viewport).xy + (float3(shadowPos).xy * float4(viewport).zw))); float2 const texelSize = (1.0f / float2(int2(tint_symbol_14.get_width(0), tint_symbol_14.get_height(0)))); float4 const clampRect = float4(float4(viewport).xy, (float4(viewport).xy + float4(viewport).zw)); float visibility = 0.0f; for(uint i = 0u; (i < shadowSampleCount); i = (i + 1u)) { visibility = (visibility + tint_symbol_14.sample_compare(tint_symbol_15, clamp((viewportPos + ((*(tint_symbol_16)).arr[i] * texelSize)), float4(clampRect).xy, float4(clampRect).zw), (shadowPos[2] - 0.01f), level(0))); } return (visibility / float(shadowSampleCount)); } SurfaceInfo GetSurfaceInfo(VertexOutput input, texture2d tint_symbol_17, sampler tint_symbol_18, texture2d tint_symbol_19, sampler tint_symbol_20, const constant Material* const tint_symbol_21, texture2d tint_symbol_22, sampler tint_symbol_23, texture2d tint_symbol_24, sampler tint_symbol_25, texture2d tint_symbol_26, sampler tint_symbol_27) { SurfaceInfo surface = {}; surface.v = normalize(input.view); float3x3 const tbn = float3x3(input.tangent, input.bitangent, input.normal); float3 const normalMap = float4(tint_symbol_17.sample(tint_symbol_18, input.texcoord)).rgb; surface.normal = normalize((tbn * ((2.0f * normalMap) - float3(1.0f)))); float4 const baseColorMap = tint_symbol_19.sample(tint_symbol_20, input.texcoord); surface.baseColor = ((input.color * (*(tint_symbol_21)).baseColorFactor) * baseColorMap); if ((surface.baseColor[3] < (*(tint_symbol_21)).alphaCutoff)) { discard_fragment(); } surface.albedo = float4(surface.baseColor).rgb; float4 const metallicRoughnessMap = tint_symbol_22.sample(tint_symbol_23, input.texcoord); surface.metallic = ((*(tint_symbol_21)).metallicRoughnessFactor[0] * metallicRoughnessMap[2]); surface.roughness = ((*(tint_symbol_21)).metallicRoughnessFactor[1] * metallicRoughnessMap[1]); float3 const dielectricSpec = float3(0.039999999f); surface.f0 = mix(dielectricSpec, surface.albedo, float3(surface.metallic)); float4 const occlusionMap = tint_symbol_24.sample(tint_symbol_25, input.texcoord); surface.ao = ((*(tint_symbol_21)).occlusionStrength * occlusionMap[0]); float4 const emissiveMap = tint_symbol_26.sample(tint_symbol_27, input.texcoord); surface.emissive = ((*(tint_symbol_21)).emissiveFactor * float4(emissiveMap).rgb); if ((input.instanceColor[3] == 0.0f)) { surface.albedo = (surface.albedo + float4(input.instanceColor).rgb); } else { surface.albedo = (surface.albedo * float4(input.instanceColor).rgb); } return surface; } float3 FresnelSchlick(float cosTheta, float3 F0) { return (F0 + ((float3(1.0f) - F0) * pow((1.0f - cosTheta), 5.0f))); } float DistributionGGX(float3 N, float3 H, float roughness) { float const a_1 = (roughness * roughness); float const a2 = (a_1 * a_1); float const NdotH = fmax(dot(N, H), 0.0f); float const NdotH2 = (NdotH * NdotH); float const num = a2; float const denom = ((NdotH2 * (a2 - 1.0f)) + 1.0f); return (num / ((PI * denom) * denom)); } float GeometrySchlickGGX(float NdotV, float roughness) { float const r_1 = (roughness + 1.0f); float const k = ((r_1 * r_1) / 8.0f); float const num = NdotV; float const denom = ((NdotV * (1.0f - k)) + k); return (num / denom); } float GeometrySmith(float3 N, float3 V, float3 L, float roughness) { float const NdotV = fmax(dot(N, V), 0.0f); float const NdotL = fmax(dot(N, L), 0.0f); float const ggx2 = GeometrySchlickGGX(NdotV, roughness); float const ggx1 = GeometrySchlickGGX(NdotL, roughness); return (ggx1 * ggx2); } float lightAttenuation(PuctualLight light) { if ((light.lightType == LightType_Directional)) { return 1.0f; } float const distance = length(light.pointToLight); if ((light.range <= 0.0f)) { return (1.0f / pow(distance, 2.0f)); } return (clamp((1.0f - pow((distance / light.range), 4.0f)), 0.0f, 1.0f) / pow(distance, 2.0f)); } float3 lightRadiance(PuctualLight light, SurfaceInfo surface) { float3 const L = normalize(light.pointToLight); float3 const H = normalize((surface.v + L)); float const NDF = DistributionGGX(surface.normal, H, surface.roughness); float const G = GeometrySmith(surface.normal, surface.v, L, surface.roughness); float3 const F = FresnelSchlick(fmax(dot(H, surface.v), 0.0f), surface.f0); float3 const kD = ((float3(1.0f) - F) * (1.0f - surface.metallic)); float const NdotL = fmax(dot(surface.normal, L), 0.0f); float3 const numerator = ((NDF * G) * F); float const denominator = fmax(((4.0f * fmax(dot(surface.normal, surface.v), 0.0f)) * NdotL), 0.001f); float3 const specular = (numerator / float3(denominator)); float3 const radiance = ((light.color * light.intensity) * lightAttenuation(light)); return (((((kD * surface.albedo) / float3(PI)) + specular) * radiance) * NdotL); } FragmentOutput fragmentMain_inner(VertexOutput input, texture2d tint_symbol_28, sampler tint_symbol_29, texture2d tint_symbol_30, sampler tint_symbol_31, const constant Material* const tint_symbol_32, texture2d tint_symbol_33, sampler tint_symbol_34, texture2d tint_symbol_35, sampler tint_symbol_36, texture2d tint_symbol_37, sampler tint_symbol_38, const device GlobalLights* const tint_symbol_39, const device LightShadowTable* const tint_symbol_40, const device LightShadows* const tint_symbol_41, depth2d tint_symbol_42, sampler tint_symbol_43, thread tint_array_wrapper_2* const tint_symbol_44, const constant Camera* const tint_symbol_45, const device ClusterLightGroup* const tint_symbol_46, texture2d tint_symbol_47, sampler tint_symbol_48) { SurfaceInfo const surface = GetSurfaceInfo(input, tint_symbol_28, tint_symbol_29, tint_symbol_30, tint_symbol_31, tint_symbol_32, tint_symbol_33, tint_symbol_34, tint_symbol_35, tint_symbol_36, tint_symbol_37, tint_symbol_38); float3 Lo = float3(0.0f, 0.0f, 0.0f); if (((*(tint_symbol_39)).dirIntensity > 0.0f)) { PuctualLight light = {}; light.lightType = LightType_Directional; light.pointToLight = (*(tint_symbol_39)).dirDirection; light.color = (*(tint_symbol_39)).dirColor; light.intensity = (*(tint_symbol_39)).dirIntensity; float const lightVis = dirLightVisibility(input.worldPos, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44); Lo = (Lo + (lightRadiance(light, surface) * lightVis)); } uint const clusterIndex = getClusterIndex(input.position, tint_symbol_45); uint const lightOffset = (*(tint_symbol_46)).lights.arr[clusterIndex].offset; uint const lightCount = (*(tint_symbol_46)).lights.arr[clusterIndex].count; for(uint lightIndex = 0u; (lightIndex < lightCount); lightIndex = (lightIndex + 1u)) { uint const i = (*(tint_symbol_46)).indices.arr[(lightOffset + lightIndex)]; PuctualLight light = {}; light.lightType = LightType_Point; light.pointToLight = (float3((*(tint_symbol_39)).lights[i].position).xyz - input.worldPos); light.range = (*(tint_symbol_39)).lights[i].range; light.color = (*(tint_symbol_39)).lights[i].color; light.intensity = (*(tint_symbol_39)).lights[i].intensity; float const lightVis = pointLightVisibility(i, input.worldPos, light.pointToLight, tint_symbol_40, tint_symbol_41, tint_symbol_42, tint_symbol_43, tint_symbol_44); Lo = (Lo + (lightRadiance(light, surface) * lightVis)); } float2 const ssaoCoord = (float4(input.position).xy / float2(int2(int2(tint_symbol_47.get_width(), tint_symbol_47.get_height())).xy)); float const ssaoFactor = tint_symbol_47.sample(tint_symbol_48, ssaoCoord)[0]; float3 const ambient = ((((*(tint_symbol_39)).ambient * surface.albedo) * surface.ao) * ssaoFactor); float3 const color = linearTosRGB(((Lo + ambient) + surface.emissive)); FragmentOutput out = {}; out.color = float4(color, surface.baseColor[3]); out.emissive = float4(surface.emissive, surface.baseColor[3]); return out; } fragment tint_symbol_2 fragmentMain(texture2d tint_symbol_49 [[texture(0)]], sampler tint_symbol_50 [[sampler(0)]], texture2d tint_symbol_51 [[texture(1)]], sampler tint_symbol_52 [[sampler(1)]], const constant Material* tint_symbol_53 [[buffer(0)]], texture2d tint_symbol_54 [[texture(2)]], sampler tint_symbol_55 [[sampler(2)]], texture2d tint_symbol_56 [[texture(3)]], sampler tint_symbol_57 [[sampler(3)]], texture2d tint_symbol_58 [[texture(4)]], sampler tint_symbol_59 [[sampler(4)]], const device GlobalLights* tint_symbol_60 [[buffer(2)]], const device LightShadowTable* tint_symbol_61 [[buffer(3)]], const device LightShadows* tint_symbol_62 [[buffer(4)]], depth2d tint_symbol_63 [[texture(6)]], sampler tint_symbol_64 [[sampler(6)]], const constant Camera* tint_symbol_66 [[buffer(1)]], const device ClusterLightGroup* tint_symbol_67 [[buffer(5)]], texture2d tint_symbol_68 [[texture(5)]], sampler tint_symbol_69 [[sampler(5)]], float4 position [[position]], tint_symbol_1 tint_symbol [[stage_in]]) { thread tint_array_wrapper_2 tint_symbol_65 = {.arr={float2(-1.5f, -1.5f), float2(-1.5f, -0.5f), float2(-1.5f, 0.5f), float2(-1.5f, 1.5f), float2(-0.5f, -1.5f), float2(-0.5f, -0.5f), float2(-0.5f, 0.5f), float2(-0.5f, 1.5f), float2(0.5f, -1.5f), float2(0.5f, -0.5f), float2(0.5f, 0.5f), float2(0.5f, 1.5f), float2(1.5f, -1.5f), float2(1.5f, -0.5f), float2(1.5f, 0.5f), float2(1.5f, 1.5f)}}; VertexOutput const tint_symbol_3 = {.position=position, .worldPos=tint_symbol.worldPos, .view=tint_symbol.view, .texcoord=tint_symbol.texcoord, .texcoord2=tint_symbol.texcoord2, .color=tint_symbol.color, .instanceColor=tint_symbol.instanceColor, .normal=tint_symbol.normal, .tangent=tint_symbol.tangent, .bitangent=tint_symbol.bitangent}; FragmentOutput const inner_result = fragmentMain_inner(tint_symbol_3, tint_symbol_49, tint_symbol_50, tint_symbol_51, tint_symbol_52, tint_symbol_53, tint_symbol_54, tint_symbol_55, tint_symbol_56, tint_symbol_57, tint_symbol_58, tint_symbol_59, tint_symbol_60, tint_symbol_61, tint_symbol_62, tint_symbol_63, tint_symbol_64, &(tint_symbol_65), tint_symbol_66, tint_symbol_67, tint_symbol_68, tint_symbol_69); tint_symbol_2 wrapper_result = {}; wrapper_result.color = inner_result.color; wrapper_result.emissive = inner_result.emissive; return wrapper_result; }