<!--
Auto-generated by: https://github.com/threlte/threlte/tree/main/packages/gltf
Command: npx @threlte/gltf@2.0.1 static/planet.gltf -t -T
-->

<script lang="ts">
	import * as THREE from 'three';
	import { Group } from 'three';
	import { T, type Props, type Events, type Slots, forwardEventHandlers } from '@threlte/core';
	import { useGltf } from '@threlte/extras';

	type $$Props = Props<THREE.Group>;
	type $$Events = Events<THREE.Group>;
	type $$Slots = Slots<THREE.Group> & { fallback: {}; error: { error: any } };

	export const ref = new Group();

	type GLTFResult = {
		nodes: {
			mesh_0: THREE.Mesh;
			mesh_1: THREE.Mesh;
		};
		materials: {};
	};

	const gltf = useGltf<GLTFResult>('/planet-transformed.glb', { useDraco: true });

	const component = forwardEventHandlers();

	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);',
		'}'
	].join('\n');
	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 * 0.8);',
		'}'
	].join('\n');

	// create custom material from the shader code above
	//   that is within specially labeled script tags
	var material2 = new THREE.ShaderMaterial({
		uniforms: {
			coeficient: {
				value: 0.45
			},
			power: {
				value: 6
			},
			glowColor: {
				value: new THREE.Color(0xa5f3fc)
			}
		},
		vertexShader: vertexShader,
		fragmentShader: fragmentShader,
		transparent: true
	});

	const material = new THREE.MeshStandardMaterial();
	material.onBeforeCompile = (shader) => {
		shader.vertexShader = `varying vec3 vPos;\n${shader.vertexShader}`;
		shader.vertexShader = shader.vertexShader.replace(
			`#include <begin_vertex>`,
			`#include <begin_vertex>\nvPos = (modelViewMatrix * vec4(transformed, 1.0)).xyz;`
		);

		shader.fragmentShader = `varying vec3 vPos;\n${shader.fragmentShader}`;

		shader.fragmentShader = shader.fragmentShader.replace(
			'vec4 diffuseColor = vec4( diffuse, opacity );',
			`vec3 viewDirection = normalize(-vPos);
     float angle = pow(0.8 - abs(dot(viewDirection, vNormal)), 3.0);
     vec4 diffuseColor = vec4(diffuse, opacity * angle);`
		);
    
	};
</script>

<T is={ref} dispose={false} {...$$restProps} bind:this={$component}>
	{#await gltf}
		<slot name="fallback" />
	{:then gltf}
		<T.Mesh
			geometry={gltf.nodes.mesh_0.geometry}
			material={gltf.nodes.mesh_0.material}
			material.flatShading={true}
		>
			<T.Mesh
				geometry={gltf.nodes.mesh_1.geometry}
				material={gltf.nodes.mesh_1.material}
				material.flatShading={true}
			/>
		</T.Mesh>

		<!-- <T.Mesh scale={1.1}>
			<T.SphereGeometry args={[1, 32, 32]} />
			<T is={material} transparent={true} color={0x77ccff} opacity={1.0} />
		</T.Mesh> -->
		<T.Mesh scale={1.15}>
			<T.SphereGeometry args={[1, 32, 32]} />
			<T is={material2}  side={THREE.BackSide} />
		</T.Mesh>
	{:catch error}
		<slot name="error" {error} />
	{/await}

	<slot {ref} />
</T>
