0
$\begingroup$

I wanna implement shadows example fromwebgl2fundamentals

also i a aware of framebuffer principe a have already working implementation of mirror projection.

Ignore VS extra vars .

I have trouble with shadows examples...

I always get black collor or error logs :

GL_INVALID_OPERATION: Feedback loop formed between Framebuffer and active Texture.

My scene have two cubes. Onefloor andmyTextCube1 on top.

I added flagobject.shadows.FBO_IN_DRAW_PASS.

This is most important code from draw function:DRAWER:

 ...if(object.FBO && object.shadows.FBO_IN_DRAW_PASS == true) {    // test FBO    let textureMatrix = m4.identity();    textureMatrix = m4.translate(textureMatrix, 0.5, 0.5, 0.5);    textureMatrix = m4.scale(textureMatrix, 0.5, 0.5, 0.5);    textureMatrix = m4.multiply(textureMatrix,                      object.shadows.lightProjectionMatrix);    const lightWorldMatrix = m4.lookAt(        [ object.shadows.lightPosition[0],          object.shadows.lightPosition[1],          object.shadows.lightPosition[2]        ],        [object.shadows.lightTarget[0] ,         object.shadows.lightTarget[1] ,          object.shadows.lightTarget[2]          ], // target        [object.shadows.orientation[0], object.shadows.orientation[1], object.shadows.orientation[2]], // up            );    textureMatrix = m4.multiply(textureMatrix,               m4.inverse(lightWorldMatrix));    const mat = m4.multiply(lightWorldMatrix,               m4.inverse(object.shadows.lightProjectionMatrix));    // draw to the depth texture    world.GL.gl.uniform1i(object.shaderProgram.u_projectedTexture, false, 0);            world.GL.gl.uniformMatrix4fv(object.shaderProgram.u_textureMatrix, false, textureMatrix);            world.GL.gl.uniform3fv(object.shaderProgram.lightWorldPositionLocation, object.shadows.lightPosition);                world.GL.gl.uniformMatrix4fv(object.shaderProgram.u_world, false,                m4.translate(object.position.worldLocation[0],                    object.position.worldLocation[1],                    object.position.worldLocation[2])            );            // world.GL.gl.uniformMatrix4fv(object.shaderProgram.u_world, false, mat);            world.GL.gl.uniform3fv(object.shaderProgram.u_reverseLightDirection, lightWorldMatrix.slice(8, 11));            world.GL.gl.uniform1f(object.shaderProgram.u_bias, object.shadows.bias);            //  console.log('LOG FBO TEXT ACTIVATE')            world.GL.gl.activeTexture(world.GL.gl.TEXTURE0);            world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.FBO.deepTexture);            world.GL.gl.uniform1i(object.shaderProgram.u_projectedTexture, 0);        } else {      // console.log('normal tex')            for(var t = 0;t < object.textures.length;t++) {                if(object.custom.gl_texture == null) {                    world.GL.gl.activeTexture(world.GL.gl['TEXTURE' + t]);                    world.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.textures[t]);                    world.GL.gl.pixelStorei(world.GL.gl.UNPACK_FLIP_Y_WEBGL, false);                    if(object.texParams.MIPMAP == false) {                        world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_S, object.texParams.TEXTURE_WRAP_S | world.GL.gl.REPEAT);                        world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_WRAP_T, object.texParams.TEXTURE_WRAP_T | world.GL.gl.REPEAT);                        // -- Allocate storage for the texture                        // world.GL.gl.texStorage2D(world.GL.gl.TEXTURE_2D, 1, world.GL.gl.RGB8, 512, 512);                        // world.GL.gl.texSubImage2D(world.GL.gl.TEXTURE_2D, 0, 0, 0,512, 512, world.GL.gl.RGB, world.GL.gl.UNSIGNED_BYTE, object.textures[t]);                    } else {                        world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MAG_FILTER, object.texParams.TEXTURE_MAG_FILTER | world.GL.gl.LINEAR);                        world.GL.gl.texParameteri(world.GL.gl.TEXTURE_2D, world.GL.gl.TEXTURE_MIN_FILTER, object.texParams.TEXTURE_MIN_FILTER | world.GL.gl.LINEAR);                        world.GL.gl.generateMipmap(world.GL.gl.TEXTURE_2D);                    }                    if(world.GL.extTFAnisotropic && object.texParams.ANISOTROPIC == true) {                        world.GL.gl.texParameterf(world.GL.gl.TEXTURE_2D,                            world.GL.extTFAnisotropic.TEXTURE_MAX_ANISOTROPY_EXT,                            world.GL.MAX_TEXTURE_MAX_ANISOTROPY_EXT);                    }                    world.GL.gl.uniform1i(object.shaderProgram.samplerUniform, t);                    world.GL.gl.uniform1i(object.shaderProgram.u_projectedTexture, 0);                } else {                    object.custom.gl_texture(object, t);                }            }        } ...
export const makeFBO2 = (gl, o) => {    if(typeof o === 'undefined') {        var o = {width: 512,    height: 512};    }    var error = function() {console.log('Error in creating FBO!'); return null;}    var gl = world.GL.gl;    const depthTexture = gl.createTexture();    const depthTextureSize = 512;    gl.bindTexture(gl.TEXTURE_2D, depthTexture);    gl.texImage2D(        gl.TEXTURE_2D,      // target        0,                  // mip level        gl.DEPTH_COMPONENT32F, // internal format        depthTextureSize,   // width        depthTextureSize,   // height        0,                  // border        gl.DEPTH_COMPONENT, // format        gl.FLOAT,           // type        null);              // data    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);    const depthFramebuffer = gl.createFramebuffer();    gl.bindFramebuffer(gl.FRAMEBUFFER, depthFramebuffer);    gl.framebufferTexture2D(        gl.FRAMEBUFFER,       // target        gl.DEPTH_ATTACHMENT,  // attachment point        gl.TEXTURE_2D,        // texture target        depthTexture,         // texture        0);                   // mip level    return [depthFramebuffer, depthTexture];}

And also importan part of code is render:RENDER

          world.GL.gl.bindFramebuffer(world.GL.gl.FRAMEBUFFER, world.FBOS[fbindex].FB);        world.GL.gl.viewport(0, 0, 512, 512);        world.GL.gl.clearColor(0.0, 1.0, 0.4, 1.0);        world.GL.gl.clear(world.GL.gl.COLOR_BUFFER_BIT | world.GL.gl.DEPTH_BUFFER_BIT);        world.GL.gl.enable(world.GL.gl.DEPTH_TEST);        world.GL.gl.enable(world.GL.gl.CULL_FACE);        world.GL.gl.disable(world.GL.gl.BLEND);    // - draw all `non fbo` and `no blend`    if(                                (world.contentList[looper].visible === true &&                !world.contentList[looper].FBO &&                world.contentList[looper].glBlend.blendEnabled == false)                  ||                 (world.contentList[looper].visible === true &&                    world.contentList[looper].shadows.FBO_IN_DRAW_PASS == false &&                    world.contentList[looper].glBlend.blendEnabled == false)            ) {                    world.GL.gl.useProgram(world.contentList[looper].shaderProgram);                    world.drawCube(world.contentList[looper], 'noray');                    world.contentList[looper].shadows.FBO_IN_DRAW_PASS = true;}    world.GL.gl.bindFramebuffer(world.GL.gl.FRAMEBUFFER, null);    // All but no blend        world.GL.gl.useProgram(world.contentList[looper].shaderProgram);                world.contentList[looper].shadows.FBO_IN_DRAW_PASS = true;                world.drawCube(world.contentList[looper]);                world.animate(world.contentList[looper]);                world.contentList[looper].shadows.FBO_IN_DRAW_PASS = false;END OF REDER FUNCApp.operation.CameraPerspective = function() {    this.GL.gl.viewport(0, 0, canvas.width, canvas.height);    this.GL.gl.clear(this.GL.gl.COLOR_BUFFER_BIT | this.GL.gl.DEPTH_BUFFER_BIT);    mat4.perspective(this.pMatrix, degToRad(App.camera.viewAngle), this.GL.gl.viewportWidth / this.GL.gl.viewportHeight, App.camera.nearViewpoint, App.camera.farViewpoint);}

And after all shaders part:

export function generateSpotLightShadowDefinitions() {    return `// inject generateSpotLightShadowDefinitions    uniform sampler2D u_projectedTexture;    uniform sampler2D u_texture;    in vec2 v_texcoord;    uniform float u_bias;    in vec4 v_projectedTexcoord;    in vec3 v_surfaceToLight;    in vec3 v_surfaceToView;    uniform vec4 u_color;    uniform float u_shininess;    uniform vec3 u_lightDirection;    uniform float u_innerLimit;    uniform float u_outerLimit;    uniform mat4 u_projection;    uniform mat4 u_view;    uniform mat4 u_world;    uniform mat4 u_textureMatrix;    uniform vec3 u_reverseLightDirection;    `;}export function generateSpotLightShadowMain() {    return `    vec3 normal = normalize(v_normal);    float light = dot(normal, u_reverseLightDirection);    vec3 projectedTexcoord = v_projectedTexcoord.xyz / v_projectedTexcoord.w;    float currentDepth = projectedTexcoord.z + u_bias;    bool inRange =            projectedTexcoord.x >= 0.0 &&            projectedTexcoord.x <= 1.0 &&            projectedTexcoord.y >= 0.0 &&            projectedTexcoord.y <= 1.0;    float projectedDepth = texture(u_projectedTexture, projectedTexcoord.xy).r;    float shadowLight = (inRange && projectedDepth <= currentDepth) ? 0.0 : 1.0;    vec4 texColor = texture(u_texture, v_texcoord) * vec4(1, 1, 1, 1);    outColor = vec4(texColor.rgb * light * shadowLight , texColor.a);    `;}

VS GLSL:

export function getInitVSCubeTexLight() {  const f = `#version 300 es  in vec3 aVertexPosition;  in vec3 aVertexNormal;  in vec2 aTextureCoord;  uniform mat4 uMVMatrix;  uniform mat4 uPMatrix;  uniform mat3 uNMatrix;  uniform vec3 uAmbientColor;  uniform vec3 uLightingDirection;  uniform vec3 uDirectionalColor;  uniform bool uUseLighting;  out vec2 vTextureCoord;  out vec3 vLightWeighting;  out vec3 meVertexPosition;  uniform vec3 u_lightWorldPosition;  out vec3 v_normal;  out vec3 v_surfaceToLight;  out vec3 v_surfaceToView;  out mat4 uMVMatrixINTER;  out mat3 uNMatrixINTER;  out mat4 uPMatrixINNTER;  in vec4 specularColor;  out vec4 vColor;  out vec3 vNormal;  out vec4 vPosition;  out float vDist;  uniform mat4 u_textureMatrix;  out vec2 v_texcoord;  out vec4 v_projectedTexcoord;  uniform mat4 u_world;  void main(void) {    meVertexPosition = aVertexPosition;    uMVMatrixINTER = uMVMatrix;    uNMatrixINTER = uNMatrix;    uPMatrixINNTER = uPMatrix;    vColor = specularColor;    vNormal = normalize(mat3(u_world) * vec3(aVertexNormal));     vPosition =  uMVMatrix * vec4(aVertexPosition, 1.0);    vDist = gl_Position.w;    v_normal = uNMatrix  *  vec3(aVertexNormal);    vec3 surfaceWorldPosition = (uNMatrix * aVertexPosition).xyz;    v_surfaceToLight = u_lightWorldPosition - surfaceWorldPosition;    v_surfaceToView = (uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0)).xyz - surfaceWorldPosition;    vec4 worldPosition =     vec4((uNMatrix * aVertexPosition).xyz, 1.0);    v_texcoord = aTextureCoord;   v_projectedTexcoord = u_textureMatrix * worldPosition;    gl_Position   = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);    vTextureCoord = aTextureCoord;    if (!uUseLighting) {      vLightWeighting = vec3(1.0, 1.0, 1.0);    } else {      vec3 transformedNormal          = uNMatrix * aVertexNormal;      float directionalLightWeighting = max(dot(transformedNormal, uLightingDirection), 0.0);      vLightWeighting                 = uAmbientColor + uDirectionalColor * directionalLightWeighting;    }  }`;    scriptManager.LOAD(f, "cubeLightTex-shader-vs", "x-shader/x-vertex", "shaders")}

enter image description here

Any suggestion?Looks like every cube for itself cast shadow no between cast...

If you wanna live demos of my library you can explore ithere.

UPDATE:

I found athttps://www.youtube.com/watch?v=0Xk96uN3Ceo&ab_channel=SketchpunkLabson 24:00 minute

drawBuffers(gl.NONE)readBuffer(gl.NONE)

I must try this lines...

Source code :github

FULL RENDER

askedDec 30, 2024 at 18:18
Nikola Lukic's user avatar
$\endgroup$
3
  • 1
    $\begingroup$Your question is too long; try to identify and reduce unnecessary details. I have two questions about your code: (1) why isexport const makeFBO2 = (gl, o) but you callmakeFBO2 in the following way:makeFBO2(object, world.GL.gl )? (2) Can you make sure that when one of theworld.FBOS[fbindex].FB is bound to the frame buffer, it's not simultaneously bound to a texture and got sampled (like hereworld.GL.gl.bindTexture(world.GL.gl.TEXTURE_2D, object.FBO.FB.texture);)?$\endgroup$CommentedDec 31, 2024 at 2:57
  • $\begingroup$You are right - i will fix & update question i still have trouble...$\endgroup$CommentedDec 31, 2024 at 9:34
  • $\begingroup$@Enigmatisms I updated Q. Only most importan code is here. Thnks for help!$\endgroup$CommentedDec 31, 2024 at 11:44

0

Know someone who can answer? Share a link to thisquestion viaemail,Twitter, orFacebook.

Your Answer

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.