Webgl Error Using Three in React

hey, I tried to use (GitHub - clementroche/motion-hover-effects) first effect in react, in terminal I see no error, but in console, there is.
I can see the demo website with no problem(Motion Hover Effects | Demo 1)
[20:21]
this is my code:

import * as THREE from “three”
import {TweenLite, Power4} from “gsap”
export function projectsAnimations () {
//VARIABLES
let itemsWrapper = document.querySelector(‘.grid’)
let options = {}
let isLoaded = false
let mouse
let timeSpeed
let time
let clock
let container = document.body
//VIEW PORT
const viewport = {
width: container.clientWidth,
height: container.clientHeight,
aspectRatio: container.clientWidth / container.clientHeight
}

//MATH
Number.prototype.map = function(in_min, in_max, out_min, out_max) {
    return ((this - in_min) * (out_max - out_min)) / (in_max - in_min) + out_min
}

window.addEventListener('resize', onWindowResize.bind(this), false)
let renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true })
renderer.setSize(viewport.width, viewport.height)
renderer.setPixelRatio(window.devicePixelRatio)
container.appendChild(renderer.domElement)
let scene = new THREE.Scene()
let camera = new THREE.PerspectiveCamera(
    40,
    viewport.aspectRatio,
    0.1,
    100
)
camera.position.set(0, 0, 3)

mouse = new THREE.Vector2()

//TIME
timeSpeed = 2
time = 0
clock = new THREE.Clock()
//...............render.............
function render() {
    // called every frame
    time += clock.getDelta() * timeSpeed
    renderer.render(scene, camera)
}
renderer.setAnimationLoop(render.bind(this))

//...........ITEMS..............
// const items = Array.prototype.slice.call(document.querySelectorAll('.link'))
let items = [...itemsWrapper.querySelectorAll('.link')]
items = items.map((item, index) => ({
    element: item,
    img: item.querySelector('img') || null,
    index: index
}))
//...................................

function initEffectShell() {
    let promises = []

    const THREEtextureLoader = new THREE.TextureLoader()

    items.forEach((item, index) => {
        // create textures
        promises.push(
            loadTexture(
                THREEtextureLoader,
                item.img ? item.img.src : null,
                index
            )
        )
    })

    return new Promise((resolve, reject) => {
        // resolve textures promises
        Promise.all(promises).then(promises => {
            // all textures are loaded
            promises.forEach((promise, index) => {
                // assign texture to item
                items[index].texture = promise.texture
            })
            resolve()
        })
    })
}

initEffectShell().then(() => {
    console.log('load finished')
    isLoaded = true
})


//..........EVENT LISTENERS..............
let tempItemIndex
let isMouseOver
let currentItem



//VIEW SIZE
let distance = camera.position.z
let vFov = (camera.fov * Math.PI) / 180
const viewSize = {
    width: 2 * Math.tan(vFov / 2) * distance * viewport.aspectRatio,
    height: 2 * Math.tan(vFov / 2) * distance, vFov
}

items.forEach((item, index) => {
    item.element.addEventListener(
        'mouseover',
        _onMouseOver.bind(this, index),
        false
    )
})

container.addEventListener(
    'mousemove',
    _onMouseMove.bind(this),
    false
)
itemsWrapper.addEventListener(
    'mouseleave',
    _onMouseLeave.bind(this),
    false
)

function _onMouseLeave(event) {
    isMouseOver = false
    onMouseLeave(event)
}

function _onMouseMove(event) {
    // get normalized mouse position on viewport
    mouse.x = (event.clientX / viewport.width) * 2 - 1
    mouse.y = -(event.clientY / viewport.height) * 2 + 1

    onMouseMove(event)
}

function _onMouseOver(index, event) {
    tempItemIndex = index

    onMouseOver(index, event)
}

//.............resize............
function onWindowResize() {
    camera.aspect = viewport.aspectRatio
    camera.updateProjectionMatrix()
    renderer.setSize(viewport.width, viewport.height)
}

//......UPDATE TEXTURE..........
function onMouseEnter() {
    if (!currentItem || !isMouseOver) {
        isMouseOver = true
        // show plane
        TweenLite.to(uniforms.uAlpha, 0.5, {
            value: 1,
            ease: Power4.easeOut
        })
    }
}

function onMouseLeave(event) {
    TweenLite.to(uniforms.uAlpha, 0.5, {
        value: 0,
        ease: Power4.easeOut
    })
}

function onMouseMove(event) {
    // project mouse position to world coodinates
    let x = mouse.x.map(
        -1,
        1,
        -viewSize.width / 2,
        viewSize.width / 2
    )
    let y = mouse.y.map(
        -1,
        1,
        -viewSize.height / 2,
        viewSize.height / 2
    )

    position = new THREE.Vector3(x, y, 0)
    TweenLite.to(plane.position, 1, {
        x: x,
        y: y,
        ease: Power4.easeOut,
        onUpdate: onPositionUpdate.bind(this)
    })
}

function onTargetChange(index) {
    // item target changed
    currentItem = items[index]
    if (!currentItem.texture) return

    // compute image ratio
    let imageRatio =
        currentItem.img.naturalWidth / currentItem.img.naturalHeight
    scale = new THREE.Vector3(imageRatio, 1, 1)
    uniforms.uTexture.value = currentItem.texture
    plane.scale.copy(scale)
}

function onMouseOver(index, e) {
    if (!isLoaded) return
    onMouseEnter()
    if (currentItem && currentItem.index === index) return
    onTargetChange(index)
}

function onPositionUpdate() {
    // compute offset
    uniforms.uOffset.value = plane.position
        .clone()
        .sub(position)
        .multiplyScalar(-options.strength)
}

//..........LOAD TEXTURE.......
function loadTexture(loader, url, index) {
    // https://threejs.org/docs/#api/en/loaders/TextureLoader
    return new Promise((resolve, reject) => {
        if (!url) {
            resolve({ texture: null, index })
            return
        }
        // load a resource
        loader.load(
            // resource URL
            url,

            // onLoad callback
            texture => {
                resolve({ texture, index })
            },

            // onProgress callback currently not supported
            undefined,

            // onError callback
            error => {
                console.error('An error happened.', error)
                reject(error)
            }
        )
    })
}


//..........INIT..............
options.strength = options.strength || 0.25

let position = new THREE.Vector3(0, 0, 0)
let scale = new THREE.Vector3(1, 1, 1)
let geometry = new THREE.PlaneBufferGeometry(1, 1, 32, 32)
let uniforms = {
    uTime: {
        value: 0
    },
    uTexture: {
        value: null
    },
    uOffset: {
        value: new THREE.Vector2(0.0, 0.0)
    },
    uAlpha: {
        value: 0
    }
}
let material = new THREE.ShaderMaterial({
    uniforms: uniforms,
    vertexShader: `
            uniform vec2 uOffset;
            varying vec2 vUv;
            vec3 deformationCurve(vec3 position, vec2 uv, vec2 offset) {
              float M_PI = 3.1415926535897932384626433832795;
              position.x = position.x + (sin(uv.y * M_PI) * offset.x);
              position.y = position.y + (sin(uv.x * M_PI) * offset.y);
              return position;
            }
            
            void main() {
              vUv = uv;
              vec3 newPosition = position;
              newPosition = deformationCurve(position,uv,uOffset);
              gl_Position = projectionMatrix * modelViewMatrix * vec4( newPosition, 1.0 );
            }
          `,
    fragmentShader: `
            uniform sampler2D uTexture;
            uniform float uAlpha;
            uniform vec2 uOffset;
            varying vec2 vUv;
            vec3 rgbShift(sampler2D texture, vec2 uv, vec2 offset) {
              float r = texture2D(uTexture,vUv + uOffset).r;
              vec2 gb = texture2D(uTexture,vUv).gb;
              return vec3(r,gb);
            }
            void main() {
              vec3 color = rgbShift(uTexture,vUv,uOffset);
              gl_FragColor = vec4(color,uAlpha);
            }
          `,
    transparent: true
})
let plane = new THREE.Mesh(geometry, material)
scene.add(plane)

}

this is the error I get:

THREE.WebGLProgram: shader error: 0 35715 false gl.getProgramInfoLog invalid shaders� THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:95: ‘texture’ : function name expected
ERROR: 0:95: ‘r’ : field selection requires structure, vector, or interface block on left hand side
ERROR: 0:96: ‘texture’ : function name expected
ERROR: 0:96: ‘gb’ : field selection requires structure, vector, or interface block on left hand side
ERROR: 0:96: ‘=’ : dimension mismatch
ERROR: 0:96: ‘=’ : cannot convert from ‘const mediump float’ to ‘highp 2-component vector of float’
�1: version 300 es
2:
3: #define varying in
4: out highp vec4 pc_fragColor;
5: #define gl_FragColor pc_fragColor
6: #define gl_FragDepthEXT gl_FragDepth
7: #define texture2D texture
8: #define textureCube texture
9: #define texture2DProj textureProj
10: #define texture2DLodEXT textureLod
11: #define texture2DProjLodEXT textureProjLod
12: #define textureCubeLodEXT textureLod
13: #define texture2DGradEXT textureGrad
14: #define texture2DProjGradEXT textureProjGrad
15: #define textureCubeGradEXT textureGrad
16: precision highp float;
17: precision highp int;
18: #define HIGH_PRECISION
19: #define SHADER_NAME ShaderMaterial
20: #define GAMMA_FACTOR 2
21: uniform mat4 viewMatrix;
22: uniform vec3 cameraPosition;
23: uniform bool isOrthographic;
24:
25: vec4 LinearToLinear( in vec4 value ) {
26: return value;
27: }
28: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
29: return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
30: }
31: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
32: return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
33: }
34: vec4 sRGBToLinear( in vec4 value ) {
35: return vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );
36: }
37: vec4 LinearTosRGB( in vec4 value ) {
38: return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );
39: }
40: vec4 RGBEToLinear( in vec4 value ) {
41: return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
42: }
43: vec4 LinearToRGBE( in vec4 value ) {
44: float maxComponent = max( max( value.r, value.g ), value.b );
45: float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
46: return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
47: }
48: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
49: return vec4( value.rgb * value.a * maxRange, 1.0 );
50: }
51: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
52: float maxRGB = max( value.r, max( value.g, value.b ) );
53: float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
54: M = ceil( M * 255.0 ) / 255.0;
55: return vec4( value.rgb / ( M * maxRange ), M );
56: }
57: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
58: return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
59: }
60: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
61: float maxRGB = max( value.r, max( value.g, value.b ) );
62: float D = max( maxRange / maxRGB, 1.0 );
63: D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
64: return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
65: }
66: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
67: vec4 LinearToLogLuv( in vec4 value ) {
68: vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
69: Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
70: vec4 vResult;
71: vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
72: float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
73: vResult.w = fract( Le );
74: vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
75: return vResult;
76: }
77: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
78: vec4 LogLuvToLinear( in vec4 value ) {
79: float Le = value.z * 255.0 + value.w;
80: vec3 Xp_Y_XYZp;
81: Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
82: Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
83: Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
84: vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
85: return vec4( max( vRGB, 0.0 ), 1.0 );
86: }
87: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
88:
89:
90: uniform sampler2D uTexture;
91: uniform float uAlpha;
92: uniform vec2 uOffset;
93: varying vec2 vUv;
94: vec3 rgbShift(sampler2D texture, vec2 uv, vec2 offset) {
95: float r = texture2D(uTexture,vUv + uOffset).r;
96: vec2 gb = texture2D(uTexture,vUv).gb;
97: return vec3(r,gb);
98: }
99: void main() {
100: vec3 color = rgbShift(uTexture,vUv,uOffset);
101: gl_FragColor = vec4(color,uAlpha);
102: }
103: with some warnings: WebGL: INVALID_OPERATION: useProgram: program not valid
WebGL: INVALID_OPERATION: drawElements: no valid shader program in use
WebGL: too many errors, no more errors will be reported to the console for this context.

threejs v118 (or was it 119?) breaks shaders, you need to go back a version, or rename “texture” in the shader-code, because it is now a reserved keyword.

1 Like

Thanks. I couldn’t get what I must change. I do not see texture function…
Can u show exactly the change?

I also changed v119 to v118 and v117, another error appeared!

TypeError: mouse.x.map is not a function

> 143 |     let x = mouse.x.map(

Guess I should edit the texture at first place, if you’d show me the change

if you go back to 117 the shader error should be gone. so that mouse thing is something else.

That was because I commented Number.prototype.map out as it gave a warning :confused:

That was the error!!! I just renamed the variable to other thing and that’s it… It woooorks!
Thank you so much!