Github首页地球学习(1)-Earth

Github首页地球学习(1)-Earth

参考1
参考2

源码地址

说明
原始代码使用 event-emitter,作为事件分发器,需要借助打包工具使用。

最终效果:
Github首页地球学习(1)-Earth_第1张图片

该小结效果:
Github首页地球学习(1)-Earth_第2张图片

1、边缘发光

顶点着色器:

  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.);
}

Github首页地球学习(1)-Earth_第3张图片

让其过渡自然一些,并混合一下:

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.);

Github首页地球学习(1)-Earth_第4张图片

2、前置光源

vec3(.875, 0.5, 1.) 对光源的范围主要在y轴进行放大。

dist = distance(vWorldPosition * vec3(.875, 0.5, 1.), vec3(.0,.0,.0));
gl_FragColor = vec4(vec3(dist),1.);

Github首页地球学习(1)-Earth_第5张图片

放大一下然后混合:

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.);

Github首页地球学习(1)-Earth_第6张图片

3、阴影

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.);
}

Github首页地球学习(1)-Earth_第7张图片

混合一下:

dist = distance(vWorldPosition, shadowPoint);
outgoingLight = mix(outgoingLight * 0.01, outgoingLight, smoothstep(0.0, shadowDist, dist));
gl_FragColor = vec4( outgoingLight, 1. );

Github首页地球学习(1)-Earth_第8张图片

4、完整着色器代码

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/
Github首页地球学习(1)-Earth_第9张图片

你可能感兴趣的:(Threejs-Shader,学习)