blob: 80f6efc7da3d3333d61c41a2d3e313de844725fe [file] [log] [blame]
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;
}