This example uses OpenLayers v10.9.0. The latest is v.
Edit

#### Multiple COG sources

cog 15 webgl 18 projection 14 reprojection 8

#####

Red channel
Green channel
Blue channel

Displaying two Sentinel 2 COGs with different projections

Two Sentinel 2 COGs each with sources for visible red, green and blue bands, and a near-infrared band. The adjacent regions are at the edge of their respective UTM zones so at least one COG must be reprojected to be displayed on the same map.

##### main.js

    import Map from 'ol/Map.js';
    import {createEmpty, extend, getCenter} from 'ol/extent.js';
    import TileLayer from 'ol/layer/WebGLTile.js';
    import {transformExtent} from 'ol/proj.js';
    import {register} from 'ol/proj/proj4.js';
    import GeoTIFF from 'ol/source/GeoTIFF.js';
    import proj4 from 'proj4';

    proj4.defs('EPSG:32631', '+proj=utm +zone=31 +datum=WGS84 +units=m +no_defs');
    proj4.defs('EPSG:32632', '+proj=utm +zone=32 +datum=WGS84 +units=m +no_defs');
    register(proj4);

    const channels = ['red', 'green', 'blue'];
    for (const channel of channels) {
      const selector = document.getElementById(channel);
      selector.addEventListener('change', update);
    }

    function getVariables() {
      const variables = {};
      for (const channel of channels) {
        const selector = document.getElementById(channel);
        variables[channel] = parseInt(selector.value, 10);
      }
      return variables;
    }

    const sourceNames = ['B04', 'B03', 'B02', 'B08'];
    const sources = [
      new GeoTIFF({
        sources: sourceNames.map(function (name) {
          return {
            url: `https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/31/T/GJ/2022/7/S2A_31TGJ_20220703_0_L2A/${name}.tif`,
            max: 3000,
          };
        }),
      }),
      new GeoTIFF({
        sources: sourceNames.map(function (name) {
          return {
            url: `https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/32/T/LP/2022/7/S2A_32TLP_20220703_0_L2A/${name}.tif`,
            max: 3000,
          };
        }),
      }),
    ];

    const layer = new TileLayer({
      sources: sources,
      style: {
        variables: getVariables(),
        color: [
          'array',
          ['band', ['var', 'red']],
          ['band', ['var', 'green']],
          ['band', ['var', 'blue']],
          ['band', 5],
        ],
      },
    });

    function update() {
      layer.updateStyleVariables(getVariables());
    }

    const map = new Map({
      target: 'map',
      layers: [layer],
      view: Promise.all(
        sources.map(function (source) {
          return source.getView();
        }),
      ).then(function (options) {
        const projection = 'EPSG:3857';
        const extent = createEmpty();
        options.forEach(function (options) {
          extend(
            extent,
            transformExtent(options.extent, options.projection, projection),
          );
        });
        return {
          projection: projection,
          center: getCenter(extent),
          zoom: 0,
          extent: extent,
        };
      }),
    });

##### index.html

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <title>Multiple COG sources</title>
        <link rel="stylesheet" href="node_modules/ol/ol.css">
        <style>
          .map {
            width: 100%;
            height: 400px;
          }
          .controls {
            display: grid;
            grid-template-columns: auto auto 1fr;
            align-items: baseline;
            gap: 0 1em;
          }
        </style>
      </head>
      <body>
        <div id="map" class="map"></div>
        <div class="controls">
          <label for="red">Red channel</label>
          <select id="red">
            <option value="1" selected>visible red</option>
            <option value="2">visible green</option>
            <option value="3">visible blue</option>
            <option value="4">near infrared</option>
          </select>
          <label></label>

          <label for="green">Green channel</label>
          <select id="green">
            <option value="1">visible red</option>
            <option value="2" selected>visible green</option>
            <option value="3">visible blue</option>
            <option value="4">near infrared</option>
          </select>
          <label></label>

          <label for="blue">Blue channel</label>
          <select id="blue">
            <option value="1">visible red</option>
            <option value="2">visible green</option>
            <option value="3" selected>visible blue</option>
            <option value="4">near infrared</option>
          </select>
          <label></label>
        </div>

        <script type="module" src="main.js"></script>
      </body>
    </html>

##### package.json

    {
      "name": "multiple-cogs",
      "dependencies": {
        "ol": "10.9.0",
        "proj4": "2.20.8"
      },
      "devDependencies": {
        "vite": "^3.2.3"
      },
      "scripts": {
        "start": "vite",
        "build": "vite build"
      }
    }