forked from CS559/CS559-Framework23
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshaderHelper.js
115 lines (105 loc) · 3.02 KB
/
shaderHelper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*jshint esversion: 11 */
// @ts-check
//import THREE from "three";
/**
* Simplified creation of Shader Material for CS559 Framework
*
* The "shaderMaterial" function creates a THREE shader material
* given URLs for the vertex and fragment shader.
*
* It work asynchronously - it gives simple shaders until the
* real ones load.
*
* There are potentially issues if the fragment shader
* ends up getting compiled before the vertex shader.
*
* @module shaderHelper
*/
import * as T from "../CS559-Three/build/three.module.js";
// this takes an object that describes a shader material and adds the
// shader code (if provided) to it.
// if the shader code is not there, it gives a default shader
const defaultVertexShader = `
void main()
{
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
`;
const defaultFragmentShader = `
void main()
{
gl_FragColor = vec4(0.4,0.4,0.6,1);
}
`;
const errorFragmentShader = `
void main()
{
gl_FragColor = vec4(0.8,0.4,0.4,1);
}
`;
/**
*
* @param {string} url
* @param {THREE.ShaderMaterial} material
*/
function loadFragmentShader(url, material) {
const loader = new T.FileLoader();
loader.load(
url,
/* onload = */ function(data) {
material.fragmentShader = data.toString();
material.needsUpdate = true;
},
/* onprogress = */ function(xhr) {},
/* onerror = */ function(err) {
console.log(`Failed to Load Shader (file:${url})`);
console.log(`Error: ${err}`);
material.fragmentShader = errorFragmentShader;
material.needsUpdate = true;
}
);
}
/**
*
* @param {string} url
* @param {THREE.ShaderMaterial} material
*/
function loadVertexShader(url, material) {
const loader = new T.FileLoader();
loader.load(
url,
/* onload = */ function(data) {
material.vertexShader = data.toString();
material.needsUpdate = true;
},
/* onprogress = */ function(xhr) {},
/* onerror = */ function(err) {
console.log(`Failed to Load Shader (file:${url})`);
console.log(`Error: ${err}`);
material.fragmentShader = errorFragmentShader;
material.needsUpdate = true;
}
);
}
/**
* Create a Shader Material from a set of shader files
* Creates the material with default shaders, and async loads the
* shaders from file and swaps them in when they are ready.
*
* @param {string} vertexShaderURL
* @param {string} fragmentShaderURL
* @param {THREE.ShaderMaterialParameters} [properties]
* @returns {THREE.ShaderMaterial}
*/
export function shaderMaterial(vertexShaderURL, fragmentShaderURL, properties = {}) {
const sm = new T.ShaderMaterial(properties);
// create a default shader until the real ones load
sm.vertexShader = defaultVertexShader;
sm.fragmentShader = defaultFragmentShader;
sm.needsUpdate = true;
// these will be loaded asynchronously
loadVertexShader(vertexShaderURL, sm);
loadFragmentShader(fragmentShaderURL, sm);
// the material is ready for use, even if it has the default shader
return sm;
}