Recently, I delved into the world of WebGL by starting to work through a book titled "WebGL: Up and Running". This book utilizes my preferred rendering solution, THREE.js, for creating 3D objects in web browsers. One section of the book caught my attention - it introduced shaders to create a dynamic, lit sun. However, when I attempted to replicate this using the provided shader code, all I ended up with was a black sphere. Surprisingly, when I switched to a simpler shader like a Lambert shader, everything worked as expected. It seems that the issue lies within the implementation of the complex shader.
I'm scratching my head trying to figure out where I went wrong. Here is the JavaScript code snippet I used to set up the scene:
var renderer, scene, camera, sunMesh, clock, uniforms;
$(function(){
//set scene size
var WIDTH = 1200,
HEIGHT = 800;
//set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');
// create a WebGL renderer, camera
// and a scene
renderer = new THREE.WebGLRenderer();
camera = new THREE.PerspectiveCamera( VIEW_ANGLE,
ASPECT,
NEAR,
FAR );
scene = new THREE.Scene();
// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
// attach the render-supplied DOM element
$container.append(renderer.domElement);
// Create a group to hold our sun mesh and light
var sunGroup = new THREE.Object3D();
var SUNMAP = "./images/lavatile.jpg";
var NOISEMAP = "./images/cloud.png";
uniforms = {
time: { type: "f", value: 1.0 },
texture1: { type: "t", value: 0, texture: THREE.ImageUtils.loadTexture( NOISEMAP ) },
texture2: { type: "t", value: 1, texture: THREE.ImageUtils.loadTexture( SUNMAP ) }
};
uniforms.texture1.texture.wrapS = uniforms.texture1.texture.wrapT = THREE.Repeat;
uniforms.texture2.texture.wrapS = uniforms.texture2.texture.wrapT = THREE.Repeat;
var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: document.getElementById( 'vertexShader' ).textContent,
fragmentShader: document.getElementById( 'fragmentShader' ).textContent
} );
var geometry = new THREE.SphereGeometry(50, 64, 64);
sunMesh = new THREE.Mesh( geometry, material );
clock = new THREE.Clock();
var light = new THREE.PointLight( 0xffffff );
light.position.set(0,0,100);
sunGroup.add(sunMesh);
sunGroup.add(light);
scene.add(sunGroup);
scene.add(camera);
renderer.render(scene, camera);
setInterval(gameloop, 50);
});
function gameloop() {
var delta = clock.getDelta();
uniforms.time.value += delta;
renderer.render(scene, camera);
}
I have uploaded the full HTML code here, which includes the shaders obtained from the WebGL book source. While there is a chance that these shaders are incorrect, I am leaning towards the possibility that my usage of the shaders might be flawed. My expectation was to see a sun with textures changing based on a noise occlusion map, accompanied by movement in the vertex position to emulate a pulsating effect. Unfortunately, all I can see is an unlit, black sphere.
Any insights on where I might have made a mistake?