; SPIR-V
; Version: 1.1
; Generator: rspirv
; Bound: 644
OpCapability Shader
OpExtension "SPV_KHR_storage_buffer_storage_class"
%1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450
OpEntryPoint GLCompute %345 "gen_terrain_compute" %342
OpEntryPoint Vertex %415 "gen_terrain_vertex" %406 %409 %411 %413
OpEntryPoint Fragment %465 "gen_terrain_fragment" %455 %457 %460 %463 %464
OpEntryPoint Vertex %558 "vs_main" %549 %552 %554 %555 %557
OpEntryPoint Fragment %583 "fs_main" %576 %578 %580 %582
OpExecutionMode %345 LocalSize 64 1 1
OpExecutionMode %465 OriginUpperLeft
OpExecutionMode %583 OriginUpperLeft
%3 = OpString "debug-symbol-terrain.wgsl"
OpSource Unknown 0 %3 "// Taken from https://github.com/sotrh/learn-wgpu/blob/11820796f5e1dbce42fb1119f04ddeb4b167d2a0/code/intermediate/tutorial13-terrain/src/terrain.wgsl
// ============================
// Terrain Generation
// ============================

// https://gist.github.com/munrocket/236ed5ba7e409b8bdf1ff6eca5dcdc39
//  MIT License. © Ian McEwan, Stefan Gustavson, Munrocket
// - Less condensed glsl implementation with comments can be found at https://weber.itn.liu.se/~stegu/jgt2012/article.pdf

fn permute3(x: vec3<f32>) -> vec3<f32> { return (((x * 34.) + 1.) * x) % vec3<f32>(289.); }

fn snoise2(v: vec2<f32>) -> f32 {
    let C = vec4<f32>(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
    var i: vec2<f32> = floor(v + dot(v, C.yy));
    let x0 = v - i + dot(i, C.xx);
    // I flipped the condition here from > to < as it fixed some artifacting I was observing
    var i1: vec2<f32> = select(vec2<f32>(1., 0.), vec2<f32>(0., 1.), (x0.x < x0.y));
    var x12: vec4<f32> = x0.xyxy + C.xxzz - vec4<f32>(i1, 0., 0.);
    i = i % vec2<f32>(289.);
    let p = permute3(permute3(i.y + vec3<f32>(0., i1.y, 1.)) + i.x + vec3<f32>(0., i1.x, 1.));
    var m: vec3<f32> = max(0.5 - vec3<f32>(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), vec3<f32>(0.));
    m = m * m;
    m = m * m;
    let x = 2. * fract(p * C.www) - 1.;
    let h = abs(x) - 0.5;
    let ox = floor(x + 0.5);
    let a0 = x - ox;
    m = m * (1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h));
    let g = vec3<f32>(a0.x * x0.x + h.x * x0.y, a0.yz * x12.xz + h.yz * x12.yw);
    return 130. * dot(m, g);
}


fn fbm(p: vec2<f32>) -> f32 {
    let NUM_OCTAVES: u32 = 5u;
    var x = p * 0.01;
    var v = 0.0;
    var a = 0.5;
    let shift = vec2<f32>(100.0);
    let cs = vec2<f32>(cos(0.5), sin(0.5));
    let rot = mat2x2<f32>(cs.x, cs.y, -cs.y, cs.x);

    for (var i = 0u; i < NUM_OCTAVES; i = i + 1u) {
        v = v + a * snoise2(x);
        x = rot * x * 2.0 + shift;
        a = a * 0.5;
    }

    return v;
}

struct ChunkData {
    chunk_size: vec2<u32>,
    chunk_corner: vec2<i32>,
    min_max_height: vec2<f32>,
}

struct Vertex {
    @location(0) position: vec3<f32>,
    @location(1) normal: vec3<f32>,
}

struct VertexBuffer {
    data: array<Vertex>, // stride: 32
}

struct IndexBuffer {
    data: array<u32>,
}

@group(0) @binding(0) var<uniform> chunk_data: ChunkData;
@group(0) @binding(1) var<storage, read_write> vertices: VertexBuffer;
@group(0) @binding(2) var<storage, read_write> indices: IndexBuffer;

fn terrain_point(p: vec2<f32>, min_max_height: vec2<f32>) -> vec3<f32> {
    return vec3<f32>(
        p.x,
        mix(min_max_height.x, min_max_height.y, fbm(p)),
        p.y,
    );
}

fn terrain_vertex(p: vec2<f32>, min_max_height: vec2<f32>) -> Vertex {
    let v = terrain_point(p, min_max_height);

    let tpx = terrain_point(p + vec2<f32>(0.1, 0.0), min_max_height) - v;
    let tpz = terrain_point(p + vec2<f32>(0.0, 0.1), min_max_height) - v;
    let tnx = terrain_point(p + vec2<f32>(-0.1, 0.0), min_max_height) - v;
    let tnz = terrain_point(p + vec2<f32>(0.0, -0.1), min_max_height) - v;

    let pn = normalize(cross(tpz, tpx));
    let nn = normalize(cross(tnz, tnx));

    let n = (pn + nn) * 0.5;

    return Vertex(v, n);
}

fn index_to_p(vert_index: u32, chunk_size: vec2<u32>, chunk_corner: vec2<i32>) -> vec2<f32> {
    return vec2(
        f32(vert_index) % f32(chunk_size.x + 1u),
        f32(vert_index / (chunk_size.x + 1u)),
    ) + vec2<f32>(chunk_corner);
}

@compute @workgroup_size(64)
fn gen_terrain_compute(
    @builtin(global_invocation_id) gid: vec3<u32>
) {
    // Create vert_component
    let vert_index = gid.x;

    let p = index_to_p(vert_index, chunk_data.chunk_size, chunk_data.chunk_corner);

    vertices.data[vert_index] = terrain_vertex(p, chunk_data.min_max_height);

    // Create indices
    let start_index = gid.x * 6u; // using TriangleList

    if (start_index >= (chunk_data.chunk_size.x * chunk_data.chunk_size.y * 6u)) { return; }

    let v00 = vert_index + gid.x / chunk_data.chunk_size.x;
    let v10 = v00 + 1u;
    let v01 = v00 + chunk_data.chunk_size.x + 1u;
    let v11 = v01 + 1u;

    indices.data[start_index] = v00;
    indices.data[start_index + 1u] = v01;
    indices.data[start_index + 2u] = v11;
    indices.data[start_index + 3u] = v00;
    indices.data[start_index + 4u] = v11;
    indices.data[start_index + 5u] = v10;
}

// ============================
// Terrain Gen (Fragment Shader)
// ============================

struct GenData {
    chunk_size: vec2<u32>,
    chunk_corner: vec2<i32>,
    min_max_height: vec2<f32>,
    texture_size: u32,
    start_index: u32,
}
@group(0)
@binding(0)
var<uniform> gen_data: GenData;

struct GenVertexOutput {
    @location(0)
    index: u32,
    @builtin(position)
    position: vec4<f32>,
    @location(1)
    uv: vec2<f32>,
};

@vertex
fn gen_terrain_vertex(@builtin(vertex_index) vindex: u32) -> GenVertexOutput {
    let u = f32(((vindex + 2u) / 3u) % 2u);
    let v = f32(((vindex + 1u) / 3u) % 2u);
    let uv = vec2<f32>(u, v);

    let position = vec4<f32>(-1.0 + uv * 2.0, 0.0, 1.0);

    // TODO: maybe replace this with u32(dot(uv, vec2(f32(gen_data.texture_dim.x))))
    let index = u32(uv.x * f32(gen_data.texture_size) + uv.y * f32(gen_data.texture_size)) + gen_data.start_index;

    return GenVertexOutput(index, position, uv);
}


struct GenFragmentOutput {
    @location(0) vert_component: u32,
    @location(1) index: u32,
}

@fragment
fn gen_terrain_fragment(in: GenVertexOutput) -> GenFragmentOutput {
    let i = u32(in.uv.x * f32(gen_data.texture_size) + in.uv.y * f32(gen_data.texture_size * gen_data.texture_size)) + gen_data.start_index;
    let vert_index = u32(floor(f32(i) / 6.));
    let comp_index = i % 6u;

    let p = index_to_p(vert_index, gen_data.chunk_size, gen_data.chunk_corner);
    let v = terrain_vertex(p, gen_data.min_max_height);

    var vert_component: f32 = 0.;
    
    switch comp_index {
        case 0u: { vert_component = v.position.x; }
        case 1u: { vert_component = v.position.y; }
        case 2u: { vert_component = v.position.z; }
        case 3u: { vert_component = v.normal.x; }
        case 4u: { vert_component = v.normal.y; }
        case 5u: { vert_component = v.normal.z; }
        default: {}
    }

    let v00 = vert_index + vert_index / gen_data.chunk_size.x;
    let v10 = v00 + 1u;
    let v01 = v00 + gen_data.chunk_size.x + 1u;
    let v11 = v01 + 1u;

    var index = 0u;
    switch comp_index {
        case 0u, 3u: { index = v00; }
        case 2u, 4u: { index = v11; }
        case 1u: { index = v01; }
        case 5u: { index = v10; }
        default: {}
    }
    index = in.index;
    // index = gen_data.start_index;
    // indices.data[start_index] = v00;
    // indices.data[start_index + 1u] = v01;
    // indices.data[start_index + 2u] = v11;
    // indices.data[start_index + 3u] = v00;
    // indices.data[start_index + 4u] = v11;
    // indices.data[start_index + 5u] = v10;

    let ivert_component = bitcast<u32>(vert_component);
    return GenFragmentOutput(ivert_component, index);
}

// ============================
// Terrain Rendering
// ============================

struct Camera {
    view_pos: vec4<f32>,
    view_proj: mat4x4<f32>,
}
@group(0) @binding(0)
var<uniform> camera: Camera;

struct Light {
    position: vec3<f32>,
    color: vec3<f32>,
}
@group(1) @binding(0)
var<uniform> light: Light;

struct VertexOutput {
    @builtin(position) clip_position: vec4<f32>,
    @location(0) normal: vec3<f32>,
    @location(1) world_pos: vec3<f32>,
}

@vertex
fn vs_main(
    vertex: Vertex,
) -> VertexOutput {
    let clip_position = camera.view_proj * vec4<f32>(vertex.position, 1.);
    let normal = vertex.normal;
    return VertexOutput(clip_position, normal, vertex.position);
}

@group(2) @binding(0)
var t_diffuse: texture_2d<f32>;
@group(2) @binding(1)
var s_diffuse: sampler;
@group(2) @binding(2)
var t_normal: texture_2d<f32>;
@group(2) @binding(3)
var s_normal: sampler;

fn color23(p: vec2<f32>) -> vec3<f32> {
    return vec3<f32>(
        snoise2(p) * 0.5 + 0.5,
        snoise2(p + vec2<f32>(23., 32.)) * 0.5 + 0.5,
        snoise2(p + vec2<f32>(-43., 3.)) * 0.5 + 0.5,
    );
}

@fragment
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
    var color = smoothstep(vec3<f32>(0.0), vec3<f32>(0.1), fract(in.world_pos));
    color = mix(vec3<f32>(0.5, 0.1, 0.7), vec3<f32>(0.2, 0.2, 0.2), vec3<f32>(color.x * color.y * color.z));

    let ambient_strength = 0.1;
    let ambient_color = light.color * ambient_strength;

    let light_dir = normalize(light.position - in.world_pos);
    let view_dir = normalize(camera.view_pos.xyz - in.world_pos);
    let half_dir = normalize(view_dir + light_dir);

    let diffuse_strength = max(dot(in.normal, light_dir), 0.0);
    let diffuse_color = diffuse_strength * light.color;

    let specular_strength = pow(max(dot(in.normal, half_dir), 0.0), 32.0);
    let specular_color = specular_strength * light.color;

    let result = (ambient_color + diffuse_color + specular_color) * color;

    return vec4<f32>(result, 1.0);
}"
OpMemberName %13 0 "chunk_size"
OpMemberName %13 1 "chunk_corner"
OpMemberName %13 2 "min_max_height"
OpName %13 "ChunkData"
OpMemberName %14 0 "position"
OpMemberName %14 1 "normal"
OpName %14 "Vertex"
OpMemberName %16 0 "data"
OpName %16 "VertexBuffer"
OpMemberName %18 0 "data"
OpName %18 "IndexBuffer"
OpMemberName %20 0 "chunk_size"
OpMemberName %20 1 "chunk_corner"
OpMemberName %20 2 "min_max_height"
OpMemberName %20 3 "texture_size"
OpMemberName %20 4 "start_index"
OpName %20 "GenData"
OpMemberName %21 0 "index"
OpMemberName %21 1 "position"
OpMemberName %21 2 "uv"
OpName %21 "GenVertexOutput"
OpMemberName %22 0 "vert_component"
OpMemberName %22 1 "index"
OpName %22 "GenFragmentOutput"
OpMemberName %24 0 "view_pos"
OpMemberName %24 1 "view_proj"
OpName %24 "Camera"
OpMemberName %25 0 "position"
OpMemberName %25 1 "color"
OpName %25 "Light"
OpMemberName %26 0 "clip_position"
OpMemberName %26 1 "normal"
OpMemberName %26 2 "world_pos"
OpName %26 "VertexOutput"
OpName %29 "chunk_data"
OpName %32 "vertices"
OpName %34 "indices"
OpName %36 "gen_data"
OpName %39 "camera"
OpName %42 "light"
OpName %45 "t_diffuse"
OpName %47 "s_diffuse"
OpName %49 "t_normal"
OpName %50 "s_normal"
OpName %52 "x"
OpName %53 "permute3"
OpName %66 "v"
OpName %67 "snoise2"
OpName %86 "i"
OpName %89 "i1"
OpName %91 "x12"
OpName %94 "m"
OpName %203 "p"
OpName %204 "fbm"
OpName %209 "x"
OpName %211 "v"
OpName %213 "a"
OpName %214 "i"
OpName %255 "p"
OpName %256 "min_max_height"
OpName %257 "terrain_point"
OpName %268 "p"
OpName %269 "min_max_height"
OpName %270 "terrain_vertex"
OpName %300 "vert_index"
OpName %301 "chunk_size"
OpName %302 "chunk_corner"
OpName %303 "index_to_p"
OpName %319 "p"
OpName %320 "color23"
OpName %342 "gid"
OpName %345 "gen_terrain_compute"
OpName %406 "vindex"
OpName %409 "index"
OpName %411 "position"
OpName %413 "uv"
OpName %415 "gen_terrain_vertex"
OpName %455 "index"
OpName %457 "position"
OpName %460 "uv"
OpName %463 "vert_component"
OpName %464 "index"
OpName %465 "gen_terrain_fragment"
OpName %468 "vert_component"
OpName %469 "index"
OpName %549 "position"
OpName %552 "normal"
OpName %554 "clip_position"
OpName %555 "normal"
OpName %557 "world_pos"
OpName %558 "vs_main"
OpName %576 "clip_position"
OpName %578 "normal"
OpName %580 "world_pos"
OpName %583 "fs_main"
OpName %592 "color"
OpMemberDecorate %13 0 Offset 0
OpMemberDecorate %13 1 Offset 8
OpMemberDecorate %13 2 Offset 16
OpMemberDecorate %14 0 Offset 0
OpMemberDecorate %14 1 Offset 16
OpDecorate %15 ArrayStride 32
OpMemberDecorate %16 0 Offset 0
OpDecorate %16 Block
OpDecorate %17 ArrayStride 4
OpMemberDecorate %18 0 Offset 0
OpDecorate %18 Block
OpMemberDecorate %20 0 Offset 0
OpMemberDecorate %20 1 Offset 8
OpMemberDecorate %20 2 Offset 16
OpMemberDecorate %20 3 Offset 24
OpMemberDecorate %20 4 Offset 28
OpMemberDecorate %21 0 Offset 0
OpMemberDecorate %21 1 Offset 16
OpMemberDecorate %21 2 Offset 32
OpMemberDecorate %22 0 Offset 0
OpMemberDecorate %22 1 Offset 4
OpMemberDecorate %24 0 Offset 0
OpMemberDecorate %24 1 Offset 16
OpMemberDecorate %24 1 ColMajor
OpMemberDecorate %24 1 MatrixStride 16
OpMemberDecorate %25 0 Offset 0
OpMemberDecorate %25 1 Offset 16
OpMemberDecorate %26 0 Offset 0
OpMemberDecorate %26 1 Offset 16
OpMemberDecorate %26 2 Offset 32
OpDecorate %29 DescriptorSet 0
OpDecorate %29 Binding 0
OpDecorate %30 Block
OpMemberDecorate %30 0 Offset 0
OpDecorate %32 DescriptorSet 0
OpDecorate %32 Binding 1
OpDecorate %34 DescriptorSet 0
OpDecorate %34 Binding 2
OpDecorate %36 DescriptorSet 0
OpDecorate %36 Binding 0
OpDecorate %37 Block
OpMemberDecorate %37 0 Offset 0
OpDecorate %39 DescriptorSet 0
OpDecorate %39 Binding 0
OpDecorate %40 Block
OpMemberDecorate %40 0 Offset 0
OpDecorate %42 DescriptorSet 1
OpDecorate %42 Binding 0
OpDecorate %43 Block
OpMemberDecorate %43 0 Offset 0
OpDecorate %45 DescriptorSet 2
OpDecorate %45 Binding 0
OpDecorate %47 DescriptorSet 2
OpDecorate %47 Binding 1
OpDecorate %49 DescriptorSet 2
OpDecorate %49 Binding 2
OpDecorate %50 DescriptorSet 2
OpDecorate %50 Binding 3
OpDecorate %342 BuiltIn GlobalInvocationId
OpDecorate %406 BuiltIn VertexIndex
OpDecorate %409 Location 0
OpDecorate %409 Flat
OpDecorate %411 BuiltIn Position
OpDecorate %413 Location 1
OpDecorate %455 Location 0
OpDecorate %455 Flat
OpDecorate %457 BuiltIn FragCoord
OpDecorate %460 Location 1
OpDecorate %463 Location 0
OpDecorate %464 Location 1
OpDecorate %549 Location 0
OpDecorate %552 Location 1
OpDecorate %554 BuiltIn Position
OpDecorate %555 Location 0
OpDecorate %557 Location 1
OpDecorate %576 BuiltIn FragCoord
OpDecorate %578 Location 0
OpDecorate %580 Location 1
OpDecorate %582 Location 0
%2 = OpTypeVoid
%5 = OpTypeFloat 32
%4 = OpTypeVector %5 3
%6 = OpTypeVector %5 2
%7 = OpTypeVector %5 4
%8 = OpTypeInt 32 0
%9 = OpTypeMatrix %6 2
%10 = OpTypeVector %8 2
%12 = OpTypeInt 32 1
%11 = OpTypeVector %12 2
%13 = OpTypeStruct %10 %11 %6
%14 = OpTypeStruct %4 %4
%15 = OpTypeRuntimeArray %14
%16 = OpTypeStruct %15
%17 = OpTypeRuntimeArray %8
%18 = OpTypeStruct %17
%19 = OpTypeVector %8 3
%20 = OpTypeStruct %10 %11 %6 %8 %8
%21 = OpTypeStruct %8 %7 %6
%22 = OpTypeStruct %8 %8
%23 = OpTypeMatrix %7 4
%24 = OpTypeStruct %7 %23
%25 = OpTypeStruct %4 %4
%26 = OpTypeStruct %7 %4 %4
%27 = OpTypeImage %5 2D 0 0 0 1 Unknown
%28 = OpTypeSampler
%30 = OpTypeStruct %13
%31 = OpTypePointer Uniform %30
%29 = OpVariable  %31  Uniform
%33 = OpTypePointer StorageBuffer %16
%32 = OpVariable  %33  StorageBuffer
%35 = OpTypePointer StorageBuffer %18
%34 = OpVariable  %35  StorageBuffer
%37 = OpTypeStruct %20
%38 = OpTypePointer Uniform %37
%36 = OpVariable  %38  Uniform
%40 = OpTypeStruct %24
%41 = OpTypePointer Uniform %40
%39 = OpVariable  %41  Uniform
%43 = OpTypeStruct %25
%44 = OpTypePointer Uniform %43
%42 = OpVariable  %44  Uniform
%46 = OpTypePointer UniformConstant %27
%45 = OpVariable  %46  UniformConstant
%48 = OpTypePointer UniformConstant %28
%47 = OpVariable  %48  UniformConstant
%49 = OpVariable  %46  UniformConstant
%50 = OpVariable  %48  UniformConstant
%54 = OpTypeFunction %4 %4
%55 = OpConstant  %5  34.0
%56 = OpConstant  %5  1.0
%57 = OpConstantComposite  %4  %56 %56 %56
%58 = OpConstant  %5  289.0
%59 = OpConstantComposite  %4  %58 %58 %58
%68 = OpTypeFunction %5 %6
%69 = OpConstant  %5  0.21132487
%70 = OpConstant  %5  0.36602542
%71 = OpConstant  %5  -0.57735026
%72 = OpConstant  %5  0.024390243
%73 = OpConstantComposite  %7  %69 %70 %71 %72
%74 = OpConstant  %5  0.0
%75 = OpConstantComposite  %6  %56 %74
%76 = OpConstantComposite  %6  %74 %56
%77 = OpConstantComposite  %6  %58 %58
%78 = OpConstant  %5  0.5
%79 = OpConstantComposite  %4  %78 %78 %78
%80 = OpConstantComposite  %4  %74 %74 %74
%81 = OpConstant  %5  2.0
%82 = OpConstant  %5  1.7928429
%83 = OpConstant  %5  0.85373473
%84 = OpConstantComposite  %4  %82 %82 %82
%85 = OpConstant  %5  130.0
%87 = OpTypePointer Function %6
%88 = OpConstantNull  %6
%90 = OpConstantNull  %6
%92 = OpTypePointer Function %7
%93 = OpConstantNull  %7
%95 = OpTypePointer Function %4
%96 = OpConstantNull  %4
%112 = OpTypeBool
%115 = OpTypeVector %112 2
%125 = OpTypePointer Function %5
%126 = OpConstant  %8  1
%135 = OpConstant  %8  0
%205 = OpConstant  %8  5
%206 = OpConstant  %5  0.01
%207 = OpConstant  %5  100.0
%208 = OpConstantComposite  %6  %207 %207
%210 = OpConstantNull  %6
%212 = OpTypePointer Function %5
%215 = OpTypePointer Function %8
%258 = OpTypeFunction %4 %6 %6
%271 = OpTypeFunction %14 %6 %6
%272 = OpConstant  %5  0.1
%273 = OpConstantComposite  %6  %272 %74
%274 = OpConstantComposite  %6  %74 %272
%275 = OpConstant  %5  -0.1
%276 = OpConstantComposite  %6  %275 %74
%277 = OpConstantComposite  %6  %74 %275
%304 = OpTypeFunction %6 %8 %10 %11
%321 = OpTypeFunction %4 %6
%322 = OpConstant  %5  23.0
%323 = OpConstant  %5  32.0
%324 = OpConstantComposite  %6  %322 %323
%325 = OpConstant  %5  -43.0
%326 = OpConstant  %5  3.0
%327 = OpConstantComposite  %6  %325 %326
%343 = OpTypePointer Input %19
%342 = OpVariable  %343  Input
%346 = OpTypeFunction %2
%347 = OpTypePointer Uniform %13
%349 = OpConstant  %8  6
%350 = OpConstant  %8  2
%351 = OpConstant  %8  3
%352 = OpConstant  %8  4
%355 = OpTypePointer Uniform %10
%358 = OpTypePointer Uniform %11
%362 = OpTypePointer StorageBuffer %15
%363 = OpTypePointer StorageBuffer %14
%364 = OpTypePointer Uniform %6
%371 = OpTypePointer Uniform %8
%392 = OpTypePointer StorageBuffer %17
%393 = OpTypePointer StorageBuffer %8
%407 = OpTypePointer Input %8
%406 = OpVariable  %407  Input
%410 = OpTypePointer Output %8
%409 = OpVariable  %410  Output
%412 = OpTypePointer Output %7
%411 = OpVariable  %412  Output
%414 = OpTypePointer Output %6
%413 = OpVariable  %414  Output
%416 = OpTypePointer Uniform %20
%418 = OpConstant  %5  -1.0
%419 = OpConstantComposite  %6  %418 %418
%434 = OpTypePointer Uniform %8
%455 = OpVariable  %407  Input
%458 = OpTypePointer Input %7
%457 = OpVariable  %458  Input
%461 = OpTypePointer Input %6
%460 = OpVariable  %461  Input
%463 = OpVariable  %410  Output
%464 = OpVariable  %410  Output
%467 = OpConstant  %5  6.0
%550 = OpTypePointer Input %4
%549 = OpVariable  %550  Input
%552 = OpVariable  %550  Input
%554 = OpVariable  %412  Output
%556 = OpTypePointer Output %4
%555 = OpVariable  %556  Output
%557 = OpVariable  %556  Output
%559 = OpTypePointer Uniform %24
%562 = OpTypePointer Uniform %23
%576 = OpVariable  %458  Input
%578 = OpVariable  %550  Input
%580 = OpVariable  %550  Input
%582 = OpVariable  %412  Output
%585 = OpTypePointer Uniform %25
%587 = OpConstantComposite  %4  %272 %272 %272
%588 = OpConstant  %5  0.7
%589 = OpConstantComposite  %4  %78 %272 %588
%590 = OpConstant  %5  0.2
%591 = OpConstantComposite  %4  %590 %590 %590
%593 = OpConstantNull  %4
%608 = OpTypePointer Uniform %4
%617 = OpTypePointer Uniform %7
%53 = OpFunction  %4  None %54
%52 = OpFunctionParameter  %4
%51 = OpLabel
OpBranch %60
%60 = OpLabel
OpLine %3 10 52
%61 = OpVectorTimesScalar  %4  %52 %55
OpLine %3 10 50
%62 = OpFAdd  %4  %61 %57
%63 = OpFMul  %4  %62 %52
OpLine %3 10 49
%64 = OpFRem  %4  %63 %59
OpReturnValue %64
OpFunctionEnd
%67 = OpFunction  %5  None %68
%66 = OpFunctionParameter  %6
%65 = OpLabel
%89 = OpVariable  %87  Function %90
%94 = OpVariable  %95  Function %96
%86 = OpVariable  %87  Function %88
%91 = OpVariable  %92  Function %93
OpBranch %97
%97 = OpLabel
OpLine %3 13 13
OpLine %3 14 24
%98 = OpVectorShuffle  %6  %73 %73 1 1
%99 = OpDot  %5  %66 %98
%100 = OpCompositeConstruct  %6  %99 %99
%101 = OpFAdd  %6  %66 %100
%102 = OpExtInst  %6  %1 Floor %101
OpLine %3 14 5
OpStore %86 %102
OpLine %3 15 14
%103 = OpLoad  %6  %86
%104 = OpFSub  %6  %66 %103
%105 = OpLoad  %6  %86
%106 = OpVectorShuffle  %6  %73 %73 0 0
%107 = OpDot  %5  %105 %106
%108 = OpCompositeConstruct  %6  %107 %107
%109 = OpFAdd  %6  %104 %108
OpLine %3 17 32
OpLine %3 17 25
%110 = OpCompositeExtract  %5  %109 0
%111 = OpCompositeExtract  %5  %109 1
%113 = OpFOrdLessThan  %112  %110 %111
%116 = OpCompositeConstruct  %115  %113 %113
%114 = OpSelect  %6  %116 %76 %75
OpLine %3 17 5
OpStore %89 %114
OpLine %3 18 26
%117 = OpVectorShuffle  %7  %109 %109 0 1 0 1
%118 = OpVectorShuffle  %7  %73 %73 0 0 2 2
%119 = OpFAdd  %7  %117 %118
%120 = OpLoad  %6  %89
OpLine %3 18 26
%121 = OpCompositeConstruct  %7  %120 %74 %74
%122 = OpFSub  %7  %119 %121
OpLine %3 18 5
OpStore %91 %122
OpLine %3 1 1
%123 = OpLoad  %6  %86
OpLine %3 19 9
%124 = OpFRem  %6  %123 %77
OpLine %3 19 5
OpStore %86 %124
OpLine %3 20 31
%127 = OpAccessChain  %125  %86 %126
%128 = OpLoad  %5  %127
OpLine %3 20 51
%129 = OpAccessChain  %125  %89 %126
%130 = OpLoad  %5  %129
OpLine %3 20 31
%131 = OpCompositeConstruct  %4  %74 %130 %56
%132 = OpCompositeConstruct  %4  %128 %128 %128
%133 = OpFAdd  %4  %132 %131
OpLine %3 20 22
%134 = OpFunctionCall  %4  %53 %133
OpLine %3 20 22
%136 = OpAccessChain  %125  %86 %135
%137 = OpLoad  %5  %136
%138 = OpCompositeConstruct  %4  %137 %137 %137
%139 = OpFAdd  %4  %134 %138
OpLine %3 20 84
%140 = OpAccessChain  %125  %89 %135
%141 = OpLoad  %5  %140
OpLine %3 20 22
%142 = OpCompositeConstruct  %4  %74 %141 %56
%143 = OpFAdd  %4  %139 %142
OpLine %3 20 13
%144 = OpFunctionCall  %4  %53 %143
OpLine %3 21 28
%145 = OpDot  %5  %109 %109
%146 = OpLoad  %7  %91
%147 = OpVectorShuffle  %6  %146 %146 0 1
%148 = OpLoad  %7  %91
%149 = OpVectorShuffle  %6  %148 %148 0 1
%150 = OpDot  %5  %147 %149
%151 = OpLoad  %7  %91
%152 = OpVectorShuffle  %6  %151 %151 2 3
%153 = OpLoad  %7  %91
%154 = OpVectorShuffle  %6  %153 %153 2 3
%155 = OpDot  %5  %152 %154
%156 = OpCompositeConstruct  %4  %145 %150 %155
%157 = OpFSub  %4  %79 %156
OpLine %3 21 24
%158 = OpExtInst  %4  %1 FMax %157 %80
OpLine %3 21 5
OpStore %94 %158
OpLine %3 22 9
%159 = OpLoad  %4  %94
%160 = OpLoad  %4  %94
%161 = OpFMul  %4  %159 %160
OpLine %3 22 5
OpStore %94 %161
OpLine %3 23 9
%162 = OpLoad  %4  %94
%163 = OpLoad  %4  %94
%164 = OpFMul  %4  %162 %163
OpLine %3 23 5
OpStore %94 %164
OpLine %3 24 13
%165 = OpVectorShuffle  %4  %73 %73 3 3 3
%166 = OpFMul  %4  %144 %165
%167 = OpExtInst  %4  %1 Fract %166
%168 = OpVectorTimesScalar  %4  %167 %81
OpLine %3 24 13
%169 = OpFSub  %4  %168 %57
OpLine %3 25 13
%170 = OpExtInst  %4  %1 FAbs %169
OpLine %3 25 13
%171 = OpFSub  %4  %170 %79
OpLine %3 26 14
%172 = OpFAdd  %4  %169 %79
%173 = OpExtInst  %4  %1 Floor %172
OpLine %3 27 14
%174 = OpFSub  %4  %169 %173
OpLine %3 1 1
%175 = OpLoad  %4  %94
OpLine %3 28 9
%176 = OpFMul  %4  %174 %174
%177 = OpFMul  %4  %171 %171
%178 = OpFAdd  %4  %176 %177
%179 = OpVectorTimesScalar  %4  %178 %83
%180 = OpFSub  %4  %84 %179
%181 = OpFMul  %4  %175 %180
OpLine %3 28 5
OpStore %94 %181
OpLine %3 29 13
%182 = OpCompositeExtract  %5  %174 0
%183 = OpCompositeExtract  %5  %109 0
%184 = OpFMul  %5  %182 %183
%185 = OpCompositeExtract  %5  %171 0
%186 = OpCompositeExtract  %5  %109 1
%187 = OpFMul  %5  %185 %186
%188 = OpFAdd  %5  %184 %187
%189 = OpVectorShuffle  %6  %174 %174 1 2
%190 = OpLoad  %7  %91
%191 = OpVectorShuffle  %6  %190 %190 0 2
%192 = OpFMul  %6  %189 %191
%193 = OpVectorShuffle  %6  %171 %171 1 2
%194 = OpLoad  %7  %91
%195 = OpVectorShuffle  %6  %194 %194 1 3
%196 = OpFMul  %6  %193 %195
%197 = OpFAdd  %6  %192 %196
%198 = OpCompositeConstruct  %4  %188 %197
OpLine %3 30 12
%199 = OpLoad  %4  %94
%200 = OpDot  %5  %199 %198
%201 = OpFMul  %5  %85 %200
OpReturnValue %201
OpFunctionEnd
%204 = OpFunction  %5  None %68
%203 = OpFunctionParameter  %6
%202 = OpLabel
%211 = OpVariable  %212  Function %74
%214 = OpVariable  %215  Function %135
%209 = OpVariable  %87  Function %210
%213 = OpVariable  %212  Function %78
OpBranch %216
%216 = OpLabel
OpLine %3 36 13
%217 = OpVectorTimesScalar  %6  %203 %206
OpLine %3 36 5
OpStore %209 %217
OpLine %3 39 17
OpLine %3 40 24
%218 = OpExtInst  %5  %1 Cos %78
OpLine %3 40 14
%219 = OpExtInst  %5  %1 Sin %78
%220 = OpCompositeConstruct  %6  %218 %219
OpLine %3 41 15
%221 = OpCompositeExtract  %5  %220 0
%222 = OpCompositeExtract  %5  %220 1
%223 = OpCompositeExtract  %5  %220 1
%224 = OpFNegate  %5  %223
%225 = OpCompositeExtract  %5  %220 0
%226 = OpCompositeConstruct  %6  %221 %222
%227 = OpCompositeConstruct  %6  %224 %225
%228 = OpCompositeConstruct  %9  %226 %227
OpBranch %229
%229 = OpLabel
OpLine %3 43 5
OpLoopMerge %230 %232 None
OpBranch %231
%231 = OpLabel
OpLine %3 43 22
%233 = OpLoad  %8  %214
%234 = OpULessThan  %112  %233 %205
OpLine %3 43 21
OpSelectionMerge %235 None
OpBranchConditional %234 %235 %236
%236 = OpLabel
OpBranch %230
%235 = OpLabel
OpBranch %237
%237 = OpLabel
OpLine %3 1 1
%239 = OpLoad  %5  %211
%240 = OpLoad  %5  %213
%241 = OpLoad  %6  %209
OpLine %3 44 21
%242 = OpFunctionCall  %5  %67 %241
OpLine %3 44 13
%243 = OpFMul  %5  %240 %242
%244 = OpFAdd  %5  %239 %243
OpLine %3 44 9
OpStore %211 %244
OpLine %3 45 13
%245 = OpLoad  %6  %209
%246 = OpMatrixTimesVector  %6  %228 %245
OpLine %3 45 13
%247 = OpVectorTimesScalar  %6  %246 %81
%248 = OpFAdd  %6  %247 %208
OpLine %3 45 9
OpStore %209 %248
OpLine %3 1 1
%249 = OpLoad  %5  %213
OpLine %3 46 13
%250 = OpFMul  %5  %249 %78
OpLine %3 46 9
OpStore %213 %250
OpBranch %238
%238 = OpLabel
OpBranch %232
%232 = OpLabel
OpLine %3 1 1
%251 = OpLoad  %8  %214
OpLine %3 43 43
%252 = OpIAdd  %8  %251 %126
OpLine %3 43 39
OpStore %214 %252
OpBranch %229
%230 = OpLabel
OpLine %3 1 1
%253 = OpLoad  %5  %211
OpReturnValue %253
OpFunctionEnd
%257 = OpFunction  %4  None %258
%255 = OpFunctionParameter  %6
%256 = OpFunctionParameter  %6
%254 = OpLabel
OpBranch %259
%259 = OpLabel
OpLine %3 77 9
%260 = OpCompositeExtract  %5  %255 0
%261 = OpCompositeExtract  %5  %256 0
%262 = OpCompositeExtract  %5  %256 1
OpLine %3 78 49
%263 = OpFunctionCall  %5  %204 %255
OpLine %3 76 12
%264 = OpExtInst  %5  %1 FMix %261 %262 %263
%265 = OpCompositeExtract  %5  %255 1
%266 = OpCompositeConstruct  %4  %260 %264 %265
OpReturnValue %266
OpFunctionEnd
%270 = OpFunction  %14  None %271
%268 = OpFunctionParameter  %6
%269 = OpFunctionParameter  %6
%267 = OpLabel
OpBranch %278
%278 = OpLabel
OpLine %3 84 13
%279 = OpFunctionCall  %4  %257 %268 %269
OpLine %3 86 29
%280 = OpFAdd  %6  %268 %273
OpLine %3 86 15
%281 = OpFunctionCall  %4  %257 %280 %269
OpLine %3 86 15
%282 = OpFSub  %4  %281 %279
OpLine %3 87 29
%283 = OpFAdd  %6  %268 %274
OpLine %3 87 15
%284 = OpFunctionCall  %4  %257 %283 %269
OpLine %3 87 15
%285 = OpFSub  %4  %284 %279
OpLine %3 88 29
%286 = OpFAdd  %6  %268 %276
OpLine %3 88 15
%287 = OpFunctionCall  %4  %257 %286 %269
OpLine %3 88 15
%288 = OpFSub  %4  %287 %279
OpLine %3 89 29
%289 = OpFAdd  %6  %268 %277
OpLine %3 89 15
%290 = OpFunctionCall  %4  %257 %289 %269
OpLine %3 89 15
%291 = OpFSub  %4  %290 %279
OpLine %3 91 14
%292 = OpExtInst  %4  %1 Cross %285 %282
%293 = OpExtInst  %4  %1 Normalize %292
OpLine %3 92 14
%294 = OpExtInst  %4  %1 Cross %291 %288
%295 = OpExtInst  %4  %1 Normalize %294
OpLine %3 94 14
%296 = OpFAdd  %4  %293 %295
OpLine %3 94 13
%297 = OpVectorTimesScalar  %4  %296 %78
OpLine %3 96 12
%298 = OpCompositeConstruct  %14  %279 %297
OpReturnValue %298
OpFunctionEnd
%303 = OpFunction  %6  None %304
%300 = OpFunctionParameter  %8
%301 = OpFunctionParameter  %10
%302 = OpFunctionParameter  %11
%299 = OpLabel
OpBranch %305
%305 = OpLabel
OpLine %3 101 9
%306 = OpConvertUToF  %5  %300
%307 = OpCompositeExtract  %8  %301 0
OpLine %3 101 9
%308 = OpIAdd  %8  %307 %126
%309 = OpConvertUToF  %5  %308
%310 = OpFRem  %5  %306 %309
%311 = OpCompositeExtract  %8  %301 0
OpLine %3 100 12
%312 = OpIAdd  %8  %311 %126
%313 = OpUDiv  %8  %300 %312
%314 = OpConvertUToF  %5  %313
%315 = OpCompositeConstruct  %6  %310 %314
%316 = OpConvertSToF  %6  %302
%317 = OpFAdd  %6  %315 %316
OpReturnValue %317
OpFunctionEnd
%320 = OpFunction  %4  None %321
%319 = OpFunctionParameter  %6
%318 = OpLabel
OpBranch %328
%328 = OpLabel
OpLine %3 270 9
%329 = OpFunctionCall  %5  %67 %319
OpLine %3 270 9
%330 = OpFMul  %5  %329 %78
OpLine %3 270 9
%331 = OpFAdd  %5  %330 %78
OpLine %3 271 17
%332 = OpFAdd  %6  %319 %324
OpLine %3 271 9
%333 = OpFunctionCall  %5  %67 %332
OpLine %3 271 9
%334 = OpFMul  %5  %333 %78
OpLine %3 271 9
%335 = OpFAdd  %5  %334 %78
OpLine %3 272 17
%336 = OpFAdd  %6  %319 %327
OpLine %3 272 9
%337 = OpFunctionCall  %5  %67 %336
OpLine %3 272 9
%338 = OpFMul  %5  %337 %78
OpLine %3 269 12
%339 = OpFAdd  %5  %338 %78
%340 = OpCompositeConstruct  %4  %331 %335 %339
OpReturnValue %340
OpFunctionEnd
%345 = OpFunction  %2  None %346
%341 = OpLabel
%344 = OpLoad  %19  %342
%348 = OpAccessChain  %347  %29 %135
OpBranch %353
%353 = OpLabel
OpLine %3 111 22
%354 = OpCompositeExtract  %8  %344 0
OpLine %3 113 36
%356 = OpAccessChain  %355  %348 %135
%357 = OpLoad  %10  %356
OpLine %3 113 59
%359 = OpAccessChain  %358  %348 %126
%360 = OpLoad  %11  %359
OpLine %3 113 13
%361 = OpFunctionCall  %6  %303 %354 %357 %360
OpLine %3 115 5
OpLine %3 115 51
%365 = OpAccessChain  %364  %348 %350
%366 = OpLoad  %6  %365
OpLine %3 115 33
%367 = OpFunctionCall  %14  %270 %361 %366
OpLine %3 115 5
%368 = OpAccessChain  %363  %32 %135 %354
OpStore %368 %367
OpLine %3 118 23
%369 = OpCompositeExtract  %8  %344 0
OpLine %3 118 23
%370 = OpIMul  %8  %369 %349
OpLine %3 120 25
%372 = OpAccessChain  %371  %348 %135 %135
%373 = OpLoad  %8  %372
OpLine %3 120 25
%374 = OpAccessChain  %371  %348 %135 %126
%375 = OpLoad  %8  %374
%376 = OpIMul  %8  %373 %375
OpLine %3 120 9
%377 = OpIMul  %8  %376 %349
%378 = OpUGreaterThanEqual  %112  %370 %377
OpLine %3 120 5
OpSelectionMerge %379 None
OpBranchConditional %378 %380 %379
%380 = OpLabel
OpReturn
%379 = OpLabel
OpLine %3 122 28
%381 = OpCompositeExtract  %8  %344 0
OpLine %3 122 15
%382 = OpAccessChain  %371  %348 %135 %135
%383 = OpLoad  %8  %382
%384 = OpUDiv  %8  %381 %383
%385 = OpIAdd  %8  %354 %384
OpLine %3 123 15
%386 = OpIAdd  %8  %385 %126
OpLine %3 124 15
%387 = OpAccessChain  %371  %348 %135 %135
%388 = OpLoad  %8  %387
%389 = OpIAdd  %8  %385 %388
OpLine %3 124 15
%390 = OpIAdd  %8  %389 %126
OpLine %3 125 15
%391 = OpIAdd  %8  %390 %126
OpLine %3 127 5
OpLine %3 127 5
%394 = OpAccessChain  %393  %34 %135 %370
OpStore %394 %385
OpLine %3 128 5
OpLine %3 128 5
%395 = OpIAdd  %8  %370 %126
OpLine %3 128 5
%396 = OpAccessChain  %393  %34 %135 %395
OpStore %396 %390
OpLine %3 129 5
OpLine %3 129 5
%397 = OpIAdd  %8  %370 %350
OpLine %3 129 5
%398 = OpAccessChain  %393  %34 %135 %397
OpStore %398 %391
OpLine %3 130 5
OpLine %3 130 5
%399 = OpIAdd  %8  %370 %351
OpLine %3 130 5
%400 = OpAccessChain  %393  %34 %135 %399
OpStore %400 %385
OpLine %3 131 5
OpLine %3 131 5
%401 = OpIAdd  %8  %370 %352
OpLine %3 131 5
%402 = OpAccessChain  %393  %34 %135 %401
OpStore %402 %391
OpLine %3 132 5
OpLine %3 132 5
%403 = OpIAdd  %8  %370 %205
OpLine %3 132 5
%404 = OpAccessChain  %393  %34 %135 %403
OpStore %404 %386
OpReturn
OpFunctionEnd
%415 = OpFunction  %2  None %346
%405 = OpLabel
%408 = OpLoad  %8  %406
%417 = OpAccessChain  %416  %36 %135
OpBranch %420
%420 = OpLabel
OpLine %3 161 19
%421 = OpIAdd  %8  %408 %350
OpLine %3 161 18
%422 = OpUDiv  %8  %421 %351
OpLine %3 161 13
%423 = OpUMod  %8  %422 %350
%424 = OpConvertUToF  %5  %423
OpLine %3 162 19
%425 = OpIAdd  %8  %408 %126
OpLine %3 162 18
%426 = OpUDiv  %8  %425 %351
OpLine %3 162 13
%427 = OpUMod  %8  %426 %350
%428 = OpConvertUToF  %5  %427
OpLine %3 163 14
%429 = OpCompositeConstruct  %6  %424 %428
OpLine %3 165 30
%430 = OpVectorTimesScalar  %6  %429 %81
%431 = OpFAdd  %6  %419 %430
OpLine %3 165 20
%432 = OpCompositeConstruct  %7  %431 %74 %56
OpLine %3 168 21
%433 = OpCompositeExtract  %5  %429 0
OpLine %3 168 21
%435 = OpAccessChain  %434  %417 %351
%436 = OpLoad  %8  %435
%437 = OpConvertUToF  %5  %436
%438 = OpFMul  %5  %433 %437
%439 = OpCompositeExtract  %5  %429 1
OpLine %3 168 17
%440 = OpAccessChain  %434  %417 %351
%441 = OpLoad  %8  %440
%442 = OpConvertUToF  %5  %441
%443 = OpFMul  %5  %439 %442
%444 = OpFAdd  %5  %438 %443
%445 = OpConvertFToU  %8  %444
OpLine %3 168 17
%446 = OpAccessChain  %434  %417 %352
%447 = OpLoad  %8  %446
%448 = OpIAdd  %8  %445 %447
OpLine %3 170 12
%449 = OpCompositeConstruct  %21  %448 %432 %429
%450 = OpCompositeExtract  %8  %449 0
OpStore %409 %450
%451 = OpCompositeExtract  %7  %449 1
OpStore %411 %451
%452 = OpCompositeExtract  %6  %449 2
OpStore %413 %452
OpReturn
OpFunctionEnd
%465 = OpFunction  %2  None %346
%453 = OpLabel
%468 = OpVariable  %212  Function %74
%469 = OpVariable  %215  Function %135
%456 = OpLoad  %8  %455
%459 = OpLoad  %7  %457
%462 = OpLoad  %6  %460
%454 = OpCompositeConstruct  %21  %456 %459 %462
%466 = OpAccessChain  %416  %36 %135
OpBranch %470
%470 = OpLabel
OpLine %3 181 17
%471 = OpCompositeExtract  %6  %454 2
%472 = OpCompositeExtract  %5  %471 0
OpLine %3 181 17
%473 = OpAccessChain  %434  %466 %351
%474 = OpLoad  %8  %473
%475 = OpConvertUToF  %5  %474
%476 = OpFMul  %5  %472 %475
%477 = OpCompositeExtract  %6  %454 2
%478 = OpCompositeExtract  %5  %477 1
OpLine %3 181 70
%479 = OpAccessChain  %434  %466 %351
%480 = OpLoad  %8  %479
OpLine %3 181 13
%481 = OpAccessChain  %434  %466 %351
%482 = OpLoad  %8  %481
%483 = OpIMul  %8  %480 %482
%484 = OpConvertUToF  %5  %483
%485 = OpFMul  %5  %478 %484
%486 = OpFAdd  %5  %476 %485
%487 = OpConvertFToU  %8  %486
OpLine %3 181 13
%488 = OpAccessChain  %434  %466 %352
%489 = OpLoad  %8  %488
%490 = OpIAdd  %8  %487 %489
OpLine %3 182 32
%491 = OpConvertUToF  %5  %490
OpLine %3 182 22
%492 = OpFDiv  %5  %491 %467
%493 = OpExtInst  %5  %1 Floor %492
%494 = OpConvertFToU  %8  %493
OpLine %3 183 22
%495 = OpUMod  %8  %490 %349
OpLine %3 185 36
%496 = OpAccessChain  %355  %466 %135
%497 = OpLoad  %10  %496
OpLine %3 185 57
%498 = OpAccessChain  %358  %466 %126
%499 = OpLoad  %11  %498
OpLine %3 185 13
%500 = OpFunctionCall  %6  %303 %494 %497 %499
OpLine %3 186 31
%501 = OpAccessChain  %364  %466 %350
%502 = OpLoad  %6  %501
OpLine %3 186 13
%503 = OpFunctionCall  %14  %270 %500 %502
OpLine %3 190 5
OpSelectionMerge %504 None
OpSwitch %495 %511 0 %505 1 %506 2 %507 3 %508 4 %509 5 %510
%505 = OpLabel
OpLine %3 191 37
%512 = OpCompositeExtract  %4  %503 0
%513 = OpCompositeExtract  %5  %512 0
OpLine %3 191 20
OpStore %468 %513
OpBranch %504
%506 = OpLabel
OpLine %3 192 37
%514 = OpCompositeExtract  %4  %503 0
%515 = OpCompositeExtract  %5  %514 1
OpLine %3 192 20
OpStore %468 %515
OpBranch %504
%507 = OpLabel
OpLine %3 193 37
%516 = OpCompositeExtract  %4  %503 0
%517 = OpCompositeExtract  %5  %516 2
OpLine %3 193 20
OpStore %468 %517
OpBranch %504
%508 = OpLabel
OpLine %3 194 37
%518 = OpCompositeExtract  %4  %503 1
%519 = OpCompositeExtract  %5  %518 0
OpLine %3 194 20
OpStore %468 %519
OpBranch %504
%509 = OpLabel
OpLine %3 195 37
%520 = OpCompositeExtract  %4  %503 1
%521 = OpCompositeExtract  %5  %520 1
OpLine %3 195 20
OpStore %468 %521
OpBranch %504
%510 = OpLabel
OpLine %3 196 37
%522 = OpCompositeExtract  %4  %503 1
%523 = OpCompositeExtract  %5  %522 2
OpLine %3 196 20
OpStore %468 %523
OpBranch %504
%511 = OpLabel
OpBranch %504
%504 = OpLabel
OpLine %3 200 15
%524 = OpAccessChain  %371  %466 %135 %135
%525 = OpLoad  %8  %524
%526 = OpUDiv  %8  %494 %525
%527 = OpIAdd  %8  %494 %526
OpLine %3 201 15
%528 = OpIAdd  %8  %527 %126
OpLine %3 202 15
%529 = OpAccessChain  %371  %466 %135 %135
%530 = OpLoad  %8  %529
%531 = OpIAdd  %8  %527 %530
OpLine %3 202 15
%532 = OpIAdd  %8  %531 %126
OpLine %3 203 15
%533 = OpIAdd  %8  %532 %126
OpLine %3 206 5
OpSelectionMerge %534 None
OpSwitch %495 %539 0 %535 3 %535 2 %536 4 %536 1 %537 5 %538
%535 = OpLabel
OpLine %3 207 24
OpStore %469 %527
OpBranch %534
%536 = OpLabel
OpLine %3 208 24
OpStore %469 %533
OpBranch %534
%537 = OpLabel
OpLine %3 209 20
OpStore %469 %532
OpBranch %534
%538 = OpLabel
OpLine %3 210 20
OpStore %469 %528
OpBranch %534
%539 = OpLabel
OpBranch %534
%534 = OpLabel
OpLine %3 213 13
%540 = OpCompositeExtract  %8  %454 0
OpLine %3 213 5
OpStore %469 %540
OpLine %3 222 27
%541 = OpLoad  %5  %468
%542 = OpBitcast  %8  %541
OpLine %3 223 12
%543 = OpLoad  %8  %469
%544 = OpCompositeConstruct  %22  %542 %543
%545 = OpCompositeExtract  %8  %544 0
OpStore %463 %545
%546 = OpCompositeExtract  %8  %544 1
OpStore %464 %546
OpReturn
OpFunctionEnd
%558 = OpFunction  %2  None %346
%547 = OpLabel
%551 = OpLoad  %4  %549
%553 = OpLoad  %4  %552
%548 = OpCompositeConstruct  %14  %551 %553
%560 = OpAccessChain  %559  %39 %135
OpBranch %561
%561 = OpLabel
OpLine %3 254 25
%563 = OpAccessChain  %562  %560 %126
%564 = OpLoad  %23  %563
%565 = OpCompositeExtract  %4  %548 0
OpLine %3 254 25
%566 = OpCompositeConstruct  %7  %565 %56
%567 = OpMatrixTimesVector  %7  %564 %566
OpLine %3 255 18
%568 = OpCompositeExtract  %4  %548 1
OpLine %3 256 12
%569 = OpCompositeExtract  %4  %548 0
%570 = OpCompositeConstruct  %26  %567 %568 %569
%571 = OpCompositeExtract  %7  %570 0
OpStore %554 %571
%572 = OpCompositeExtract  %4  %570 1
OpStore %555 %572
%573 = OpCompositeExtract  %4  %570 2
OpStore %557 %573
OpReturn
OpFunctionEnd
%583 = OpFunction  %2  None %346
%574 = OpLabel
%592 = OpVariable  %95  Function %593
%577 = OpLoad  %7  %576
%579 = OpLoad  %4  %578
%581 = OpLoad  %4  %580
%575 = OpCompositeConstruct  %26  %577 %579 %581
%584 = OpAccessChain  %559  %39 %135
%586 = OpAccessChain  %585  %42 %135
OpBranch %594
%594 = OpLabel
OpLine %3 278 28
OpLine %3 278 17
%595 = OpCompositeExtract  %4  %575 2
%596 = OpExtInst  %4  %1 Fract %595
%597 = OpExtInst  %4  %1 SmoothStep %80 %587 %596
OpLine %3 278 5
OpStore %592 %597
OpLine %3 279 17
OpLine %3 279 13
%598 = OpAccessChain  %125  %592 %135
%599 = OpLoad  %5  %598
%600 = OpAccessChain  %125  %592 %126
%601 = OpLoad  %5  %600
%602 = OpFMul  %5  %599 %601
%603 = OpAccessChain  %125  %592 %350
%604 = OpLoad  %5  %603
%605 = OpFMul  %5  %602 %604
%606 = OpCompositeConstruct  %4  %605 %605 %605
%607 = OpExtInst  %4  %1 FMix %589 %591 %606
OpLine %3 279 5
OpStore %592 %607
OpLine %3 282 25
%609 = OpAccessChain  %608  %586 %126
%610 = OpLoad  %4  %609
%611 = OpVectorTimesScalar  %4  %610 %272
OpLine %3 284 21
%612 = OpAccessChain  %608  %586 %135
%613 = OpLoad  %4  %612
%614 = OpCompositeExtract  %4  %575 2
%615 = OpFSub  %4  %613 %614
%616 = OpExtInst  %4  %1 Normalize %615
OpLine %3 285 20
%618 = OpAccessChain  %617  %584 %135
%619 = OpLoad  %7  %618
%620 = OpVectorShuffle  %4  %619 %619 0 1 2
%621 = OpCompositeExtract  %4  %575 2
%622 = OpFSub  %4  %620 %621
%623 = OpExtInst  %4  %1 Normalize %622
OpLine %3 286 20
%624 = OpFAdd  %4  %623 %616
%625 = OpExtInst  %4  %1 Normalize %624
OpLine %3 288 32
%626 = OpCompositeExtract  %4  %575 1
%627 = OpDot  %5  %626 %616
OpLine %3 288 28
%628 = OpExtInst  %5  %1 FMax %627 %74
OpLine %3 289 25
%629 = OpAccessChain  %608  %586 %126
%630 = OpLoad  %4  %629
%631 = OpVectorTimesScalar  %4  %630 %628
OpLine %3 291 37
%632 = OpCompositeExtract  %4  %575 1
%633 = OpDot  %5  %632 %625
OpLine %3 291 33
%634 = OpExtInst  %5  %1 FMax %633 %74
OpLine %3 291 29
%635 = OpExtInst  %5  %1 Pow %634 %323
OpLine %3 292 26
%636 = OpAccessChain  %608  %586 %126
%637 = OpLoad  %4  %636
%638 = OpVectorTimesScalar  %4  %637 %635
OpLine %3 294 18
%639 = OpFAdd  %4  %611 %631
%640 = OpFAdd  %4  %639 %638
%641 = OpLoad  %4  %592
%642 = OpFMul  %4  %640 %641
OpLine %3 296 12
%643 = OpCompositeConstruct  %7  %642 %56
OpStore %582 %643
OpReturn
OpFunctionEnd