【发布时间】:2014-10-25 19:48:50
【问题描述】:
我正在尝试使用粒子在 3D 场景中显示飘落的雪花。
我不想在 HTML 页面中创建着色器,因为我的项目不允许添加特定脚本,并且许多其他脚本正在动态加载,不包括在 HTML 页面中作为<script src=''>。
我收到下一个错误(短: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
您可以告诉我“伙计,看看控制台,您在控制台中发现了所有错误,只需 google。” 但是,奇怪的是,如果使用相同的着色器,它们在 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 );
};
那么,怎么了?
请帮我提个建议。
【问题讨论】:
标签: javascript three.js glsl webgl shader