首页 > 解决方案 > WebGL(Three.js)`警告:顶点着色器'flakeUv'的输出未由片段着色器`警告和`flakeScale`读取

问题描述

我检查了有关类似问题的问题,但没有找到解决方案。

我已经声明varying vec2 flakeUv;了顶点和片段着色器,但由于某种原因它不会从一个到另一个,而其他参数(如 vUv)工作正常。

这个问题有一个演示项目:https ://github.com/tabakerov/webglquestion

制服:

const uniforms = { 
  paintColor1: { type: "c", value: new THREE.Color(0x350bF0) },
  paintColor2: { type: "c", value: new THREE.Color(0xcc9284) },
  paintColor3: { type: "c", value: new THREE.Color(0x0a0a0a) },
  normalMap: { type: "t", value: microflakeNormalMap},
  normalScale: { type: "f", value: 0.90, min: 0.0, max: 1.0},
  glossLevel: { type: "f", value: 0.80, min: 0.0, max: 5.0},
  brightnessFactor: {type: "f", value: 0.28, min: 0.0, max: 1.0},
  envMap: { type: "t", value: reflectionCube},
  microflakeNMap: { type: "t", value: microflakeNormalMap},
  flakeColor: { type: "c", value: new THREE.Color(0xFFFFFF) },
  flakeScale: { type: "f", value: -40.0, min: -50.0, max: 1.0},
  normalPerturbation: { type: "f", value: 1.0, min: -1.0, max: 1.0},
  microflakePerturbationA: { type: "f", value: 0.1, min: -1.0, max: 1.0},
  microflakePerturbation: { type: "f", value: 0.48, min: 0.0, max: 1.0}
};

顶点着色器:

#version 300 es
uniform float flakeScale;
varying vec4 mvPosition;
varying vec3 worldNormal;
varying vec3 cameraToVertex;
varying vec2 vUv;
varying vec2 flakeUv;
void main() {
    mvPosition = modelViewMatrix * vec4( position, 1.0 );
    worldNormal = mat3( modelMatrix[ 0 ].xyz, modelMatrix[ 1 ].xyz, modelMatrix[ 2 ].xyz ) * normal;
    vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
    cameraToVertex = normalize(worldPosition.xyz - cameraPosition);
    vUv = uv;
    flakeUv =  uv * flakeScale;
    gl_Position = projectionMatrix * mvPosition;
}

片段着色器:

#version 300 es
uniform vec3 paintColor1;
uniform vec3 paintColor2;
uniform vec3 paintColor3;    
uniform float normalPerturbation;
uniform float microflakePerturbationA;
uniform float microflakePerturbation;    
uniform float glossLevel;
uniform float brightnessFactor;
uniform samplerCube envMap;    
uniform sampler2D normalMap;
uniform sampler2D microflakeNMap;
uniform vec3 flakeColor;
uniform float normalScale;
varying vec2 vUv;
varying vec2 flakeUv;
varying vec3 worldNormal;
varying vec4 mvPosition;
varying vec3 cameraToVertex;

out vec4 out_FragColor;
// This function taken directly from the three.js phong fragment shader.
// http://hacksoflife.blogspot.ch/2009/11/per-pixel-tangent-space-normal-mapping.html
vec3 perturbNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {

    vec3 q0 = dFdx( eye_pos.xyz );
    vec3 q1 = dFdy( eye_pos.xyz );
    vec2 st0 = dFdx( vUv.st );
    vec2 st1 = dFdy( vUv.st );

    vec3 S = normalize( q0 * st1.t - q1 * st0.t );
    vec3 T = normalize( -q0 * st1.s + q1 * st0.s );
    vec3 N = normalize( surf_norm );

    vec3 mapN = texture2D( normalMap, vUv ).xyz * 2.0 - 1.0;
    mapN.xy = normalScale * mapN.xy;
    mat3 tsn = mat3( S, T, N );
    return normalize( tsn * mapN );
}

vec3 perturbSparkleNormal2Arb( vec3 eye_pos, vec3 surf_norm ) {

    vec3 q0 = dFdx( eye_pos.xyz );
    vec3 q1 = dFdy( eye_pos.xyz );
    vec2 st0 = dFdx( vUv.st );
    vec2 st1 = dFdy( vUv.st );

    vec3 S = normalize( q0 * st1.t - q1 * st0.t );
    vec3 T = normalize( -q0 * st1.s + q1 * st0.s );
    vec3 N = normalize( surf_norm );

    vec3 mapN = texture2D( microflakeNMap,  vUv * (-50.0) ).xyz * 2.0 - 1.0;
    mapN.xy = 1.0 * mapN.xy;
    mat3 tsn = mat3( S, T, N );
    return normalize( tsn * mapN );

}

void main() {

    // Refelection
    vec3 normal =  perturbNormal2Arb( mvPosition.xyz, worldNormal );
    float fFresnel = dot( normalize( -cameraToVertex ), normal );
    vec3 reflection = 2.0 * worldNormal * fFresnel - normalize(-cameraToVertex);
    vec4 envColor = textureCube( envMap, vec3( -reflection.x, reflection.yz ), glossLevel );
    envColor.rgb *= brightnessFactor;
    float fEnvContribution = 1.0 - 0.5 * fFresnel;

    // Flakes
    vec3 vFlakesNormal = vec3(0.0, 0.0, 0.0); // perturbSparkleNormal2Arb(mvPosition.xyz, worldNormal);
    vec3 vNp1 = microflakePerturbationA * vFlakesNormal + normalPerturbation * worldNormal;
    vec3 vNp2 = microflakePerturbation * ( vFlakesNormal + worldNormal ) ;

    float  fFresnel1 = clamp(dot( -cameraToVertex, vNp1 ), 0.0, 1.0);
    float  fFresnel2 = clamp(dot( -cameraToVertex, vNp2 ), 0.0, 1.0);

    float fFresnel1Sq = fFresnel1 * fFresnel1;
    vec3 paintColor = fFresnel1   * paintColor1 +
                    fFresnel1Sq * paintColor2 +
                    fFresnel1Sq * fFresnel1Sq * paintColor3 +
                    pow( fFresnel2, 16.0 ) * flakeColor;

    out_FragColor = envColor * fEnvContribution + vec4(paintColor, 1.0);
}

标签: three.jsopengl-esshaderwebglfragment-shader

解决方案


啊,因为我认为问题出在我身上......我注释掉了vec3 vFlakesNormal = vec3(0.0, 0.0, 0.0); // perturbSparkleNormal2Arb(mvPosition.xyz, worldNormal);实际功能并改用了存根。

这是修复https://github.com/tabakerov/webglquestion/commit/7b2795a3dea20081dec0f43d497c56331d88508a的提交


推荐阅读