IE 11 Texture not rendering in ASP.NET MVC Application

I realize this probably isn’t a ThreeJS problem, the only reason I want this to work in IE 11 is because that is what everyone in our work environment uses(sadly)… but is there anyone out there that maybe has run into the same issue? Anyone that has been using Three JS within an ASP.Net application? When I check console, I see warnings… but i don’t know why that would have anything to do with my texture not rendering. You can see that the scene renders fine, but you can’t see the earth texture image. The warnings I see in console:

Here is what it looks like at runtime: (You can see the labels that I have added on top of the sphere/earth, just not the earth itself)

Anyone know anything that I can check? Here is the main JS code:
//Define namespace
var EarthView3D = EarthView3D || {};

//THREE JS setup variables
var camera, scene, renderer, labelRenderer, earth;

$(document).ready(function () {

EarthView3D.GetSites(); // This must run before initializing EarthView, Init() is called in success property of ajax call.

}); /* END DOCUMENT READY */

EarthView3D.GetSites = function () {
$.ajax({
    url: basePath + 'EarthView3D/GetSites',
    type: 'GET',
    dataType: 'html',
    cache: false,
    success: function (data) {
        // Set the siteObjects, defined at the top of this file.
        var siteObjects = JSON.parse(data);
        EarthView3D.Init(siteObjects, EarthView3D.Animate);
    },
    error: function (jqXHR, textStatus, errorThrown) {
        alert('Error retrieving site coordinates for earth view.');
    },
    complete: function (jqXHR, textStatus) {

    }
});
};

EarthView3D.ViewSite = function (_siteID) {
$('#loading').show();
$.ajax({
    url: basePath + 'EarthView3D/ViewSite',
    type: 'GET',
    dataType: 'html',
    data: { siteID: _siteID },
    cache: false,
    success: function (data) {
        $('#earth_view_site_modal').html(data).modal('show');
    },
    error: function (jqXHR, textStatus, errorThrown) {
        alert('Error retrieving site info');
    },
    complete: function (jqXHR, textStatus) {
        $('#loading').hide();
    }
});
};

EarthView3D.Init = function (siteObjects, animateCallback) {

const EARTH_RADIUS = 225;
const EARTH_SEGMENTS = 75;
const EARTH_RINGS = 75;

camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 2000); //-87 pixels for header and dev environment bar.
camera.position.set(-70, 375, 500);
scene = new THREE.Scene();

var light = new THREE.PointLight(0xffffff, 1, Infinity);
camera.add(light);

scene.add(camera);

// Starfield
var starGeometry = new THREE.SphereGeometry(1000, 50, 50); //basically creates another sphere around the earth's sphere, and covers it in starfield image.
var starMaterial = new THREE.MeshPhongMaterial({
    map: new THREE.ImageUtils.loadTexture(basePath + 'Content/images/galaxy_starfield.png'),
    side: THREE.DoubleSide,
    shininess: 0
});
var starField = new THREE.Mesh(starGeometry, starMaterial);
scene.add(starField);

// Create group to hold sphere and texture, makes up the earth.
earth = new THREE.Group();
scene.add(earth);

//paths to each of the texture images.
var earthNoCloudsTex = basePath + 'Content/images/earth_no_clouds_12k.jpg';
var earthDarkTex = basePath + 'Content/images/earth_dark_12k.jpg';
var earthDarkInvertTex = basePath + 'Content/images/earth_dark_invert_12k.jpg';
var earthRedTex = basePath + 'Content/images/earth_dark_red_12k.jpg';

// Flag for current texture that is displaying
var currentTexture = earthNoCloudsTex;

//for loading earth texture images.
var loader = new THREE.TextureLoader();

// Instantiate material to later be wrapped around the sphere.
var material = new THREE.MeshBasicMaterial();
// Create the sphere
var sphere = new THREE.SphereGeometry(EARTH_RADIUS, EARTH_SEGMENTS, EARTH_RINGS);
// Instantiate mesh to later combine sphere with material
var mesh;

loader.load(currentTexture, function (texture) {
    // Map the texture to the material. 
    material = new THREE.MeshBasicMaterial({
        map: texture
    });
    // Create a new mesh with sphere geometry.
    mesh = new THREE.Mesh(sphere, material);
    // Add mesh to globe
    earth.add(mesh);
});

scene.add(earth);

//Add toggle click event for changing earth background texture
$('.texture_change_button').on("click", function (e) {
    //figure out which button was clicked
    var buttonClicked = $(this).attr('id');
    //disable all currently disabled buttons before disabling another
    $(":disabled").attr('disabled', false);
    //disable button clicked so that it can't be clicked twice.
    $(this).attr('disabled', true);
    //depending on the id of the buttonClicked, update the currentTexture
    switch (buttonClicked) {
        case 'earth_no_clouds_button':
            currentTexture = earthNoCloudsTex;
            break;
        case 'earth_dark_button':
            currentTexture = earthDarkTex;
            break;
        case 'earth_dark_invert_button':
            currentTexture = earthDarkInvertTex;
            break;
        case 'earth_red_button':
            currentTexture = earthRedTex;
    }
    //switch out the image with new currentTexture
    loader.load(currentTexture, function (texture) {
        //this actually updates the image
        material.map = texture;
        earth.add(mesh);
    });
});

// Add siteObjects to Earth
for (var i = 0; i < siteObjects.length; i++) {

    var siteID = siteObjects[i].SiteID;
    var name = siteObjects[i].Name;
    var desc = siteObjects[i].Description;
    var lat = siteObjects[i].LAT;
    var lon = siteObjects[i].LON;
    var status = siteObjects[i].Status;

    // Create dot for each site
    var siteDiv = document.createElement('div');
    siteDiv.setAttribute("id", name);

    //set data attributes to later use when clicking dot.
    siteDiv.setAttribute("data-siteid", siteID);
 
    siteDiv.setAttribute("title", name);
    siteDiv.classList = status.toLowerCase() == "fmc" ? "site_status fmc" :
                        status.toLowerCase() == "pmc" ? "site_status pmc" :
                                                        "site_status nmc";

    //Create label to append to each site's dot
    var siteDivLabel = document.createElement('label');
    siteDivLabel.setAttribute("id", name + '_label');
    siteDivLabel.setAttribute("title", name + ' label');
    siteDivLabel.textContent = name;

    //Setting the label's class (Some labels need to display on different sides of the dot so that all can be seen in initial view.)
    if (siteID == 6 || siteID == 9) { // 6 is BUckley, 9 is COD
        siteDivLabel.className = 'label_top_right earth_view_label';
    } else if (siteID == 12 || siteID == 20 || siteID == 19) { // 12 is FGA, 20 is PAFB, 19 is MDIOC
        siteDivLabel.className = 'label_bottom_right earth_view_label';
    } else if (siteID == 8) { // 8 is CMD
        siteDivLabel.className = 'label_bottom_left earth_view_label';
    } else {
        siteDivLabel.className = 'label_top_left earth_view_label';
    }
    siteDiv.appendChild(siteDivLabel);

    var siteDot = new THREE.CSS2DObject(siteDiv);

    siteDiv.parent = siteDot;

    siteDot.element.style.cursor = "pointer";

    // Add click event for each dot/label that takes them to the site section for the dashboard homepage.
    siteDot.element.onclick = function () {
        var siteSK = $(this).data('siteid');

        EarthView3D.ViewSite(siteSK);
    };

    var sitePosition = EarthView3D.CalcPosFromLatLonRad(lat, lon, EARTH_RADIUS);

    // Some code to slightly move certain site markers around from their original position so that they don't overlap each other too much.
    if (siteID == 5) { // 5 is boulder
        siteDot.position.set(sitePosition[0] - 1, sitePosition[1] + 1, Math.abs(sitePosition[2]));
    } else if (siteID == 8) { // 8 is CMD
        siteDot.position.set(sitePosition[0] - 1, sitePosition[1] - 1, Math.abs(sitePosition[2]));
    } else if (siteID == 20) { // 20 is PAFB
        siteDot.position.set(sitePosition[0] + 1, sitePosition[1] - 6, Math.abs(sitePosition[2]));
    } else if (siteID == 19) { // 19 is MDIOC
        siteDot.position.set(sitePosition[0] + 5, sitePosition[1] + 4, Math.abs(sitePosition[2]));
    } else if (siteID == 6) { // 6 is Buckley
        siteDot.position.set(sitePosition[0] + 2, sitePosition[1] + 3, Math.abs(sitePosition[2]));
    } else {
        siteDot.position.set(sitePosition[0], sitePosition[1], Math.abs(sitePosition[2]));
    }
    earth.add(siteDot);
}

renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor(0xffffff, 0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
var earthContainer = document.getElementById('earth_container');
earthContainer.appendChild(renderer.domElement);

labelRenderer = new THREE.CSS2DRenderer();
labelRenderer.setSize(window.innerWidth, window.innerHeight);
labelRenderer.domElement.style.position = 'absolute';
labelRenderer.domElement.style.top = 0;
document.body.appendChild(labelRenderer.domElement);

// For rotation and mouse controls
var controls = new THREE.OrbitControls(camera, labelRenderer.domElement);
controls.minDistance = 400;
controls.maxDistance = 800;
animateCallback(siteObjects); //Running Animate right after Init.
};

/* Referenced from answer found here:
https://stackoverflow.com/questions/28365948/javascript-latitude-longitude-to-xyz-position-on-earth-threejs
*/
EarthView3D.CalcPosFromLatLonRad = function (lat, lon, radius) {

var phi = (90 - lat) * (Math.PI / 180)
var theta = (lon + 180) * (Math.PI / 180)

x = -((radius) * Math.sin(phi) * Math.cos(theta))
z = ((radius) * Math.sin(phi) * Math.sin(theta))
y = ((radius) * Math.cos(phi))

return [x, y, z];
};

EarthView3D.Animate = function () {
//earth.rotation.y -= .0004; - Rotation was causing shaking of markers/labels, so commented out.
requestAnimationFrame(EarthView3D.Animate);
renderer.render(scene, camera);
labelRenderer.render(scene, camera);
};

Also, if my starfield texture is rendering just fine in IE11… Why can my earth texture not render? They both create a sphere and then wrap the texture around sphere… The only difference is my starfield uses the deprecated THREE.ImageUtils.loadTexture() function, and earth uses TextureLoader(), and creates a group. Maybe the group is what messes it up? I am going to try and take the earth texture and sphere and all that out of the group, and do it just like the starfield. I will keep everyone updated.

I have fixed this issue by using the deprecated way of loading a texture:

THREE.ImageUtils.loadTexture()

Instead of using:

THREE.TextureLoader()

As well as no longer grouping everything, just adding it straight to the scene (I like this better anyways)

My textures now load in IE 11 Version 11.1039.17763.0 and all other browsers. WHEW!

2 Likes