我已经检查过类似问题的信笺,但没有找到解决方案。
我已经为顶点着色器和片段着色器都声明了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);
}
啊,我以为问题是我...我注释了vec3 vFlakesNormal = vec3(0.0, 0.0, 0.0); // perturbSparkleNormal2Arb(mvPosition.xyz, worldNormal);
实际函数,而是使用了存根。
这里是提交的修订为https://github.com/tabakerov/webglquestion/commit/7b2795a3dea20081dec0f43d497c56331d88508a