UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

174 lines (125 loc) 5.43 kB
import { GLSL3, ShaderMaterial, Vector2, Vector3 } from "three"; import { ParameterLookupTable } from "../../../particles/particular/engine/parameter/ParameterLookupTable.js"; import { Sampler2D } from "../../../texture/sampler/Sampler2D.js"; import sampler2d_to_texture from "../../../texture/sampler/sampler2d_to_texture.js"; const v_shader = ` varying vec3 v_v3_clip_position; void main() { vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); mat4 mat = projectionMatrix; gl_Position = projectionMatrix * mvPosition; vec3 ndc = gl_Position.xyz / gl_Position.w; v_v3_clip_position = (ndc)*0.5 + 0.5; // convert clip coordinate to linear scale //v_v3_clip_position.z = convert_depth_to_linear(v_v3_clip_position.z); } `; const f_shader = ` precision mediump usampler3D; uniform usampler3D fp_t_light_tiles; uniform vec3 fp_v3_light_cluster_resolution; uniform float fp_f_camera_near; uniform float fp_f_camera_far; uniform sampler2D t_heatmap_lookup; uniform vec2 fp_resolution; uniform mat4 projectionMatrix; varying vec3 v_v3_clip_position; out vec4 pc_fragColor; float convert_depth_to_linear_m(in float depth){ float f = fp_f_camera_far; float n = fp_f_camera_near; float z_diff = f - n; float A = projectionMatrix[2][2]; float B = projectionMatrix[3][2]; float z_ndc = 2.0 * depth - 1.0; float z_eye = B / (A + z_ndc); return z_eye / z_diff; } float convert_depth_to_linear(in float d){ float d_n = 2.0*d - 1.0; float f = fp_f_camera_far; float n = fp_f_camera_near; float fn = f*n; float z_diff = f - n; float denominator = (f + n - d_n * z_diff ); float z_view = (2.0*fn) / denominator; return (z_view - n) / z_diff; } void main(){ vec3 clip_v = vec3(gl_FragCoord.xy / fp_resolution, convert_depth_to_linear( gl_FragCoord.z)); ivec3 v3_cluster_resolution = textureSize(fp_t_light_tiles, 0); ivec3 v3_cluster_position = ivec3( ( 1.0 - clip_v.x) * float(v3_cluster_resolution.x), clip_v.y*float(v3_cluster_resolution.y), (clip_v.z)*float(v3_cluster_resolution.z) ); uvec3 cluster_metadata = texelFetch(fp_t_light_tiles, v3_cluster_position , 0).rgb; // gl_FragColor = vec4(v_v3_clip_position, 1.0); vec4 color = texture2D( t_heatmap_lookup, vec2(float(cluster_metadata.y)/16.0, 0.5) ).rgba; // gl_FragColor = texture2D( t_heatmap_lookup, vec2(gl_FragCoord.z, 0.5) ).rgba; // gl_FragColor = texture2D( t_heatmap_lookup, vec2(clip_v.z, 0.5) ).rgba; pc_fragColor = vec4(color.rgb, 1.0); // gl_FragColor = vec4(clip_v.zzz, 1.0); // gl_FragColor = vec4(gl_FragCoord.z,gl_FragCoord.z/2.0+ 0.5,1.0, 1.0); // gl_FragColor = vec4(gl_FragCoord.z*0.5+0.5,gl_FragCoord.z*0.5+0.5,1.0, 1.0); } `; export class FPlusDebugMaterial extends ShaderMaterial { constructor() { super({ uniforms: { fp_t_light_tiles: { type: 't', value: null }, fp_v3_light_cluster_resolution: { type: 'v3', value: new Vector3() }, fp_f_camera_near: { type: 'f', value: 0 }, fp_f_camera_far: { type: 'f', value: 0 }, fp_resolution: { type: 'v2', value: new Vector2() }, t_heatmap_lookup: { type: 't', value: null } }, vertexShader: v_shader, fragmentShader: f_shader, glslVersion: GLSL3 }); const heatmap_lut = new ParameterLookupTable(4); heatmap_lut.write([ 0, 0, 0, 255, 80, 0, 100, 255, 0, 0, 255, 255, 0, 179, 179, 255, 0, 255, 0, 255, 255, 255, 0, 255, 255, 5, 5, 255 ]); const heatmap_sampler = Sampler2D.uint8(4, 32, 1); const r = []; for (let i = 0; i < heatmap_sampler.width; i++) { heatmap_lut.sample(i / (heatmap_sampler.width - 1), r); heatmap_sampler.write(i, 0, r); } const heatmap_texture = sampler2d_to_texture(heatmap_sampler); this.uniforms.t_heatmap_lookup.value = heatmap_texture; } /** * * @param {LightManager} light_manager */ attach_lights(light_manager) { const uniforms = this.uniforms; uniforms['fp_t_light_tiles'].value = light_manager.getTextureClusters(); uniforms['fp_v3_light_cluster_resolution'].value.copy(light_manager.getResolution()); } }