我正在尝试在我的frag shader中渲染多个粒子,但是只显示了600个中的两个。有人能帮我理解发生了什么吗?
#version 120
uniform sampler2DRect texture2;
uniform float iTime;
uniform vec2 iResolution;
#define M_PI 3.1415926535897932384626433832795
float random(vec2 co){
float a = 12.9898;
float b = 78.233;
float c = 43758.5453;
float dt= dot(co.xy ,vec2(a,b));
float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
void main(void){
vec4 outColor = vec4(0.0, 0.0,0.0,1.0);
float time = iTime * 0.1;
vec2 uvNorm = gl_FragCoord.xy / iResolution.xy;
vec2 uv = -0.5 + 1.0 * uvNorm;
uv /= vec2(iResolution.y / iResolution.x, 1.);
for(float i=0.0; i<600.0 ;i++){
float f1 = mod(i * 0.101213, 0.28);
float fft = texture2DRect(texture2, vec2(f1)).x;
float r = (fft/10.0);
float a = random(vec2(i))*(M_PI*2.);
vec2 center = vec2(cos(a), sin(a)) * r/1.2;
float dist = length(uv - center);
float birghtness = 1./pow(0.01 + dist*250., 2.);
vec3 color = vec3(fft-0.1, 1.0, fft-0.2);
vec3 col = color* birghtness/2.0 * fft * 2.;
col += color * birghtness * fft * 1.5;
outColor.rgb += col;
}
gl_FragColor = outColor;
}
我对openGL相当新,我以前遇到过关于不同版本的openGL的一些问题。这可能类似吗?
答案 0 :(得分:2)
粒子聚集在一个小区域。将颗粒数量从600减少到例如50,你可以看到分离的粒子。
for(float i=0.0; i<50.0 ;i++){
....
此外,显示颗粒的区域非常小。缩放半径,以放大绘制粒子的区域:
vec2 uvNorm = gl_FragCoord.xy / iResolution.xy;
vec2 uv = (uvNorm - 0.5) * vec2(iResolution.x / iResolution.y, 1.0);
uv *= 0.3; // scale
请注意,您不会使用变量iTime
/ time
。这可能会导致粒子聚集在一起,因为您只显示初始状态
我不知道在初始算法中如何使用时间,因为您没有发布引用。但是我把它放在某个地方,看看代码片段中的结果:
var ShaderProgram = {};
ShaderProgram.Create = function( shaderList ) {
var shaderObjs = [];
for ( var i_sh = 0; i_sh < shaderList.length; ++ i_sh ) {
var shderObj = this.CompileShader( shaderList[i_sh].source, shaderList[i_sh].stage );
if ( shderObj == 0 )
return 0;
shaderObjs.push( shderObj );
}
var progObj = this.LinkProgram( shaderObjs )
if ( progObj != 0 ) {
progObj.attribIndex = {};
var noOfAttributes = gl.getProgramParameter( progObj, gl.ACTIVE_ATTRIBUTES );
for ( var i_n = 0; i_n < noOfAttributes; ++ i_n ) {
var name = gl.getActiveAttrib( progObj, i_n ).name;
progObj.attribIndex[name] = gl.getAttribLocation( progObj, name );
}
progObj.unifomLocation = {};
var noOfUniforms = gl.getProgramParameter( progObj, gl.ACTIVE_UNIFORMS );
for ( var i_n = 0; i_n < noOfUniforms; ++ i_n ) {
var name = gl.getActiveUniform( progObj, i_n ).name;
progObj.unifomLocation[name] = gl.getUniformLocation( progObj, name );
}
}
return progObj;
}
ShaderProgram.AttributeIndex = function( progObj, name ) { return progObj.attribIndex[name]; }
ShaderProgram.UniformLocation = function( progObj, name ) { return progObj.unifomLocation[name]; }
ShaderProgram.Use = function( progObj ) { gl.useProgram( progObj ); }
ShaderProgram.SetUniformI1 = function( progObj, name, val ) { if(progObj.unifomLocation[name]) gl.uniform1i( progObj.unifomLocation[name], val ); }
ShaderProgram.SetUniformF1 = function( progObj, name, val ) { if(progObj.unifomLocation[name]) gl.uniform1f( progObj.unifomLocation[name], val ); }
ShaderProgram.SetUniformF2 = function( progObj, name, arr ) { if(progObj.unifomLocation[name]) gl.uniform2fv( progObj.unifomLocation[name], arr ); }
ShaderProgram.CompileShader = function( source, shaderStage ) {
var shaderScript = document.getElementById(source);
if (shaderScript) {
source = "";
var node = shaderScript.firstChild;
while (node) {
if (node.nodeType == 3) source += node.textContent;
node = node.nextSibling;
}
}
var shaderObj = gl.createShader( shaderStage );
gl.shaderSource( shaderObj, source );
gl.compileShader( shaderObj );
var status = gl.getShaderParameter( shaderObj, gl.COMPILE_STATUS );
if ( !status ) alert(gl.getShaderInfoLog(shaderObj));
return status ? shaderObj : 0;
}
ShaderProgram.LinkProgram = function( shaderObjs ) {
var prog = gl.createProgram();
for ( var i_sh = 0; i_sh < shaderObjs.length; ++ i_sh )
gl.attachShader( prog, shaderObjs[i_sh] );
gl.linkProgram( prog );
status = gl.getProgramParameter( prog, gl.LINK_STATUS );
if ( !status ) alert("Could not initialise shaders");
gl.useProgram( null );
return status ? prog : 0;
}
var VertexBuffer = {};
VertexBuffer.Create = function( attributes, indices ) {
var buffer = {};
buffer.buf = [];
buffer.attr = []
for ( var i = 0; i < attributes.length; ++ i ) {
buffer.buf.push( gl.createBuffer() );
buffer.attr.push( { size : attributes[i].attrSize, loc : attributes[i].attrLoc } );
gl.bindBuffer( gl.ARRAY_BUFFER, buffer.buf[i] );
gl.bufferData( gl.ARRAY_BUFFER, new Float32Array( attributes[i].data ), gl.STATIC_DRAW );
}
buffer.inx = gl.createBuffer();
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, buffer.inx );
gl.bufferData( gl.ELEMENT_ARRAY_BUFFER, new Uint16Array( indices ), gl.STATIC_DRAW );
buffer.inxLen = indices.length;
gl.bindBuffer( gl.ARRAY_BUFFER, null );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null );
return buffer;
}
VertexBuffer.Draw = function( bufObj ) {
for ( var i = 0; i < bufObj.buf.length; ++ i ) {
gl.bindBuffer( gl.ARRAY_BUFFER, bufObj.buf[i] );
gl.vertexAttribPointer( bufObj.attr[i].loc, bufObj.attr[i].size, gl.FLOAT, false, 0, 0 );
gl.enableVertexAttribArray( bufObj.attr[i].loc );
}
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, bufObj.inx );
gl.drawElements( gl.TRIANGLES, bufObj.inxLen, gl.UNSIGNED_SHORT, 0 );
for ( var i = 0; i < bufObj.buf.length; ++ i )
gl.disableVertexAttribArray( bufObj.attr[i].loc );
gl.bindBuffer( gl.ARRAY_BUFFER, null );
gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, null );
}
var Texture = {};
Texture.HandleLoadedTexture2D = function( image, texture, flipY ) {
gl.activeTexture( gl.TEXTURE0 );
gl.bindTexture( gl.TEXTURE_2D, texture );
gl.texImage2D( gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image );
if ( flipY != undefined && flipY == true )
gl.pixelStorei( gl.UNPACK_FLIP_Y_WEBGL, true );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT );
gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT );
gl.bindTexture( gl.TEXTURE_2D, null );
return texture;
}
Texture.LoadTexture2D = function( name ) {
var texture = gl.createTexture();
texture.image = new Image();
texture.image.setAttribute('crossorigin', 'anonymous');
texture.image.onload = function () {
Texture.HandleLoadedTexture2D( texture.image, texture, true )
}
texture.image.src = name;
return texture;
}
var timing = {};
timing.prevTimeAbs = 0;
timing.pause = 0;
timing.deltaTimeLastMs = 0;
timing.deltaTimeAbsMs = 0;
timing.init = function() {
this.prevTimeAbs = Date.now();
this.pause = 0;
this.deltaTimeLastMs = 0;
this.deltaTimeAbsMs = 0;
};
timing.calcDeltaTimes = function() {
var currentTimeAbs = Date.now();
var delta = currentTimeAbs - this.prevTimeAbs;
this.prevTimeAbs = currentTimeAbs;
this.deltaTimeLastMs = this.pause == 0 ? delta : 0;
this.deltaTimeAbsMs += this.deltaTimeLastMs;
return this.deltaTimeAbsMs;
};
function drawScene(){
var canvas = document.getElementById( "camera-canvas" );
var vp = [canvas.width, canvas.height];
var pastTime = timing.calcDeltaTimes() / 1000.0;
gl.viewport( 0, 0, canvas.width, canvas.height );
gl.enable( gl.DEPTH_TEST );
gl.clearColor( 0.0, 0.0, 0.0, 1.0 );
gl.clear( gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT );
var texUnit = 0;
gl.activeTexture( gl.TEXTURE0 + texUnit );
gl.bindTexture( gl.TEXTURE_2D, textureObj );
ShaderProgram.Use( progDraw );
ShaderProgram.SetUniformF1( progDraw, "iTime", pastTime );
ShaderProgram.SetUniformF2( progDraw, "iResolution", vp );
ShaderProgram.SetUniformI1( progDraw, "texture2", texUnit );
VertexBuffer.Draw( bufRect );
}
var gl;
var prog;
var bufObj = {};
var textureObj;
var maskTextureObj;
function sceneStart() {
var canvas = document.getElementById( "camera-canvas");
gl = canvas.getContext( "experimental-webgl" );
//gl = canvas.getContext( "webgl2" );
if ( !gl )
return;
var texCX = 128;
var texCY = 128;
var texPlan = [];
for (ix = 0; ix < texCX; ++ix) {
for (iy = 0; iy < texCY; ++iy) {
var val_x = Math.sin( Math.PI * 6.0 * ix / texCX )
var val_y = Math.sin( Math.PI * 6.0 * iy / texCY )
texPlan.push( 128 + 127 * val_x, 63, 128 + 127 * val_y, 255 );
}
}
textureObj = Texture.LoadTexture2D( "https://raw.githubusercontent.com/Rabbid76/graphics-snippets/master/resource/texture/supermario.jpg" );
progDraw = ShaderProgram.Create(
[ { source : "draw-shader-vs", stage : gl.VERTEX_SHADER },
{ source : "draw-shader-fs", stage : gl.FRAGMENT_SHADER }
] );
progDraw.inPos = gl.getAttribLocation( progDraw, "inPos" );
if ( prog == 0 )
return;
bufRect = VertexBuffer.Create(
[ { data : [ -1, -1, 1, -1, 1, 1, -1, 1 ], attrSize : 2, attrLoc : progDraw.inPos } ],
[ 0, 1, 2, 0, 2, 3 ] );
timing.init();
setInterval(drawScene, 50);
}
<script id="draw-shader-vs" type="x-shader/x-vertex">
precision mediump float;
attribute vec2 inPos;
varying vec2 vertPos;
void main()
{
vertPos = inPos;
gl_Position = vec4( inPos, 0.0, 1.0 );
}
</script>
<script id="draw-shader-fs" type="x-shader/x-fragment">
precision mediump float;
varying vec2 vertPos;
uniform float iTime;
uniform vec2 iResolution;
uniform sampler2D texture2;
#define M_PI 3.1415926535897932384626433832795
float random(vec2 co){
float a = 12.9898;
float b = 78.233;
float c = 43758.5453;
float dt= dot(co.xy ,vec2(a,b));
float sn= mod(dt,3.14);
return fract(sin(sn) * c);
}
void main(void){
vec4 outColor = vec4(0.0, 0.0,0.0,1.0);
float time = iTime * 0.1;
vec2 uvNorm = gl_FragCoord.xy / iResolution.xy;
vec2 uv = (uvNorm - 0.5) * vec2(iResolution.x / iResolution.y, 1.0);
uv *= 0.25; // scale
//for(float i=0.0; i<600.0 ;i++){
for(float i=0.0; i<30.0 ;i++){
float f1 = mod(sin(time) * i * 0.101213, 0.28);
float fft = texture2D(texture2, vec2(f1)).x;
float r = (fft/10.0);
float a = random(vec2(i,i))*(M_PI*2.);
vec2 center = vec2(cos(a), sin(a)) * r/1.2;
float dist = length(uv - center);
float birghtness = 1./pow(0.01 + dist*250., 2.);
vec3 color = vec3(fft-0.1, 1.0, fft-0.2);
vec3 col = color* birghtness/2.0 * fft * 2.;
col += color * birghtness * fft * 1.5;
outColor.rgb += col;
}
gl_FragColor = outColor;
}
</script>
<body onload="sceneStart();">
<canvas id="camera-canvas" style="border: none;" width="512" height="512"></canvas>
</body>