UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

197 lines (158 loc) 5.71 kB
// import { Color, GLSL3, RawShaderMaterial, Vector2, Vector4 } from "three"; const shader_vx = ` in vec3 position; in vec3 normal; in vec2 uv; in vec3 color; in vec4 tangent; out vec3 vNormal; out vec3 vTangent; out vec3 vBinormal; out vec2 vUv; out mat3 TBN; out vec3 vColor; out float depth; uniform mat4 modelViewMatrix; uniform mat4 projectionMatrix; uniform mat3 normalMatrix; uniform vec4 projection_params; void main() { vUv = uv; vColor = color; // get smooth normals vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); vec3 transformedNormal = normalMatrix * normal; vec3 T = normalize(vec3(modelViewMatrix * tangent) ); vNormal = normalize( transformedNormal ); vec3 N = vNormal; vec3 B = cross(N,T); // construct Tangent Bitangent Normal matrix TBN = mat3(T,B,N); gl_Position = projectionMatrix * mvPosition; depth = 1.0 + (mvPosition.z * projection_params.w); } `; const shader_fg = ` precision highp float; precision highp int; layout(location = 0) out vec4 gColor; layout(location = 1) out vec4 gNormal; layout(location = 2) out vec4 gORM; uniform vec3 color; uniform sampler2D tDiffuse; uniform sampler2D tNormal; uniform sampler2D tRoughness; uniform sampler2D tMetalness; uniform sampler2D tOcclusion; uniform sampler2D tEmissive; uniform float uTextureLODBias; uniform vec2 uAtlasResolution; uniform vec2 repeat; in vec3 vNormal; in vec2 vUv; in mat3 TBN; in vec3 vColor; in float depth; vec4 texture_supersample_4(in sampler2D sampler, in vec2 uv, float lod_bias){ vec2 half_pixel_size = vec2(0.5) / uAtlasResolution; // per pixel partial derivatives vec2 dx = dFdx(uv.xy); vec2 dy = dFdy(uv.xy); // rotated grid uv offsets vec2 uvOffsets = vec2(0.125, 0.375); vec4 offsetUV = vec4(0.0, 0.0, 0.0, uTextureLODBias); float bias = -1.0 + lod_bias; // supersampled using 2x2 rotated grid vec4 col; offsetUV.xy = uv.xy + uvOffsets.x * dx + uvOffsets.y * dy; col += texture(sampler, offsetUV.xy, bias); offsetUV.xy = uv.xy - uvOffsets.x * dx - uvOffsets.y * dy; col += texture(sampler, offsetUV.xy, bias); offsetUV.xy = uv.xy + uvOffsets.y * dx - uvOffsets.x * dy; col += texture(sampler, offsetUV.xy, bias); offsetUV.xy = uv.xy - uvOffsets.y * dx + uvOffsets.x * dy; col += texture(sampler, offsetUV.xy, bias); col *= 0.25; return col; } void main() { // write color to G-Buffer vec4 diffuse_texture_sample = texture_supersample_4( tDiffuse, vUv, uTextureLODBias); if(diffuse_texture_sample.a < 0.5){ // alpha masking discard; } gColor = diffuse_texture_sample; gColor.rgb *= vColor; gColor.rgb *= color; // write normals to G-Buffer // see https://learnopengl.com/Advanced-Lighting/Normal-Mapping vec3 normal_sample = texture_supersample_4(tNormal, vUv,uTextureLODBias).rgb*2.0 - 1.0; vec3 normal = normalize(TBN * normal_sample); gNormal = vec4( normal*0.5 + 0.5, depth); float roughness = texture_supersample_4(tRoughness, vUv,uTextureLODBias).g; float metalness = texture_supersample_4(tMetalness, vUv,uTextureLODBias).b; float occlusion = texture_supersample_4(tOcclusion, vUv,uTextureLODBias).r; vec3 emissive = texture_supersample_4(tEmissive, vUv,uTextureLODBias).rgb; gORM = vec4(occlusion, roughness, metalness, 1.0); } `; /** * PBR shader: * - albedo + alpha * - normal * - roughness * - metalness * - ambient occlusion */ export class BakeShaderStandard extends RawShaderMaterial { constructor() { super({ vertexShader: shader_vx, fragmentShader: shader_fg, glslVersion: GLSL3, uniforms: { color: { value: new Color(1, 1, 1) }, tDiffuse: { value: null }, tNormal: { value: null }, tRoughness: { value: null }, tMetalness: { value: null }, tOcclusion: { value: null }, tEmissive: { value: null }, /** * @see https://docs.unity3d.com/2020.3/Documentation/Manual/SL-UnityShaderVariables.html */ projection_params: { value: new Vector4(0, 0, 0, 0) }, /** * Bias texture LOD, -0.5 pushes MIP switching a half a LOD further away, and produces more crisp-looking results */ uTextureLODBias:{ value:-0.5 }, uAtlasResolution:{ value: new Vector2(1,1) } } }); this.defaultAttributeValues.tangent = [ 1, 0, 0, 1 ]; } }