Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Sec3Engine/demos/ParticleDemo.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,11 @@ function startDemo() {
SEC3ENGINE.run(gl);
}

function webGLStart() {
function webGLStart() {

canvas = document.getElementById("glcanvas");
initGL(canvas);
canvas = document.getElementById("glcanvas");
SEC3.canvas = canvas;
initGL(canvas);

camera = SEC3ENGINE.createCamera(CAMERA_TRACKING_TYPE);
camera.goHome([0.0, 0.0, 10.0]);
Expand Down
123 changes: 88 additions & 35 deletions Sec3Engine/js/core/ParticleSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,39 @@ SEC3.createParticleSystem = function(specs) {

var renderProgram;
var stepProgram;
var interactor = {};
interactor.attractor = [ -13.0, 6.0, 1.0, 1.0 ];
var self = {};
var interactor = {};
interactor.attractor = [ -13.0, 6.0, 1.0, 1.0 ];
var self = {};

// Helpers to safely access optional scene and camera globals used by legacy demos.
var getActiveCamera = function() {
if (typeof scene !== "undefined" && scene.getCamera) {
return scene.getCamera();
}
if (typeof camera !== "undefined") {
return camera;
}
return null;
};

var getActiveLight = function() {
if (typeof scene !== "undefined" && scene.getLight && scene.getNumLights && scene.getNumLights() > 0) {
return scene.getLight(0);
}
return null;
};

//----------------------------------------------------------------METHODS:


var update = function() {
var update = function() {

stepParticles();
updateShadowMap(scene.getLight(0));
};
stepParticles();
var activeLight = getActiveLight();
if (activeLight) {
updateShadowMap(activeLight);
}
};

var draw = function( light ) {
renderParticles( light );
Expand Down Expand Up @@ -96,21 +117,28 @@ SEC3.createParticleSystem = function(specs) {

gl.vertexAttribPointer(stepProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(stepProgram.aVertexPosition);
var center = vec3.clone(scene.getCamera().getPosition());
var offset = vec3.clone(camera.normal);
vec3.scale(offset, offset, -6.0);
vec3.add(center, center, offset);
gl.uniform4f(stepProgram.uAttractor, center[0], center[1], center[2], 0.4 );
var activeCamera = getActiveCamera();
if (activeCamera) {
var center = vec3.clone(activeCamera.getPosition());
var offset = vec3.clone(activeCamera.normal);
vec3.scale(offset, offset, -6.0);
vec3.add(center, center, offset);
gl.uniform4f(stepProgram.uAttractor, center[0], center[1], center[2], 0.4 );
}

gl.drawArrays(gl.TRIANGLES, 0, 6);
}

/*
* draws current scene into shadow map
*/
var updateShadowMap = function ( light ) {
var updateShadowMap = function ( light ) {

if (!light || !light.cascadeFramebuffers || !light.cascadeFramebuffers[0]) {
return;
}

var fbo = light.cascadeFramebuffers[0];
var fbo = light.cascadeFramebuffers[0];
gl.colorMask(false,false,false,false);
gl.useProgram(self.shadowProgram.ref());
gl.viewport(0, 0, fbo.getWidth(), fbo.getHeight());
Expand Down Expand Up @@ -139,30 +167,49 @@ SEC3.createParticleSystem = function(specs) {
/*
* Draws all particles in system
*/
var renderParticles = function ( light ) {
var renderParticles = function ( light ) {

light = light || getActiveLight();
if (!light || !light.cascadeFramebuffers || !light.cascadeFramebuffers[0]) {
return;
Comment on lines +170 to +174
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge renderParticles bails out when no light is present

The new guard in renderParticles returns whenever no light with cascade framebuffers is found, but particleDemo.html/Sec3Engine/demos/ParticleDemo.js never create a light and drawScene calls system.draw() without passing one. In that scenario getActiveLight() yields null, this guard trips, and the demo never issues any draw calls, leaving the canvas blank even though the rest of the setup succeeds. Rendering should handle the no-light case instead of exiting early or the demo needs to provide a light.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

@lyonsno lyonsno Nov 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@codex If the light isn't being added, why was this working originally?

}

gl.useProgram(self.renderProgram.ref());
gl.viewport(0, 0, SEC3.canvas.width, SEC3.canvas.height );


gl.uniform3fv(renderProgram.uLightPosition, light.getPosition());
gl.uniform3fv(renderProgram.uCPosLoc, scene.getCamera().getPosition());

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, positionTextures[srcIndex]);
gl.uniform1i( renderProgram.uParticlePositions, 0);

gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, SEC3.gBuffer.depthTexture() );
gl.uniform1i( renderProgram.uGDepthLoc, 1 );

gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, light.cascadeFramebuffers[0].depthTexture() );
gl.uniform1i(renderProgram.uShadowMap, 2);

gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, light.getMVP() );
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, scene.getCamera().getMVP());
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition() );
if (light) {
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition());
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniform3fv(renderProgram.uCPosLoc, activeCamera.getPosition());
}

gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, positionTextures[srcIndex]);
gl.uniform1i( renderProgram.uParticlePositions, 0);

if (SEC3.gBuffer && SEC3.gBuffer.depthTexture) {
gl.activeTexture( gl.TEXTURE1 );
gl.bindTexture( gl.TEXTURE_2D, SEC3.gBuffer.depthTexture() );
gl.uniform1i( renderProgram.uGDepthLoc, 1 );
}

if (light) {
gl.activeTexture(gl.TEXTURE2);
gl.bindTexture(gl.TEXTURE_2D, light.cascadeFramebuffers[0].depthTexture() );
gl.uniform1i(renderProgram.uShadowMap, 2);

gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, light.getMVP() );
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, activeCamera.getMVP());
}
if (light) {
gl.uniform3fv(renderProgram.uLightPosition, light.getPosition() );
}
//bind the default frame buffer, disable depth testing and enable alpha blending
finalFBO.bind(gl);

Expand Down Expand Up @@ -293,8 +340,14 @@ SEC3.createParticleSystem = function(specs) {
renderProgram.uShadowMultiply = gl.getUniformLocation(renderProgram.ref(), "uShadowMultiply");
renderProgram.uScale = gl.getUniformLocation(renderProgram.ref(), "uScale");
gl.useProgram(renderProgram.ref());
gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, scene.getLight(0).getMVP());
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, scene.getCamera().getMVP());
var activeLight = getActiveLight();
if (activeLight) {
gl.uniformMatrix4fv(renderProgram.uShadowMapTransform, false, activeLight.getMVP());
}
var activeCamera = getActiveCamera();
if (activeCamera) {
gl.uniformMatrix4fv(renderProgram.uCameraTransform, false, activeCamera.getMVP());
}
gl.uniform2fv( renderProgram.uScreenSizeLoc, vec2.fromValues(SEC3.canvas.width, SEC3.canvas.height ));
gl.uniform1f(renderProgram.uLuminence, self.luminence);
gl.uniform1f(renderProgram.uAlpha, self.RGBA[3]);
Expand Down
16 changes: 13 additions & 3 deletions Sec3Engine/js/core/camera.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@
//SEC3 is a core function interface
var SEC3 = SEC3 || {};

// Camera type constants expected by legacy demos.
var CAMERA_EXPLORING_TYPE = 0;
var CAMERA_TRACKING_TYPE = 1;

SEC3.Camera = function(){

SEC3.PerspProjector.call( this );

};

SEC3.Camera.prototype = Object.create( SEC3.PerspProjector.prototype );

SEC3.Camera.prototype = Object.create( SEC3.PerspProjector.prototype );

// Convenience factory used by demo pages.
SEC3.createCamera = function(/* type */){
// Only one camera type is implemented; ignore the requested type for now.
return new SEC3.Camera();
};
24 changes: 17 additions & 7 deletions particleDemo.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@
<title>Sec3 Particle Demo</title>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<!-- glMatrix version 2.2.0 -->
<script type="text/javascript" src="/Sec3Engine/js/math/gl-matrix.js"></script>
<script src="Sec3Engine/js/core/ParticleSystem.js" type="text/javascript"></script>
<script type="text/javascript" src="/Sec3Engine/js/math/gl-matrix.js"></script>
<script src="Sec3Engine/js/core/SceneObject.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/projector.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/PerspProjector.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/ParticleSystem.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/shader-util.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/webgl-util.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/camera.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/cameraInteractor.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/particleInteractor.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/texture.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/extensions.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/geometry.js" type ="text/javascript"></script>
<script src="/Sec3Engine/js/math/UI.js" type="text/javascript"></script>
<script src="/Sec3Engine/js/math/math.js" type="text/javascript"></script>
<script src="ParticleSystem/ParticleDemo.js" type="text/javascript"></script>
<script src="Sec3Engine/js/core/extensions.js" type ="text/javascript"></script>
<script src="Sec3Engine/js/core/geometry.js" type ="text/javascript"></script>
<script src="/Sec3Engine/js/math/UI.js" type="text/javascript"></script>
<script src="/Sec3Engine/js/math/math.js" type="text/javascript"></script>
<script type="text/javascript">
// Legacy demos expect the engine API under the SEC3ENGINE name.
// Merge any helpers attached to the old namespace (for example
// ParticleInteractor) and expose the combined API under both names.
SEC3ENGINE = Object.assign(SEC3, SEC3ENGINE || {});
SEC3 = SEC3ENGINE;
</script>
<script src="Sec3Engine/demos/ParticleDemo.js" type="text/javascript"></script>

</head>

Expand Down