Opengl es 如何在外部文件中移动着色器脚本?
我想知道如何将html中实际包含的着色器移动到外部文件中。这样,我就可以将它们包含在我的吞咽任务中。我了解了JavaScript着色器文件是如何编写的,但我不太了解 例如,使用下面的光晕着色器代码,如何将其移动到外部文件Opengl es 如何在外部文件中移动着色器脚本?,opengl-es,three.js,shader,Opengl Es,Three.js,Shader,我想知道如何将html中实际包含的着色器移动到外部文件中。这样,我就可以将它们包含在我的吞咽任务中。我了解了JavaScript着色器文件是如何编写的,但我不太了解 例如,使用下面的光晕着色器代码,如何将其移动到外部文件 <script type="x-shader/x-vertex" id="vertexShaderGlow"> uniform vec3 viewVector; uniform float c; uniform float p; va
<script type="x-shader/x-vertex" id="vertexShaderGlow">
uniform vec3 viewVector;
uniform float c;
uniform float p;
varying float intensity;
void main()
{
vec3 vNormal = normalize( normalMatrix * normal );
vec3 vNormel = normalize( normalMatrix * viewVector );
intensity = pow( c - dot(vNormal, vNormel), p );
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
</script>
<script type="x-shader/x-vertex" id="fragmentShaderGlow">
uniform vec3 glowColor;
varying float intensity;
void main()
{
vec3 glow = glowColor * intensity;
gl_FragColor = vec4( glow, 1.0 );
}
</script>
均匀vec3视向量;
均匀浮点数c;
均匀浮动p;
浮动强度变化;
void main()
{
vec3 vNormal=规格化(normalMatrix*normal);
vec3 vNormel=规格化(normalMatrix*viewVector);
强度=功率(c-点(vNormal,vNormal),p);
gl_位置=projectionMatrix*modelViewMatrix*vec4(位置,1.0);
}
颜色均匀;
浮动强度变化;
void main()
{
vec3发光=发光颜色*强度;
gl_FragColor=vec4(辉光,1.0);
}
您可以将着色器代码移动到单独的JS文件中,并在三个.JS之后包含该文件。这里有一个例子 根据以上内容,您可以创建如下材料:
material = new THREE.ShaderMaterial({
uniforms : THREE.ColorifyShader.uniforms,
vertexShader : THREE.ColorifyShader.vertexShader,
fragmentShader : THREE.ColorifyShader.fragmentShader
});
当然,您不需要调用对象
THREE.ColorifyShader
,您可以随意调用它。您可以将着色器代码移动到单独的JS文件中,并在THREE.JS之后包含该文件。这里有一个例子 根据以上内容,您可以创建如下材料:
material = new THREE.ShaderMaterial({
uniforms : THREE.ColorifyShader.uniforms,
vertexShader : THREE.ColorifyShader.vertexShader,
fragmentShader : THREE.ColorifyShader.fragmentShader
});
当然,您不需要调用对象
THREE.ColorifyShader
,您可以随意调用它。提供的另一个答案是简单地使用GLSL代码并将每一行转换为字符串。每个字符串都是数组中的一个值。join
调用将所有字符串与\n
字符连接起来,以使调试时代码更易于阅读。我以前曾多次这样做过,这是一个合理的解决方案,可以解决您试图做的事情
但如果您希望使用原始GLSL代码创建外部文件,也可以这样做。考虑这两个文件:
- glow_vertex.glsl
- glow_fragment.glsl
var vertexShader = null;
var fragmentShader = null;
function shadersDone(){
var material = new THREE.ShaderMaterial({
uniforms: { /* define your uniforms */},
vertexShader: vertexShader,
fragmentShader: fragmentShader
});
}
function vertexDone(code){
vertexShader = code;
if(fragmentShader !== null){
shadersDone();
}
}
function fragmentDone(code){
fragmentShader = code;
if(vertexShader !== null){
shadersDone();
}
}
var xhr1 = new XMLHttpRequest();
var xhr2 = new XMLHttpRequest();
xhr1.open("GET", "/server/glow_vertex.glsl", true);
xhr2.open("GET", "/server/glow_fragment.glsl", true);
xhr1.responseType = "text";
xhr2.responseType = "text";
xhr1.onload = function(){
if(xhr1.readyState === xhr1.DONE && xhr1.status === 200){
vertexDone(xhr1.resultText);
}
};
xhr2.onload = function(){
if(xhr2.readyState === xhr2.DONE && xhr2.status === 200){
fragmentDone(xhr2.resultText);
}
};
xhr1.send(null);
xhr2.send(null);
注意,这都是异步的。此外,您的服务器需要配置为以纯文本形式发送GLSL文件
只要我们谈论的是现代网络……
还可以选择导入着色器代码非常大,但目前仅在Chrome和Opera中受支持(尽管PolyFill确实存在)。Microsoft Edge将该功能列为“正在考虑中”,Firefox不会缩进以在其当前状态下实现该功能。因此,用一大粒盐来吃下面的东西,并注意:
在HTML中,在使用它的JavaScript之前
<link id="vertexImport" rel="import" href="/server/glow_vertex.glsl" />
<link id="fragmentImport" rel="import" href="/server/glow_fragment.glsl" />
同样,这是异步的。您可能需要为每个链接添加一个
onload
处理程序,以便在加载代码之前不尝试访问代码。提供的另一个答案是简单地获取GLSL代码并将每一行转换为字符串。每个字符串都是数组中的一个值。join
调用将所有字符串与\n
字符连接起来,以使调试时代码更易于阅读。我以前曾多次这样做过,这是一个合理的解决方案,可以解决您试图做的事情
但如果您希望使用原始GLSL代码创建外部文件,也可以这样做。考虑这两个文件:
- glow_vertex.glsl
- glow_fragment.glsl
var vertexShader = null;
var fragmentShader = null;
function shadersDone(){
var material = new THREE.ShaderMaterial({
uniforms: { /* define your uniforms */},
vertexShader: vertexShader,
fragmentShader: fragmentShader
});
}
function vertexDone(code){
vertexShader = code;
if(fragmentShader !== null){
shadersDone();
}
}
function fragmentDone(code){
fragmentShader = code;
if(vertexShader !== null){
shadersDone();
}
}
var xhr1 = new XMLHttpRequest();
var xhr2 = new XMLHttpRequest();
xhr1.open("GET", "/server/glow_vertex.glsl", true);
xhr2.open("GET", "/server/glow_fragment.glsl", true);
xhr1.responseType = "text";
xhr2.responseType = "text";
xhr1.onload = function(){
if(xhr1.readyState === xhr1.DONE && xhr1.status === 200){
vertexDone(xhr1.resultText);
}
};
xhr2.onload = function(){
if(xhr2.readyState === xhr2.DONE && xhr2.status === 200){
fragmentDone(xhr2.resultText);
}
};
xhr1.send(null);
xhr2.send(null);
注意,这都是异步的。此外,您的服务器需要配置为以纯文本形式发送GLSL文件
只要我们谈论的是现代网络……
还可以选择导入着色器代码非常大,但目前仅在Chrome和Opera中受支持(尽管PolyFill确实存在)。Microsoft Edge将该功能列为“正在考虑中”,Firefox不会缩进以在其当前状态下实现该功能。因此,用一大粒盐来吃下面的东西,并注意:
在HTML中,在使用它的JavaScript之前
<link id="vertexImport" rel="import" href="/server/glow_vertex.glsl" />
<link id="fragmentImport" rel="import" href="/server/glow_fragment.glsl" />
同样,这是异步的。您可能需要为每个链接添加一个
onload
处理程序,这样您就不会在加载代码之前尝试访问代码。建议加入一个glsl行数组的答案是一种三行可能会遇到的模式,但在本用例中可能应该避免
它在某种模块中可能很有用,在这种模块中,它是某种着色器的“编译”快照,不打算修改
否则,这种方法的主要缺点是缺少语法突出显示和冗长
现在大多数js代码都是以这种或那种方式转换的。着色器代码应该像这样内联
const myShader = new THREE.ShaderMaterial({
vertexShader: require('./myVert.vs'),
fragmentShader: require('./myFrag.vs'),
})
编辑
myVert.vs:
//this is all nicely highlighted in sublime text for example
void main (){
gl_Position = vec4( position.xy, 0., 1.);
}
myVert.fs:
void main (){
gl_FragColor = vec4(1.,0.,0.,1.);
}
myClass.js:
class myMaterial extends THREE.ShaderMaterial{
constructor(){
super({
vertexShader: require('./myVert.vs'),
//^ becomes vertexShader: 'void main() {...}'
...
建议连接一组glsl线的答案是三条线可以遇到的模式,但在本用例中可能应该避免 它在某种模块中可能很有用,在这种模块中,它是某种着色器的“编译”快照,不打算修改 否则,这种方法的主要缺点是缺少语法突出显示和冗长 现在大多数js代码都是以这种或那种方式转换的。着色器代码应该像这样内联
const myShader = new THREE.ShaderMaterial({
vertexShader: require('./myVert.vs'),
fragmentShader: require('./myFrag.vs'),
})
编辑
myVert.vs:
//this is all nicely highlighted in sublime text for example
void main (){
gl_Position = vec4( position.xy, 0., 1.);
}
myVert.fs:
void main (){
gl_FragColor = vec4(1.,0.,0.,1.);
}
myClass.js:
class myMaterial extends THREE.ShaderMaterial{
constructor(){
super({
vertexShader: require('./myVert.vs'),
//^ becomes vertexShader: 'void main() {...}'
...
您只需要将着色器代码作为字符串,因此可以使用任何允许您从外部文件引入字符串的方法