shadermaterial 实现大气层效果和辉光效果

1.创建两个球体,一个一小,一个略大的作为他的辉光
2.作为辉光的球体从内到外片元透明度逐渐减小(线性减小或是指数减小都可以)
3.将覆盖原物体的部分丢弃

辉光效果

var vertexShader = [
    'varying vec3	vVertexWorldPosition;',
    'varying vec3	vVertexNormal;',
    'varying vec4	vFragColor;',
    'void main(){',
    '	vVertexNormal	= normalize(normalMatrix * normal);',//将法线转换到视图坐标系中
    '	vVertexWorldPosition	= (modelMatrix * vec4(position, 1.0)).xyz;',//将顶点转换到世界坐标系中
    '	// set gl_Position',
    '	gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
    '}']
    
   var  fragmentShader: [
        'uniform vec3	glowColor;',
        'uniform float	coeficient;',
        'uniform float	power;',

        'varying vec3	vVertexNormal;',
        'varying vec3	vVertexWorldPosition;',

        'varying vec4	vFragColor;',

        'void main(){',
        '	vec3 worldVertexToCamera= cameraPosition - vVertexWorldPosition;',	//世界坐标系中顶点位置到相机位置到的距离
        '	vec3 viewCameraToVertex	= (viewMatrix * vec4(worldVertexToCamera, 0.0)).xyz;',//视图坐标系中从相机位置到顶点位置的距离
        '	viewCameraToVertex	= normalize(viewCameraToVertex);',//规一化
        '	float intensity		= coeficient + dot(vVertexNormal, viewCameraToVertex);',
        '	if(intensity > 0.65){ intensity = 0.0;}',
        '	gl_FragColor		= vec4(glowColor, intensity);',
        '}'
        //vVertexNormal视图坐标系中点的法向量
        //viewCameraToVertex视图坐标系中点到摄像机的距离向量
        //dot点乘得到它们的夹角的cos值
        //从中心向外面角度越来越大(从锐角到钝角)从cos函数也可以知道这个值由负变正,不透明度最终从高到低
 

大气层效果

var vertexShader = [
    'varying vec3	vVertexWorldPosition;',
    'varying vec3	vVertexNormal;',
    'varying vec4	vFragColor;',
    'void main(){',
    '	vVertexNormal	= normalize(normalMatrix * normal);',//将法线转换到视图坐标系中
    '	vVertexWorldPosition	= (modelMatrix * vec4(position, 1.0)).xyz;',//将顶点转换到世界坐标系中
    '	// set gl_Position',
    '	gl_Position	= projectionMatrix * modelViewMatrix * vec4(position, 1.0);',
    '}']
    
var  fragmentShader: [
        'uniform vec3	glowColor;',
        'uniform float	coeficient;',
        'uniform float	power;',

        'varying vec3	vVertexNormal;',
        'varying vec3	vVertexWorldPosition;',

        'varying vec4	vFragColor;',

        'void main(){',
        '	vec3 worldCameraToVertex= vVertexWorldPosition - cameraPosition;',	//世界坐标系中从相机位置到顶点位置的距离
        '	vec3 viewCameraToVertex	= (viewMatrix * vec4(worldCameraToVertex, 0.0)).xyz;',//视图坐标系中从相机位置到顶点位置的距离
        '	viewCameraToVertex	= normalize(viewCameraToVertex);',//规一化
        '	float intensity		= pow(coeficient + dot(vVertexNormal, viewCameraToVertex), power);',
        '	gl_FragColor		= vec4(glowColor, intensity);',
        '}'
        //vVertexNormal视图坐标系中点的法向量
        //viewCameraToVertex视图坐标系中点到摄像机的距离向量
        //dot点乘得到它们的夹角的cos值
        //从中心向外面角度越来越小(从钝角到锐角)从cos函数也可以知道这个值由负变正,不透明度最终从低到高
    ]

分层显示透明度

'uniform vec3	glowColor;',
'uniform float	coeficient;',
'varying vec3	vVertexNormal;',
'varying vec3	vVertexWorldPosition;',
'void main(){',
'	vec3 worldVertexToCamera= cameraPosition - vVertexWorldPosition;',	
'	vec3 viewCameraToVertex	= (viewMatrix * vec4(worldVertexToCamera, 0.0)).xyz;',
'	viewCameraToVertex	= normalize(viewCameraToVertex);',
'	float intensity		= coeficient + dot(vVertexNormal, viewCameraToVertex);',
'	if(intensity > 0.65 && intensity < 0.8){ intensity = 0.8;}',
'	if(intensity > 0.8){ intensity = 1.0;}',
'	gl_FragColor = vec4(glowColor, intensity);',
'}'

代码参考:
https://blog.csdn.net/srk19960903/article/details/78734238
https://blog.csdn.net/lin5165352/article/details/83055606

你可能感兴趣的:(threejs)