参考1
参考2
源码地址
说明
原始代码使用 event-emitter,作为事件分发器,需要借助打包工具使用。
顶点着色器:
varying vec3 vWorldPosition;
void main() {
// 常规操作
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
// 这里是主要
vec4 worldPosition = modelMatrix * vec4(position, 1.0);
vWorldPosition = worldPosition.xyz;
}
片元着色器:
varying vec3 vWorldPosition;
void main() {
float dist;
float distZ;
// highlights,四周高光
distZ = distance(vWorldPosition.z, 0.0);
gl_FragColor = vec4(vec3(distZ),1.);
}
让其过渡自然一些,并混合一下:
float dist;
float distZ;
vec3 outgoingLight = baseColor;
distZ = distance(vWorldPosition.z, 0.0);
outgoingLight = mix(
highlightColor,
outgoingLight,
smoothstep(0.0, highlightDist, pow(distZ, 0.5))
);
gl_FragColor = vec4(vec3(outgoingLight),1.);
vec3(.875, 0.5, 1.) 对光源的范围主要在y轴进行放大。
dist = distance(vWorldPosition * vec3(.875, 0.5, 1.), vec3(.0,.0,.0));
gl_FragColor = vec4(vec3(dist),1.);
放大一下然后混合:
dist = distance(vWorldPosition * vec3(.875, 0.5, 1.), vec3(.0,.0,.0));
outgoingLight = mix(frontHighlightColor * 1.6, outgoingLight, smoothstep(0.0, 15.0, dist));
gl_FragColor = vec4(vec3(outgoingLight),1.);
float remap01(float a, float b, float t) {
return (t-a)/(b-a);
}
void main(){
dist = distance(vWorldPosition, shadowPoint);
gl_FragColor = vec4(vec3(remap01(0.0, 15., dist)), 1.);
}
混合一下:
dist = distance(vWorldPosition, shadowPoint);
outgoingLight = mix(outgoingLight * 0.01, outgoingLight, smoothstep(0.0, shadowDist, dist));
gl_FragColor = vec4( outgoingLight, 1. );
export default {
vert: `
uniform float shadowDist;
uniform float highlightDist;
uniform vec3 shadowPoint;
uniform vec3 highlightPoint;
uniform vec3 frontPoint;
uniform vec3 highlightColor;
uniform vec3 frontHighlightColor;
varying vec3 vWorldPosition;
void main() {
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
vec4 worldPosition = modelMatrix * vec4(position, 1.0);
vWorldPosition = worldPosition.xyz;
}
`,
frag: `
uniform vec3 baseColor;
uniform float shadowDist;
uniform float highlightDist;
uniform vec3 shadowPoint;
uniform vec3 highlightPoint;
uniform vec3 frontPoint;
uniform vec3 highlightColor;
uniform vec3 frontHighlightColor;
varying vec3 vWorldPosition;
void main() {
float dist;
float distZ;
vec3 outgoingLight = baseColor;
// highlights,四周高光
#ifdef USE_HIGHLIGHT
distZ = distance(vWorldPosition.z, 0.0);
outgoingLight = mix(
highlightColor,
outgoingLight,
smoothstep(0.0, highlightDist, pow(distZ, 0.5))
);
#endif
// front hightlight 前置光源
#ifdef USE_FRONT_HIGHLIGHT
dist = distance(vWorldPosition * vec3(.875, 0.5, 1.), frontPoint);
outgoingLight = mix(frontHighlightColor * 1.6, outgoingLight, smoothstep(0.0, 15.0, dist));
#endif
// shadows
dist = distance(vWorldPosition, shadowPoint);
outgoingLight = mix(outgoingLight * 0.01, outgoingLight, smoothstep(0.0, shadowDist, dist));
gl_FragColor = vec4( outgoingLight, 1. );
}
`,
};
一个其他版本的实现:
https://m.tb.cn/h.fvRFX23?tk=gyLa2n6g1eU
https://liborong3d.gitee.io/libra3d/three-plugin-globe/