我试图用粒子来显示3D场景中飘落的雪花。
我不想在HTML页面中创建着色器,因为我的项目不允许添加特定脚本,并且许多其他脚本都是动态加载的,不包括在<script src=''>
的HTML页面中。
我收到了下一个错误(简称:http://pastebin.com/KqiZze49,已满:http://pastebin.com/LZHhCnuh):
THREE.WebGLShader: Shader couldn't compile. three.min.js:592(anonymous function)
three.min.js:592(anonymous function) three.min.js:588initMaterial three.min.js:566z
three.min.js:488renderBuffer three.min.js:544v three.min.js:483render
three.min.js:556Rekod3DBuildings.Engine.renderScene rekod3d-new.js:668
(anonymous function) new-index.html:71
THREE.WebGLShader: gl.getShaderInfoLog() ERROR: 0:68: 'gl_FragColor' : undeclared identifier
ERROR: 0:68: 'assign' : cannot convert from '4-component vector of float' to 'float'
ERROR: 0:68: 'gl_PointCoord' : undeclared identifier
ERROR: 0:68: 'texture2D' : no matching overloaded function found
你可以告诉我&#34;男人,看看控制台,你在控制台中得到了所有错误,只是google。&#34; 但是,奇怪的是,如果使用相同的着色器,这些着色器在JavaScript中动态生成,但在HTML页面中用作准备好的部分,则没有错误,结果是:
正如您在上面的屏幕截图中所示,如果着色器包含在HTML页面中,则没有错误。 当然,从逻辑上讲,你想告诉我,显然我在JavaScript中没有正确地创建着色器,但也有一些奇怪的东西,让我们看看:
1)。我如何在JavaScript中生成着色器?
Rekod3DBuildings.Engine.prototype.createVertexShaderForSnowParticles = function( scriptId ) {
if ( typeof scriptId === 'string' ) {
var script = document.createElement( 'script' );
script.id = scriptId;
script.type = 'x-shader/x-vertex';
script.textContent = '\
attribute float size;\
attribute float time;\
attribute vec3 customColor;\
uniform float globalTime;\
varying vec3 vColor;\
varying float fAlpha;\
\
void main() {\
vColor = customColor;\
vec3 pos = position;\
float localTime = time + globalTime;\
float modTime = mod( localTime, 1.0 );\
float accTime = modTime * modTime;\
pos.x += cos( modTime * 8.0 + ( position.z ) ) * 70.0;\
pos.z += sin( modTime * 6.0 + ( position.x ) ) * 100.0;\
fAlpha = ( pos.z ) / 1800.0;\
vec3 animated = vec3( pos.x, pos.y * accTime, pos.z );\
vec4 mvPosition = modelViewMatrix * vec4( animated, 1.0 );\
gl_PointSize = min( 150.0, size * ( 150.0 / length( mvPosition.xyz ) ) );\
gl_Position = projectionMatrix * mvPosition;\
}';
document.head.appendChild( script );
return script;
}
else
console.error( 'Script id for the vertex shader isn\'t a type of `string`.' );
};
Rekod3DBuildings.Engine.prototype.createFragmentShaderForSnowParticles = function( scriptId ) {
if ( typeof scriptId === 'string' ) {
var script = document.createElement( 'script' );
script.id = scriptId;
script.type = 'x-shader/x-fragment';
script.textContent = '\
uniform vec3 color;\
uniform sampler2D texture;\
varying vec3 vColor;\
varying float fAlpha;\
\
void main() {\
gl_FragColor = vec4( color * vColor, fAlpha );\
gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );\
}';
document.head.appendChild( script );
return script;
}
else
console.error( 'Script id for the fragment shader isn\'t a type of `string`.' );
};
2)。创建它们之后,我们是否添加了它们的检查?
查看屏幕截图,成功添加了着色器:
源代码,正在准备粒子(http://pastebin.com/HgLHJWFu):
Rekod3DBuildings.Engine.prototype.setSnowParticles = function() {
var map = THREE.ImageUtils.loadTexture( 'images/textures/snowflake.png' );
var attributes = {
size: { type: 'f', value: [] },
customColor: { type: 'c', value: [] },
time: { type: 'f', value: [] },
};
this.snowUniforms = {
color: { type: "c", value: new THREE.Color( 0x777777 ) },
texture: { type: "t", value: 0, texture: map },
globalTime: { type: "f", value: 0.0 },
};
var shaderMaterial = new THREE.ShaderMaterial( {
uniforms: this.snowUniforms,
attributes: attributes,
vertexShader: document.getElementById( 'fragmentshader-airplane' ).textContent,
fragmentShader: document.getElementById( 'vertexshader-airplane' ).textContent,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true,
});
var geometry = new THREE.Geometry();
for ( var i = 0; i < 10000; i++ )
geometry.vertices.push( new THREE.Vector3( Math.random() * 18000 - 1500, -5000, Math.random() * 18000 ) );
var particles = new THREE.PointCloud( geometry, shaderMaterial );
particles.position.x = -5000;
particles.position.y = 5000;
particles.position.z = -5000;
var vertices = particles.geometry.vertices;
var values_size = attributes.size.value;
var values_color = attributes.customColor.value;
var values_time = attributes.time.value;
for( var v = 0; v < vertices.length; v++ ) {
values_size[ v ] = 50 + Math.random() * 80;
values_color[ v ] = new THREE.Color( 0xffffff );
values_time[ v ] = Math.random();
}
this.scene.add( particles );
};
那么,出了什么问题?
请帮我提一些建议。
答案 0 :(得分:2)
在屏幕截图中读取代码片段,您将片段着色器文本加载到顶点着色器中,反之亦然,因此来自着色器编译器的gl_FragColor错误。我很确定逆转这些将有很大帮助。 : - )
答案 1 :(得分:0)
你真的需要通过DOM吗?
我可以用这种方式动态创建着色器
THREE.SlicedBoxGeometry.prototype.GetVertexShader = function() {
var r = "";
r+= "uniform vec4 uClipPlane1; \n";
r+= "uniform vec4 uClipPlane2; \n";
r+= "uniform vec4 uClipPlane3; \n";
r+= "varying vec3 vPos; \n";
r+= "void main() \n";
r+= "{ \n";
r+= " vec3 newPosition = position; \n";
r+= " if (position.x == " + this.width_half.toFixed(2) + " ) { \n";
r+= " newPosition.x = - uClipPlane1.w / uClipPlane1.x; \n";
r+= " } \n";
r+= " if (position.y == " + this.height_half.toFixed(2) + ") { \n";
r+= " newPosition.y = - uClipPlane2.w / uClipPlane2.y; \n";
r+= " } \n";
r+= " if (position.z == " + this.depth_half.toFixed(2) + ") { \n";
r+= " newPosition.z = - uClipPlane3.w / uClipPlane3.z; \n";
r+= " } \n";
r+= " gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );\n";
r+= " vPos = newPosition; \n";
r+= "}\n";
return r;
}
可能不是更好的方法,但它有效...
将着色器放在DOM中的唯一原因就在于
<script type="something-not-javascript" id="someId">
shader code goes here
</script>
然后您可以使用
检索它var shaderSource = document.getElementById("someId").text
你把它放在DOM中,因为你可以编辑它而不必用引号括起每一行......
否则,如果您要将它放在JavaScript中,那么上面的格式或类似的内容也可以使用
THREE.SlicedBoxGeometry.prototype.GetVertexShader = function() {
return [
"uniform vec4 uClipPlane1; ",
"uniform vec4 uClipPlane2; ",
"uniform vec4 uClipPlane3; ",
"varying vec3 vPos; ",
"",
"",
"void main() ",
"{ ",
" vec3 newPosition = position; ",
" if (position.x == " + this.width_half.toFixed(2) + " ) { ",
" newPosition.x = - uClipPlane1.w / uClipPlane1.x; ",
" } ",
" if (position.y == " + this.height_half.toFixed(2) + ") { ",
" newPosition.y = - uClipPlane2.w / uClipPlane2.y; ",
" } ",
" if (position.z == " + this.depth_half.toFixed(2) + ") { ",
" newPosition.z = - uClipPlane3.w / uClipPlane3.z; ",
" } ",
" gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );",
" vPos = newPosition; ",
"}",
].join("¥n");
};