首页 > 解决方案 > three.js WebGL:INVALID_OPERATION:drawElements:没有使用有效的着色器程序

问题描述

我的three.js版本是v-125,爆出来的代码是在6个PlaneGeometry上初始化渲染ShaderMaterial,是88版本的代码修改的。

这是着色器的代码。

import noise from 'glsl-noise/classic/3d';
varying vec2 vUv;
uniform int index;
uniform float seed;
uniform float resolution;
uniform float res1;
uniform float res2;
uniform float resMix;
uniform float mixScale;
uniform float doesRidged;
const int octaves = 16;

// #define M_PI 3.1415926535897932384626433832795;


vec3 getSphericalCoord(int index, float x, float y, float width) {
    width /= 2.0;
    x -= width;
    y -= width;
    vec3 coord = vec3(0.0, 0.0, 0.0);

    if (index == 0) {coord.x=width; coord.y=-y; coord.z=-x;}
    else if (index == 1) {coord.x=-width; coord.y=-y; coord.z=x;}
    else if (index == 2) {coord.x=x; coord.y=width; coord.z=y;}
    else if (index == 3) {coord.x=x; coord.y=-width; coord.z=-y;}
    else if (index == 4) {coord.x=x; coord.y=-y; coord.z=width;}
    else if (index == 5) {coord.x=-x; coord.y=-y; coord.z=-width;}

    return normalize(coord);
}

float simplexRidged(vec3 pos, float seed) {
    float n = noise(vec3(pos + seed));
    n = (n + 1.0) * 0.5;
    n = 2.0 * (0.5 - abs(0.5 - n));
    return n;
}

float simplex(vec3 pos, float seed) {
    float n = noise(vec3(pos + seed));
    return (n + 1.0) * 0.5;
}

float baseNoise(vec3 pos, float frq, float seed ) {
    float amp = 0.5;

    float n = 0.0;
    float gain = 1.0;
    for(int i=0; i<octaves; i++) {
        n +=  simplex(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
        gain *= 2.0;
    }

    // increase contrast
    n = ( (n - 0.5) * 2.0 ) + 0.5;

    return n;
}

float ridgedNoise(vec3 pos, float frq, float seed) {
    float amp = 0.5;
    float n = 0.0;
    float gain = 1.0;
    for(int i=0; i<octaves; i++) {
        n +=  simplexRidged(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
        gain *= 2.0;
    }

    n = pow(n, 4.0);
    return n;
}

float invRidgedNoise(vec3 pos, float frq, float seed) {

    float amp = 0.5;

    float n = 0.0;
    float gain = 1.0;
    for(int i=0; i<octaves; i++) {
        n +=  simplexRidged(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
        gain *= 2.0;
    }

    n = pow(n, 4.0);
    n = 1.0 - n;

    return n;
}

float cloud(vec3 pos, float seed) {
    float n = noise(vec3(pos + seed));
    // n = sin(n*4.0 * cos(n*2.0));
    n = sin(n*5.0);
    // n = abs(sin(n*5.0));
    // n = 1.0 - n;

    n = n*0.5 + 0.5;
    // n = 1.0-n;
    // n = n*1.2;
    // n = 1.0-n;

    return n;
}

float cloudNoise(vec3 pos, float frq, float seed) {

    float amp = 0.5;

    float n = 0.0;
    float gain = 1.0;
    for(int i=0; i<octaves; i++) {
        n +=  cloud(vec3(pos.x*gain/frq, pos.y*gain/frq, pos.z*gain/frq), seed+float(i)*10.0) * amp/gain;
        gain *= 2.0;
    }

    // n = pow(n, 5.0);

    n = 1.0-n;
    n = pow(n, 1.0);
    n = 1.0-n;

    return n;
}

void main() {
    float x = vUv.x;
    float y = 1.0 - vUv.y;
    vec3 sphericalCoord = getSphericalCoord(index, x*resolution, y*resolution, resolution);

    float sub1, sub2, sub3, n;

    float resMod = 1.0; // overall res magnification
    float resMod2 = mixScale; // minimum res mod

    if (doesRidged == 0.0) {
        sub1 = cloudNoise(sphericalCoord, res1*resMod, seed+11.437);
        sub2 = cloudNoise(sphericalCoord, res2*resMod, seed+93.483);
        sub3 = cloudNoise(sphericalCoord, resMix*resMod, seed+23.675);
        n = cloudNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+78.236);
    }
    else if (doesRidged == 1.0) {
        sub1 = ridgedNoise(sphericalCoord, res1*resMod, seed+83.706);
        sub2 = ridgedNoise(sphericalCoord, res2*resMod, seed+29.358);
        sub3 = ridgedNoise(sphericalCoord, resMix*resMod, seed+53.041);
        n = ridgedNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+34.982);
    }
    else  if (doesRidged == 2.0) {
        sub1 = invRidgedNoise(sphericalCoord, res1*resMod, seed+49.684);
        sub2 = invRidgedNoise(sphericalCoord, res2*resMod, seed+136.276);
        sub3 = invRidgedNoise(sphericalCoord, resMix*resMod, seed+3.587);
        n = invRidgedNoise(sphericalCoord + vec3((sub1/sub3)*0.1), resMod2+sub2, seed+33.321);
    }
    else {
        sub1 = baseNoise(sphericalCoord, res1*resMod, seed+52.284);
        sub2 = baseNoise(sphericalCoord, res2*resMod, seed+137.863);
        sub3 = baseNoise(sphericalCoord, resMix*resMod, seed+37.241);
        float alpha = sub1*3.14*2.0;
        float beta = sub2*3.14*2.0;
        float fx = cos(alpha)*cos(beta);
        float fz = sin(alpha)*cos(beta);
        float fy = sin(beta);
        n = baseNoise(sphericalCoord + (vec3(fx,fy,fz) * sub3), 1.0, seed+28.634);
    }

    gl_FragColor = vec4(vec3(n), 1.0);

}

这是将着色器应用于

    import * as THREE from 'three'
    import fragShader from './flowNoiseMap.frag'
    import seedrandom from 'seedrandom';

    class NoiseMap
    {
      constructor() {
        window.rng = seedrandom('adfadfadf');
        this.setupMaterial();
        this.setupPlane();
        let resMin = 0.01;
        let resMax = 5.0;
        this.resolution = 1024;
        this.seed = this.randRange(0, 1) * 1000.0;

        this.render({
          seed: this.seed,
          resolution: this.resolution,
          res1: this.randRange(resMin, resMax),
          res2: this.randRange(resMin, resMax),
          resMix: this.randRange(resMin, resMax),
          mixScale: this.randRange(0.5, 1.0),
          doesRidged: Math.floor(this.randRange(0, 4))
         });
      }
    
      setupPlane() {
        this.maps = [];
        this.textures = [];
        this.textureCameras = [];
        this.textureScenes = [];
        this.planes = [];
        this.geos = [];
    
        for (let i = 0; i < 6; i++) {
          let tempRes = 1000;
          this.textures[i] = new THREE.WebGLRenderTarget(tempRes, tempRes, {minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat});
            this.textureCameras[i] = new THREE.OrthographicCamera(-tempRes/2, tempRes/2, tempRes/2, -tempRes/2, -100, 100);
            this.textureCameras[i].position.z = 10;
            this.textureScenes[i] = new THREE.Scene();
            this.geos[i] = new THREE.PlaneGeometry(1, 1);
            this.planes[i] = new THREE.Mesh(this.geos[i], this.mats[i]);
            this.planes[i].position.z = -10;
            this.textureScenes[i].add(this.planes[i]);
            //window.renderer.render(textureScene, textureCamera);
            this.maps.push(this.textures[i].texture);
        }
      }
    
      setup() {
        this.mats = [];
        for (let i = 0; i < 6; i++) {
          this.mats[i] = new THREE.ShaderMaterial({
            uniforms: {
              index: {type: "i", value: i},
              seed: {type: "f", value: 0},
              resolution: {type: "f", value: 0},
              res1: {type: "f", value: 0},
              res2: {type: "f", value: 0},
              resMix: {type: "f", value: 0},
              mixScale: {type: "f", value: 0},
              doesRidged: {type: "f", value: 0}
            },
            vertexShader: vertShader,
            fragmentShader: fragShader,
            transparent: true,
            depthWrite: false
          });
        }
      }
    
      render(props) {
        let resolution = props.resolution;
        for (let i = 0; i < 6; i++) {
          this.mats[i].uniforms.seed.value = props.seed;
          this.mats[i].uniforms.resolution.value = props.resolution;
          this.mats[i].uniforms.res1.value = props.res1;
          this.mats[i].uniforms.res2.value = props.res2;
          this.mats[i].uniforms.resMix.value = props.resMix;
          this.mats[i].uniforms.mixScale.value = props.mixScale;
          this.mats[i].uniforms.doesRidged.value = props.doesRidged;
          this.mats[i].needsUpdat = true;
        }
    
          this.renderMaterial(props) 
        }
    
      renderMaterial(props) {
        let resolution = props.resolution;
        console.log('map render')
        for (let i = 0; i < 6; i++) {
            this.textures[i].setSize(resolution, resolution);
            this.textures[i].needsUpdate = true;
            this.textureCameras[i].left = -resolution/2;
            this.textureCameras[i].right = resolution/2;
            this.textureCameras[i].top = resolution/2;
            this.textureCameras[i].bottom = -resolution/2;
            this.textureCameras[i].updateProjectionMatrix();
            this.geos[i] = new THREE.PlaneGeometry(resolution, resolution);
            this.planes[i].geometry = this.geos[i];
            window.renderer.render(this.textureScenes[i], this.textureCameras[i]);
            this.geos[i].dispose();
        
        }
      }

      randRange(low, high) {
        let range = high - low;
        let n = window.rng() * range;
        return low + n;
      }
    }


    new NoiseMap();
    

运行代码给了我错误

three.module.js?3179:19503 WebGL: INVALID_OPERATION: useProgram: program not valid
useProgram @ three.module.js?3179:19503
setProgram @ three.module.js?3179:24390
WebGLRenderer.renderBufferDirect @ three.module.js?3179:23631

WebGL: INVALID_OPERATION: drawElements: no valid shader program in use
three.module.js?3179:17081 THREE.WebGLProgram: shader error:  0 35715 false gl.getProgramInfoLog invalid shaders  THREE.WebGLShader: gl.getShaderInfoLog() fragment
ERROR: 0:89: 'import' : syntax error
1: #version 300 es
2: #define varying in
3: out highp vec4 pc_fragColor;
4: #define gl_FragColor pc_fragColor
5: #define gl_FragDepthEXT gl_FragDepth
6: #define texture2D texture
7: #define textureCube texture
8: #define texture2DProj textureProj
9: #define texture2DLodEXT textureLod
10: #define texture2DProjLodEXT textureProjLod
11: #define textureCubeLodEXT textureLod
12: #define texture2DGradEXT textureGrad
13: #define texture2DProjGradEXT textureProjGrad
14: #define textureCubeGradEXT textureGrad
15: precision highp float;
16: precision highp int;
17: #define HIGH_PRECISION
18: #define SHADER_NAME ShaderMaterial
19: #define GAMMA_FACTOR 2
20: uniform mat4 viewMatrix;
21: uniform vec3 cameraPosition;
22: uniform bool isOrthographic;
23: 
24: vec4 LinearToLinear( in vec4 value ) {
25:     return value;
26: }
27: vec4 GammaToLinear( in vec4 value, in float gammaFactor ) {
28:     return vec4( pow( value.rgb, vec3( gammaFactor ) ), value.a );
29: }
30: vec4 LinearToGamma( in vec4 value, in float gammaFactor ) {
31:     return vec4( pow( value.rgb, vec3( 1.0 / gammaFactor ) ), value.a );
32: }
33: vec4 sRGBToLinear( in vec4 value ) {
34:     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 );
35: }
36: vec4 LinearTosRGB( in vec4 value ) {
37:     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 );
38: }
39: vec4 RGBEToLinear( in vec4 value ) {
40:     return vec4( value.rgb * exp2( value.a * 255.0 - 128.0 ), 1.0 );
41: }
42: vec4 LinearToRGBE( in vec4 value ) {
43:     float maxComponent = max( max( value.r, value.g ), value.b );
44:     float fExp = clamp( ceil( log2( maxComponent ) ), -128.0, 127.0 );
45:     return vec4( value.rgb / exp2( fExp ), ( fExp + 128.0 ) / 255.0 );
46: }
47: vec4 RGBMToLinear( in vec4 value, in float maxRange ) {
48:     return vec4( value.rgb * value.a * maxRange, 1.0 );
49: }
50: vec4 LinearToRGBM( in vec4 value, in float maxRange ) {
51:     float maxRGB = max( value.r, max( value.g, value.b ) );
52:     float M = clamp( maxRGB / maxRange, 0.0, 1.0 );
53:     M = ceil( M * 255.0 ) / 255.0;
54:     return vec4( value.rgb / ( M * maxRange ), M );
55: }
56: vec4 RGBDToLinear( in vec4 value, in float maxRange ) {
57:     return vec4( value.rgb * ( ( maxRange / 255.0 ) / value.a ), 1.0 );
58: }
59: vec4 LinearToRGBD( in vec4 value, in float maxRange ) {
60:     float maxRGB = max( value.r, max( value.g, value.b ) );
61:     float D = max( maxRange / maxRGB, 1.0 );
62:     D = clamp( floor( D ) / 255.0, 0.0, 1.0 );
63:     return vec4( value.rgb * ( D * ( 255.0 / maxRange ) ), D );
64: }
65: const mat3 cLogLuvM = mat3( 0.2209, 0.3390, 0.4184, 0.1138, 0.6780, 0.7319, 0.0102, 0.1130, 0.2969 );
66: vec4 LinearToLogLuv( in vec4 value ) {
67:     vec3 Xp_Y_XYZp = cLogLuvM * value.rgb;
68:     Xp_Y_XYZp = max( Xp_Y_XYZp, vec3( 1e-6, 1e-6, 1e-6 ) );
69:     vec4 vResult;
70:     vResult.xy = Xp_Y_XYZp.xy / Xp_Y_XYZp.z;
71:     float Le = 2.0 * log2(Xp_Y_XYZp.y) + 127.0;
72:     vResult.w = fract( Le );
73:     vResult.z = ( Le - ( floor( vResult.w * 255.0 ) ) / 255.0 ) / 255.0;
74:     return vResult;
75: }
76: const mat3 cLogLuvInverseM = mat3( 6.0014, -2.7008, -1.7996, -1.3320, 3.1029, -5.7721, 0.3008, -1.0882, 5.6268 );
77: vec4 LogLuvToLinear( in vec4 value ) {
78:     float Le = value.z * 255.0 + value.w;
79:     vec3 Xp_Y_XYZp;
80:     Xp_Y_XYZp.y = exp2( ( Le - 127.0 ) / 2.0 );
81:     Xp_Y_XYZp.z = Xp_Y_XYZp.y / value.y;
82:     Xp_Y_XYZp.x = value.x * Xp_Y_XYZp.z;
83:     vec3 vRGB = cLogLuvInverseM * Xp_Y_XYZp.rgb;
84:     return vec4( max( vRGB, 0.0 ), 1.0 );
85: }
86: vec4 linearToOutputTexel( vec4 value ) { return LinearToLinear( value ); }
87: 
88: #define GLSLIFY 1
89: import noise from 'glsl-noise/classic/3d'
90: 
91: varying vec2 vUv;
92: uniform int index;
93: uniform float seed;
94: uniform float resolution;
95: uniform float res1;
96: uniform float res2;
97: uniform float resMix;
98: uniform float mixScale;
99: uniform float doesRidged;
100: const int octaves = 16;
101: 
102: // #define M_PI 3.1415926535897932384626433832795;
103: 
104: vec3 getSphericalCoord(int index, float x, float y, float width) {
105:    width /= 2.0;
106:    x -= width;
107:    y -= width;
108:    vec3 coord = vec3(0.0, 0.0, 0.0);
109: 
110:    if (index == 0) {coord.x=width; coord.y=-y; coord.z=-x;}
111:    else if (index == 1) {coord.x=-width; coord.y=-y; coord.z=x;}
112:    else if (index == 2) {coord.x=x; coord.y=width; coord.z=y;}
113:    else if (index == 3) {coord.x=x; coord.y=-width; coord.z=-y;}
114:    else if (index == 4) {coord.x=x; coord.y=-y; coord.z=width;}
115:    else if (index == 5) {coord.x=-x; coord.y=-y; coord.z=-width;}
116: 
117:    return normalize(coord);
118: }
119: ..................

这个着色器代码有什么问题,因为它用于在版本 88 中工作

标签: three.jsfragment-shader

解决方案


您在编译的着色器中有这一行:

从“glsl-noise/classic/3d”导入噪声;

这不是有效的 GLSL。似乎您在构建过程中缺少一个步骤,该步骤解决了导入并将代码从glsl-noise/classic/3d您的着色器中注入。


推荐阅读