Shadow calculation coordinates, buffered

Shadows are generated once per mesh instance. Although the dynamic parameter is marked for light.

  • The light remains rendered at the default values ​​used by the material.

Initialize material, set default value:

    private _bindDependenciesToMaterial(material: pc.StandardMaterial) {
        
        material.setAttribute(vertexCoordAttrName, TerrainPatchesBasic.SEMANTIC_COORD_ATTR);
        material.setAttribute(vertexHeightAttrName, pc.SEMANTIC_POSITION);
        material.setAttribute(vertexNormalAttrName, pc.SEMANTIC_NORMAL);

        // Init params by default
        material.setParameter(useBaseVertexAttrName, this.useBaseVertex ? 1 : 0);
        material.setParameter(coordXOffsetAttrName, 0);
        material.setParameter(coordZOffsetAttrName, 0);

        const chunksStore = terrainShaderChunks;
        const chunkNames  = Object.keys(chunksStore);

        for (let chunkName of chunkNames) {
            material.chunks[chunkName] = chunksStore[chunkName];
        }

        material.chunks.APIVersion = pc.CHUNKAPI_1_70;
        material.update();
    }
protected _createPatchMesh(patchIndex: number, app: pc.AppBase, entity: pc.Entity, material: pc.Material): pc.MeshInstance {

        ...

        const patchMeshInstance = new pc.MeshInstance(patchMesh, material, entity);

        patchMeshInstance.visible = false;
        patchMeshInstance.visibleThisFrame = false;

        // Overwriting the material parameters
        patchMeshInstance.setParameter(useBaseVertexAttrName, this.useBaseVertex ? 1 : 0);
        patchMeshInstance.setParameter(coordXOffsetAttrName, patchBuf.minX);
        patchMeshInstance.setParameter(coordZOffsetAttrName, patchBuf.minZ);

        return patchMeshInstance;
    }

Shader chunk: transformVS:

    mat4 getModelMatrix()
    {
        return matrix_model;
    }
    
    vec2 getXZWithoutScale() {

        float x, z;

        if (${useBaseVertexAttrName} == 1.0) {
            x = float(${vertexCoordAttrName}.x);
            z = float(${vertexCoordAttrName}.y);
        } else {
            x = float(${vertexCoordAttrName}.x) + ${coordXOffsetAttrName};
            z = float(${vertexCoordAttrName}.y) + ${coordZOffsetAttrName};
        }
        
        return vec2(x, z);
    }

    vec2 getXZ() {

        float x, z;

        if (${useBaseVertexAttrName} == 1.0) {
            x = float(${vertexCoordAttrName}.x) * uWorldScale;
            z = float(${vertexCoordAttrName}.y) * uWorldScale;
        } else {
            x = (float(${vertexCoordAttrName}.x) + ${coordXOffsetAttrName}) * uWorldScale;
            z = (float(${vertexCoordAttrName}.y) + ${coordZOffsetAttrName}) * uWorldScale;
        }
    
        return vec2(x, z);
    }
    
    vec4 getPosition()
    {
        dModelMatrix = getModelMatrix();

        vec2 xz = getXZ();
        vec3 localPos = vec3(xz[0], ${vertexHeightAttrName}, xz[1]);

        vec4 posW = dModelMatrix * vec4(localPos, 1.0);

        dPositionW = posW.xyz;

        vec4 screenPos = matrix_viewProjection * posW;
        return screenPos;
    }
    
    vec3 getWorldPosition()
    {
        return dPositionW;
    }

When I set a default value like 128, the shadows start rendering from that position.

    private _bindDependenciesToMaterial(material: pc.StandardMaterial) {
        
        material.setAttribute(vertexCoordAttrName, TerrainPatchesBasic.SEMANTIC_COORD_ATTR);
        material.setAttribute(vertexHeightAttrName, pc.SEMANTIC_POSITION);
        material.setAttribute(vertexNormalAttrName, pc.SEMANTIC_NORMAL);

        material.setParameter(useBaseVertexAttrName, this.useBaseVertex ? 1 : 0);
        material.setParameter(coordXOffsetAttrName, 128); // <--- HERE
        material.setParameter(coordZOffsetAttrName, 128); // <--- HERE

        const chunksStore = terrainShaderChunks;
        const chunkNames  = Object.keys(chunksStore);

        for (let chunkName of chunkNames) {
            material.chunks[chunkName] = chunksStore[chunkName];
        }

        material.chunks.APIVersion = pc.CHUNKAPI_1_70;
        material.update();
    }

... 
       material.setParameter(useBaseVertexAttrName, this.useBaseVertex ? 1 : 0);
       material.setParameter(coordXOffsetAttrName, 256);
       material.setParameter(coordZOffsetAttrName, 256);
...

@mvaligursky

Could you please try to explain what are you trying to do, as I’m not sure I understand.
Are you trying to generate shadow maps per patch yourself and then use them by standard materials or something?

No, I’m using a standard shader.

Shadows are generated with the material’s default value. Although I rewrite them through the mesh instance.

So what are you trying to do and what is the problem?

Rewriting shadow parameters using the mesh instance won’t work in the future, as those “global” parameters will be moved to a static uniform buffer that the mesh cannot update.

That is, there is no way I can overwrite the material parameter through the mesh instance?

Yes you can override material’s parameters, that works now and will keep working.
But not some parameters that are constant for the camera for example.

Where can I get a list of parameters that cannot be overwritten?

This hasn’t been worked on yet. In general all parameters of a camera and lights, as those are constant per camera / layer rendering.

Currently these parameters are constant, but the list will grow in the future:

Hmm, so, I’ve looked at it briefly yesterday. It looks like that terrain is generated in 128x128 chunks. Each chunk own draw call. That first chunk that is generated gets all the shadows from all other chunks. So, when other chunks are added later, their shadows are still drawn on the first one. It seems that the new updated dPositionW is not considered when the shadow is drawn. Or perhaps it is drawn only once, so later updates are ignored and the same value is used. I’d assume Realtime mode would redraw it? Or maybe there is a different way to force updating it?

@mvaligursky is there a way to reset the shadow map coordinates, so that the new chunks are included? It looks like the initial values of dPositionW are used, and if it is changed later, the changes are ignored. What would be a way to force using new values?