| 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<Light>; |
| ^^^^^^ |
| |
| #include <metal_stdlib> |
| |
| using namespace metal; |
| |
| template<typename T, int N, int M> |
| inline vec<T, M> operator*(matrix<T, N, M> lhs, packed_vec<T, N> rhs) { |
| return lhs * vec<T, N>(rhs); |
| } |
| |
| template<typename T, int N, int M> |
| inline vec<T, N> operator*(packed_vec<T, M> lhs, matrix<T, N, M> rhs) { |
| return vec<T, M>(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<float, access::sample> 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<float, access::sample> 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<int>((as_type<uint>(shadowIndex) + as_type<uint>(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<float, access::sample> tint_symbol_17, sampler tint_symbol_18, texture2d<float, access::sample> tint_symbol_19, sampler tint_symbol_20, const constant Material* const tint_symbol_21, texture2d<float, access::sample> tint_symbol_22, sampler tint_symbol_23, texture2d<float, access::sample> tint_symbol_24, sampler tint_symbol_25, texture2d<float, access::sample> 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<float, access::sample> tint_symbol_28, sampler tint_symbol_29, texture2d<float, access::sample> tint_symbol_30, sampler tint_symbol_31, const constant Material* const tint_symbol_32, texture2d<float, access::sample> tint_symbol_33, sampler tint_symbol_34, texture2d<float, access::sample> tint_symbol_35, sampler tint_symbol_36, texture2d<float, access::sample> 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<float, access::sample> 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<float, access::sample> 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<float, access::sample> tint_symbol_49 [[texture(0)]], sampler tint_symbol_50 [[sampler(0)]], texture2d<float, access::sample> tint_symbol_51 [[texture(1)]], sampler tint_symbol_52 [[sampler(1)]], const constant Material* tint_symbol_53 [[buffer(0)]], texture2d<float, access::sample> tint_symbol_54 [[texture(2)]], sampler tint_symbol_55 [[sampler(2)]], texture2d<float, access::sample> tint_symbol_56 [[texture(3)]], sampler tint_symbol_57 [[sampler(3)]], texture2d<float, access::sample> 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<float, access::sample> 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<float, access::sample> 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; |
| } |
| |