import * as THREE from "three";

interface IParams {
    color?: THREE.ColorRepresentation, side?: THREE.Side
}

export class MeshMaterial extends THREE.ShaderMaterial {

    constructor(params: IParams) {
        super({
            side: params.side || THREE.FrontSide,
            uniforms: {
                color: { value: new THREE.Color(params.color || 0xffffff) },
            },
            defines: {},
            vertexShader: `
                varying vec2 vUv;
                varying vec3 vNormal;

                void main() {
                    vUv = uv;
                    vNormal = normalMatrix * normal;

                    // BackSide 背面法線會與正面法線相反
                    #ifdef FLIP_SIDED

                        vNormal = - vNormal;

                    #endif

                    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
                }
            `,
            fragmentShader: `
                uniform vec3 color;
                varying vec2 vUv;
                varying vec3 vNormal;

                #include <packing>

                void main() {

                    vec3 normal = normalize(vNormal);

                    float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;
                    
                    // DoubleSide 兩面可見
                    #ifdef DOUBLE_SIDED

                        normal *= faceDirection;

                    #endif

                    gl_FragColor = vec4( packNormalToRGB(normal), 1.0);
                }
            `,
        });
    }
}