Errors are being encountered when retrieving Shadow Shader Chunks

As I work on combining a basic toon shaded ShaderMaterial with threejs' built-in shadow system, I encountered some errors. It seems that when I set the Mesh's recieveShadow property to true, I run into issues. The errors I am facing are:

Vertex Errors

THREE.WebGLShader: gl.getShaderInfoLog() vertex ERROR: 0:72: 'worldPosition' : undeclared identifier 
ERROR: 0:72: 'assign' :  cannot convert from 'mediump 4X4 matrix of float' to 'mediump 4-component vector of float'

Fragment Errors

THREE.WebGLShader: gl.getShaderInfoLog() fragment ERROR: 0:356: 'shadowMask' : undeclared identifier
ERROR: 0:356: 'assign' :  cannot convert from 'mediump 3-component vector float' to 'float'

I am using the superpowers-game engine, which utilizes typescript and the threejs plugin version r73. Below is my code (still in progress):

Shaders

const IslandVertexShader = `
    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }

    void main() {

        vNormal = normalize( normalMatrix * normal );
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vViewPosition = -mvPosition.xyz;
        vUv = uv;

        ${ THREE.ShaderChunk[ "shadowmap_vertex" ] }

        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

     }
`

const IslandFragmentShader = `
    uniform vec3 uMaterialColor;

    uniform vec3 uDirLightPos;
    uniform vec3 uDirLightColor;

    uniform float uKd;
    uniform float uBorder;

    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_fragment" ] }

    void main() {

        // compute direction to light
        vec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );
        vec3 lVector = normalize( lDirection.xyz );

        // diffuse: N * L. Normal must be normalized, since it's interpolated.
        vec3 normal = normalize( vNormal );
        
        float diffuse = dot( normal, lVector );
        if ( diffuse > 0.5 ) { diffuse = 1.0; }
        else if ( diffuse > -0.2 ) { diffuse = 0.7; }
        else { diffuse = 0.6; }

        gl_FragColor = vec4( uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );

        ${ THREE.ShaderChunk[ "shadowmap_fragment" ] }

    }
`

Declaration

var sphere = new THREE.TorusKnotGeometry( 5, 1, 100, 16 );

var shader = new THREE.ShaderMaterial();
shader.uniforms = THREE.UniformsUtils.merge([THREE.UniformsLib["shadowmap"], {
    uDirLightPos: { type: "v3", value: new THREE.Vector3(0, 10, 0) },
    uDirLightColor: { type: "v3", value: new THREE.Vector3(1, 1, 1) },
    uMaterialColor: { type: "v3", value: new THREE.Vector3(0.5, 1, 1) },
    uKd: { type: "f", value: 1 }
}]);

shader.vertexShader = IslandVertexShader;
shader.fragmentShader = IslandFragmentShader;
shader.lights = true;
shader.needsUpdate = true;

var mesh = new THREE.Mesh(sphere, shader);
mesh.castShadow = true;
mesh.receiveShadow = true;
(<any>this.actor).__inner.threeObject.add(mesh); // Ignore this

Answer №1

Finally, I managed to figure it out after delving deep into the code. Although some parts may not apply if you are using a more recent version, here is the revised and corrected code:

const IslandVertexShader = `
    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    ${ THREE.ShaderChunk[ "shadowmap_pars_vertex" ] }

    void main() {

        ${ THREE.ShaderChunk[ "begin_vertex" ] }

        vNormal = normalize( normalMatrix * normal );
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        vViewPosition = -mvPosition.xyz;
        vUv = uv;

        ${ THREE.ShaderChunk[ "worldpos_vertex" ] }
        ${ THREE.ShaderChunk[ "shadowmap_vertex" ] }

        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

    }
`

const IslandFragmentShader = `
    uniform vec3 uMaterialColor;

    uniform vec3 uDirLightPos;
    uniform vec3 uDirLightColor;

    uniform float uKd;
    uniform float uBorder;

    varying vec3 vNormal;
    varying vec3 vViewPosition;
    varying vec2 vUv;

    vec3 shadowMask = vec3( 1.0 );

    ${ THREE.ShaderChunk[ "shadowmap_pars_fragment" ] }


    void main() {

        // calculate light direction
        vec4 lDirection = viewMatrix * vec4( uDirLightPos, 0.0 );
        vec3 lVector = normalize( lDirection.xyz );

        // diffuse: N * L. Normalizing the normal since it's interpolated.
        vec3 normal = normalize( vNormal );
        
        float diffuse = dot( normal, lVector );
        if ( diffuse > 0.5 ) { diffuse = 1.0; }
        else if ( diffuse > -0.2 ) { diffuse = 0.7; }
        else { diffuse = 0.6; }

        ${ THREE.ShaderChunk[ "shadowmap_fragment" ] }
        
        gl_FragColor = vec4( shadowMask * uKd * uMaterialColor * uDirLightColor * diffuse, 1.0 );


    }
`

I made sure to include the begin_vertex and worldpos_vertex chunks, defined the vec3 shadowMask in the fragment shader, and utilized it when generating the final gl_FragColor. My insights came from studying the workings of the BasicMaterial shader in the threejs r73 commit (access link).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Steps to generate an accurate file order using Typescript:

Consider the scenario with two typescript files: In File a.ts: module SomeModule { export class AClass { } } And in File b.ts: module SomeModule { export var aValue = new AClass(); } When compiling them using tsc -out out.js b.ts a.ts, there are ...

Creating rectangular shapes on the canvas with the help of react hooks

I have a React+Typescript web application and I am currently working on implementing the functionality to draw rectangles on a canvas. My goal is to utilize React hooks instead of classes in order to achieve this. The desired outcome is to enable the user ...

The attribute 'prop' is not found on the type 'IntrinsicAttributes & TableProp'.ts(2322)

Encountering an error while trying to pass a prop to a React component for the first time. Despite looking at other posts for solutions, I have been unable to resolve it so far. Here is a snippet of my code: type TableProp = {}; function Table(prop: Tabl ...

Utilizando Typescript com Ionic 2 e AngularJS para autenticar através de um método de post na requisição HTTP e

Greetings and good afternoon to everyone. I hope you all are doing well. I am a beginner in AngularJS, currently using Visual Studio, Ionic 2, and TypeScript. I have successfully connected my app to a REST API in .NET and have implemented a token for tes ...

Warning: The value returned by this.profileService.getUserProfile(...) does not exist

My challenge involves setting up a profile page with options to update username, password, and email. I've managed to get the "change email" and "change password" functions working smoothly. However, when I try to apply the same method to "change name ...

I am looking to switch up the color of the cube in my three.js creation

I have successfully assembled a cube using the following code snippet: cube = new THREE.Mesh( new THREE.CubeGeometry(50,20,50), new THREE.MeshLambertMaterial({color: 0x6699ff}) ); ...

Typescript: require generic types to include specific keys at all times

Is there a way to ensure that the function below only accepts a data object if it contains an id key, and then allows us to access the id from the data object? function someFuntion<T>(data : T){ const id = data['id'] //Error : Element imp ...

Why isn't my Next.js middleware working properly with TypeScript?

My issue arises from the fact that, despite following the documentation, the middleware in Next.js is not functioning as I anticipated. I experimented with what I thought was the simplest middleware possible. I expected that when navigating to /, a conso ...

What is the significance of `new?()` in TypeScript?

Here is a snippet of code I'm working with in the TypeScript playground: interface IFoo { new?(): string; } class Foo implements IFoo { new() { return 'sss'; } } I noticed that I have to include "?" in the interface met ...

How can you typically verify the type of an object variable in TypeScript?

How can I verify if the obj variable contains all the properties defined in the Person interface? interface Person { name: string; age: number; } const jsonObj = `{ name: "John Doe", age: 30, }`; const obj: Person = JSON.parse(jsonObj); ...

Error message: Unable to set the uploaded file in the specified state within a React application

I am currently working on a react application that involves file uploads. My goal is to update the state variable with the uploaded file in either .docx or .pdf format as soon as it is uploaded. However, when I try to set the state, it shows up as undefine ...

Tips on displaying a spinner only when data is retrieved from an Http service

How can I ensure that a spinner is only shown during an HTTP service call and dismissed when my component receives data? To address this issue, I implemented a cache service to store data fetched from the HTTP service for future use. However, I want to sh ...

The TypeScript compiler has encountered an error (TS2339) indicating that the property 'id' does not exist on the type 'User'

Hi there, I'm new to TS and this is my first question here. I am encountering an error that says 'property 'id' does not exist on type 'User''. Could someone please explain why this error is happening and how I can fix it ...

Script for Excel Online utilizing data from a specific cell containing dates

I am currently working on a script in Excel online to automate date generation. My goal is to input a specific date into cell F1, such as 13/2/2023, and have G1 display the last day of the same year - 31/12/2023. The date needs to be extracted from cell A1 ...

Variable not accessible in a Typescript forEach loop

I am facing an issue with a foreach loop in my code. I have a new temp array created within the loop, followed by a nested foreach loop. However, when trying to access the temp array inside the nested loop, I encounter a "variable not available" error. le ...

What is the TypeScript definition for the return type of a Reselect function in Redux?

Has anyone been able to specify the return type of the createSelector function in Redux's Reselect library? I didn't find any information on this in the official documentation: https://github.com/reduxjs/reselect#q-are-there-typescript-typings ...

Utilize mapping for discriminated union type narrowing instead of switch statements

My objective is to utilize an object for rendering a React component based on a data type property. I am exploring ways to avoid utilizing switch cases when narrowing a discriminated union type in TypeScript. The typical method involves using if-else or sw ...

Using boolean value as default input value in React

When trying to set the default value of a controlled checkbox input from my request, I encountered an error stating "Type 'boolean' is not assignable to type 'string | number | readonly string[] | undefined'". Do you have any suggestion ...

Tips for resolving this unhandled error in React TypeScript

After creating a program in React TypeScript, I encountered an uncaught error. Despite running and debugging tests and conducting extensive research on Google, I have been unable to resolve this issue on my own. Therefore, I am reaching out for assistance ...

What is the most effective way to compare two arrays of objects in JavaScript?

I'm working on a function that needs to return an array of elements based on certain filters. Here is the code for the function: filter_getCustomFilterItems(filterNameToSearch: string, appliedFilters: Array<any>) { let tempFilterArray = []; ...