Loading External Shaders Using THREE.JS

时光怂恿深爱的人放手 提交于 2019-12-13 08:50:05

问题


I am trying to make a THREE.JS scene with GLSL shaders applied, but am having trouble figuring out how to make it load my shaders. The scene appears to work, but the shaders don't do what they're supposed to. I'm using a shader loader function I found that uses pure THREE.JS instead of AJAX or Jquery.

Here is the main javascript for my scene.

var container,
	renderer,
	scene,
	camera, 
	light,
	mesh,
	controls,
	start = Date.now(),
	fov = 30;

window.addEventListener( 'load', function() {

	container = document.getElementById( "container" ); 

	if(!Detector.webgl) {
		Detector.addGetWebGLMessage(container);
		return;
	}

	//get the width and height
	var WIDTH = window.innerWidth,
		HEIGHT = window.innerHeight;

	//sphere params
	var radius = 20,
		segments = 4,
		rotation = 6;

	scene = new THREE.Scene();

	//											  ASPECT RATIO
	camera = new THREE.PerspectiveCamera(fov, WIDTH / HEIGHT, 1, 10000);
	camera.position.z = 100;

	scene.add(new THREE.AmbientLight(0x333333));

	light = new THREE.DirectionalLight(0xffffff, 1);
	light.position.set(100, 3, 5);
	scene.add(light);

	;
	
	ShaderLoader('./shaders/vertex.vert', './shaders/fragment.frag')
	
	material = new THREE.ShaderMaterial( {
			uniforms: {
				tExplosion: {
					type: "t",
					value: THREE.ImageUtils.loadTexture( 'images/explosion.png' )
				},
				time: {	//float initialized to 0
					type: "f",
					value: 0.0
				}
			},
			vertexShader: ShaderLoader.vertex_text,
			fragmentShader: ShaderLoader.fragment_text
	} );

	mesh = new THREE.Mesh( 
		new THREE.IcosahedronGeometry( radius, segments ),
		material
		);
	scene.add( mesh );

	renderer = new THREE.WebGLRenderer();
	renderer.setSize( WIDTH, HEIGHT );
	renderer.setPixelRatio( window.devicePixelRatio );

	
	//update renderer size, aspect ratio, and projectionmatrix, on resize
	window.addEventListener('resize', function() {
		var WIDTH = window.innerWidth,
			HEIGHT = window.innerHeight;

		renderer.setSize(WIDTH, HEIGHT);

		camera.aspect = WIDTH / HEIGHT;
		camera.updateProjectionMatrix();
	});
	
	controls = new THREE.TrackballControls( camera );

	container.appendChild( renderer.domElement );

	render();

} );

function render() {	
		material.uniforms[ 'time' ].value = .00025 * ( Date.now() - start );
		controls.update();
		requestAnimationFrame( render );
		renderer.render(scene, camera);
}

// This is a basic asyncronous shader loader for THREE.js.
function ShaderLoader(vertex_url, fragment_url, onLoad, onProgress, onError) {
    var vertex_loader = new THREE.XHRLoader(THREE.DefaultLoadingManager);
    vertex_loader.setResponseType('text');
    vertex_loader.load(vertex_url, function (vertex_text) {
        var fragment_loader = new THREE.XHRLoader(THREE.DefaultLoadingManager);
        fragment_loader.setResponseType('text');
        fragment_loader.load(fragment_url, function (fragment_text) {
            onLoad(vertex_text, fragment_text);
        });
    }, onProgress, onError);
}
	

But when my scene loads, it is just a red sphere with no lighting or applied shaders... What am I doing wrong? I'm new to all of this so it is probably something easily noticeable for someone more experienced, but I have searched and searched and been experimenting and can't figure it out.

Thanks!


回答1:


Try to add material.needsUpdate = true after you load your shader.




回答2:


The snippet show error of the WebGL detector. Are you loading that library? https://github.com/mrdoob/three.js/blob/master/examples/js/Detector.js



来源:https://stackoverflow.com/questions/45134352/loading-external-shaders-using-three-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!