UNPKG

@animech-public/playcanvas

Version:
2 lines (1 loc) 7.67 kB
import{math as t}from"../../core/math/math.js";import{Color as e}from"../../core/math/color.js";import{RenderPassShaderQuad as n}from"../../scene/graphics/render-pass-shader-quad.js";import{shaderChunks as s}from"../../scene/shader-lib/chunks/chunks.js";import{TONEMAP_ACES2 as r,TONEMAP_NEUTRAL as i,TONEMAP_ACES as a,TONEMAP_HEJL as o,TONEMAP_FILMIC as g,TONEMAP_LINEAR as h}from"../../scene/constants.js";class u extends n{constructor(t){super(t),this.sceneTexture=null,this.bloomIntensity=.01,this._bloomTexture=null,this._toneMapping=r,this._gradingEnabled=!1,this.gradingSaturation=1,this.gradingContrast=1,this.gradingBrightness=1,this._shaderDirty=!0,this._vignetteEnabled=!1,this.vignetteInner=.5,this.vignetteOuter=1,this.vignetteCurvature=.5,this.vignetteIntensity=.3,this._fringingEnabled=!1,this.fringingIntensity=10,this._taaEnabled=!1,this._sharpness=.5,this._key="";const{scope:e}=t;this.sceneTextureId=e.resolve("sceneTexture"),this.bloomTextureId=e.resolve("bloomTexture"),this.bloomIntensityId=e.resolve("bloomIntensity"),this.bcsId=e.resolve("brightnessContrastSaturation"),this.vignetterParamsId=e.resolve("vignetterParams"),this.fringingIntensityId=e.resolve("fringingIntensity"),this.sceneTextureInvResId=e.resolve("sceneTextureInvRes"),this.sceneTextureInvResValue=new Float32Array(2),this.sharpnessId=e.resolve("sharpness")}set bloomTexture(t){this._bloomTexture!==t&&(this._bloomTexture=t,this._shaderDirty=!0)}get bloomTexture(){return this._bloomTexture}set taaEnabled(t){this._taaEnabled!==t&&(this._taaEnabled=t,this._shaderDirty=!0)}get taaEnabled(){return this._taaEnabled}set gradingEnabled(t){this._gradingEnabled!==t&&(this._gradingEnabled=t,this._shaderDirty=!0)}get gradingEnabled(){return this._gradingEnabled}set vignetteEnabled(t){this._vignetteEnabled!==t&&(this._vignetteEnabled=t,this._shaderDirty=!0)}get vignetteEnabled(){return this._vignetteEnabled}set fringingEnabled(t){this._fringingEnabled!==t&&(this._fringingEnabled=t,this._shaderDirty=!0)}get fringingEnabled(){return this._fringingEnabled}set toneMapping(t){this._toneMapping!==t&&(this._toneMapping=t,this._shaderDirty=!0)}get toneMapping(){return this._toneMapping}get toneMapChunk(){switch(this.toneMapping){case h:return s.tonemappingLinearPS;case g:return s.tonemappingFilmicPS;case o:return s.tonemappingHejlPS;case a:return s.tonemappingAcesPS;case r:return s.tonemappingAces2PS;case i:return s.tonemappingNeutralPS}return s.tonemappingNonePS}set sharpness(t){this._sharpness!==t&&(this._sharpness=t,this._shaderDirty=!0)}get sharpness(){return this._sharpness}get isSharpnessEnabled(){return this._sharpness>0}postInit(){this.setClearColor(e.BLACK),this.setClearDepth(1),this.setClearStencil(0)}frameUpdate(){if(this._shaderDirty){this._shaderDirty=!1;const t=`${this.toneMapping}-`+(this.bloomTexture?"bloom":"nobloom")+"-"+(this.gradingEnabled?"grading":"nograding")+"-"+(this.vignetteEnabled?"vignette":"novignette")+"-"+(this.fringingEnabled?"fringing":"nofringing")+"-"+(this.taaEnabled?"taa":"notaa")+"-"+(this.isSharpnessEnabled?"cas":"nocas");if(this._key!==t){this._key=t;const e=(this.bloomTexture?"#define BLOOM\n":"")+(this.gradingEnabled?"#define GRADING\n":"")+(this.vignetteEnabled?"#define VIGNETTE\n":"")+(this.fringingEnabled?"#define FRINGING\n":"")+(this.taaEnabled?"#define TAA\n":"")+(this.isSharpnessEnabled?"#define CAS\n":""),n=s.decodePS+s.gamma2_2PS+this.toneMapChunk;this.shader=this.createQuadShader(`ComposeShader-${t}`,e+n+"\n\tvarying vec2 uv0;\n\tuniform sampler2D sceneTexture;\n\tuniform vec2 sceneTextureInvRes;\n\t#ifdef BLOOM\n\t\tuniform sampler2D bloomTexture;\n\t\tuniform float bloomIntensity;\n\t#endif\n\t#ifdef GRADING\n\t\tuniform vec3 brightnessContrastSaturation;\n\t\tvec3 contrastSaturationBrightness(vec3 color, float brt, float sat, float con)\n\t\t{\n\t\t\tcolor = color * brt;\n\t\t\tfloat grey = dot(color, vec3(0.3, 0.59, 0.11));\n\t\t\tcolor = mix(vec3(grey), color, sat);\n\t\t\treturn max(mix(vec3(0.5), color, con), 0.0);\n\t\t}\n\t\n\t#endif\n\t#ifdef VIGNETTE\n\t\tuniform vec4 vignetterParams;\n\t\tfloat vignette(vec2 uv) {\n\t\t\tfloat inner = vignetterParams.x;\n\t\t\tfloat outer = vignetterParams.y;\n\t\t\tfloat curvature = vignetterParams.z;\n\t\t\tfloat intensity = vignetterParams.w;\n\t\t\tvec2 curve = pow(abs(uv * 2.0 -1.0), vec2(1.0 / curvature));\n\t\t\tfloat edge = pow(length(curve), curvature);\n\t\t\treturn 1.0 - intensity * smoothstep(inner, outer, edge);\n\t\t}\t\t\n\t#endif\n\t#ifdef FRINGING\n\t\tuniform float fringingIntensity;\n\t\tvec3 fringing(vec2 uv, vec3 color) {\n\t\t\tvec2 centerDistance = uv0 - 0.5;\n\t\t\tvec2 offset = fringingIntensity * pow(centerDistance, vec2(2.0, 2.0));\n\t\t\tcolor.r = texture2D(sceneTexture, uv0 - offset).r;\n\t\t\tcolor.b = texture2D(sceneTexture, uv0 + offset).b;\n\t\t\treturn color;\n\t\t}\n\t#endif\n\t#ifdef CAS\n\t\tuniform float sharpness;\n\t\tfloat maxComponent(float x, float y, float z) { return max(x, max(y, z)); }\n\t\tvec3 toSDR(vec3 c) { return c / (1.0 + maxComponent(c.r, c.g, c.b)); }\n\t\tvec3 toHDR(vec3 c) { return c / (1.0 - maxComponent(c.r, c.g, c.b)); }\n\t\tvec3 cas(vec3 color, vec2 uv, float sharpness) {\n\t\t\tfloat x = sceneTextureInvRes.x;\n\t\t\tfloat y = sceneTextureInvRes.y;\n\t\t\tvec3 a = toSDR(texture2DLodEXT(sceneTexture, uv + vec2(0.0, -y), 0.0).rgb);\n\t\t\tvec3 b = toSDR(texture2DLodEXT(sceneTexture, uv + vec2(-x, 0.0), 0.0).rgb);\n\t\t\tvec3 c = toSDR(color.rgb);\n\t\t\tvec3 d = toSDR(texture2DLodEXT(sceneTexture, uv + vec2(x, 0.0), 0.0).rgb);\n\t\t\tvec3 e = toSDR(texture2DLodEXT(sceneTexture, uv + vec2(0.0, y), 0.0).rgb);\n\t\t\tfloat min_g = min(a.g, min(b.g, min(c.g, min(d.g, e.g))));\n\t\t\tfloat max_g = max(a.g, max(b.g, max(c.g, max(d.g, e.g))));\n\t\t\tfloat sharpening_amount = sqrt(min(1.0 - max_g, min_g) / max_g);\n\t\t\tfloat w = sharpening_amount * sharpness;\n\t\t\tvec3 res = (w * (a + b + d + e) + c) / (4.0 * w + 1.0);\n\t\t\treturn toHDR(res);\n\t\t}\n\t#endif\n\tvoid main() {\n\t\tvec2 uv = uv0;\n\t\t#ifdef TAA\n\t\t#ifdef WEBGPU\n\t\t\tuv.y = 1.0 - uv.y;\n\t\t#endif\n\t\t#endif\n\t\tvec4 scene = texture2DLodEXT(sceneTexture, uv, 0.0);\n\t\tvec3 result = scene.rgb;\n\t\t#ifdef CAS\n\t\t\tresult = cas(result, uv, sharpness);\n\t\t#endif\n\t\t#ifdef FRINGING\n\t\t\tresult = fringing(uv, result);\n\t\t#endif\n\t\t#ifdef BLOOM\n\t\t\tvec3 bloom = texture2DLodEXT(bloomTexture, uv, 0.0).rgb;\n\t\t\tresult += bloom * bloomIntensity;\n\t\t#endif\n\t\t#ifdef GRADING\n\t\t\tresult = contrastSaturationBrightness(result, brightnessContrastSaturation.x, brightnessContrastSaturation.z, brightnessContrastSaturation.y);\n\t\t#endif\n\t\tresult = toneMap(result);\n\t\t#ifdef VIGNETTE\n\t\t\tresult *= vignette(uv);\n\t\t#endif\n\t\tresult = gammaCorrectOutput(result);\n\t\tgl_FragColor = vec4(result, scene.a);\n\t}\n")}}}execute(){this.sceneTextureId.setValue(this.sceneTexture),this.sceneTextureInvResValue[0]=1/this.sceneTexture.width,this.sceneTextureInvResValue[1]=1/this.sceneTexture.height,this.sceneTextureInvResId.setValue(this.sceneTextureInvResValue),this._bloomTexture&&(this.bloomTextureId.setValue(this._bloomTexture),this.bloomIntensityId.setValue(this.bloomIntensity)),this._gradingEnabled&&this.bcsId.setValue([this.gradingBrightness,this.gradingContrast,this.gradingSaturation]),this._vignetteEnabled&&this.vignetterParamsId.setValue([this.vignetteInner,this.vignetteOuter,this.vignetteCurvature,this.vignetteIntensity]),this._fringingEnabled&&this.fringingIntensityId.setValue(this.fringingIntensity/1024),this.isSharpnessEnabled&&this.sharpnessId.setValue(t.lerp(-.125,-.2,this.sharpness)),super.execute()}}export{u as RenderPassCompose};