diff --git a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts index 3291a6499..4d63d5b76 100644 --- a/packages/core/src/RenderPipeline/BasicRenderPipeline.ts +++ b/packages/core/src/RenderPipeline/BasicRenderPipeline.ts @@ -203,8 +203,8 @@ export class BasicRenderPipeline { // Scalable ambient obscurance pass // Before opaque pass so materials can sample ambient occlusion in BRDF - if (ambientOcclusionEnabled && supportDepthTexture) { - const saoPass = this._saoPass; + const saoPass = this._saoPass; + if (ambientOcclusionEnabled && supportDepthTexture && saoPass.isSupported) { saoPass.onConfig(camera, this._depthOnlyPass.renderTarget); saoPass.onRender(context); } else { diff --git a/packages/core/src/lighting/ambientOcclusion/ScalableAmbientObscurancePass.ts b/packages/core/src/lighting/ambientOcclusion/ScalableAmbientObscurancePass.ts index 8d20ae8b6..b57d62ca9 100644 --- a/packages/core/src/lighting/ambientOcclusion/ScalableAmbientObscurancePass.ts +++ b/packages/core/src/lighting/ambientOcclusion/ScalableAmbientObscurancePass.ts @@ -29,6 +29,8 @@ export class ScalableAmbientObscurancePass extends PipelinePass { private static _powerProp = ShaderProperty.getByName("material_power"); private static _invProjScaleXYProp = ShaderProperty.getByName("material_invProjScaleXY"); + readonly isSupported: boolean; + // Shader properties for bilateral blur private static _farPlaneOverEdgeDistanceProp = ShaderProperty.getByName("material_farPlaneOverEdgeDistance"); private static _kernelProp = ShaderProperty.getByName("material_kernel"); @@ -52,6 +54,7 @@ export class ScalableAmbientObscurancePass extends PipelinePass { const material = new Material(engine, Shader.find(ScalableAmbientObscurancePass.SHADER_NAME)); material._addReferCount(1); this._material = material; + this.isSupported = this.engine._hardwareRenderer.capability.isFragmentHighPrecision; } onConfig(camera: Camera, depthRenderTarget: RenderTarget): void { diff --git a/packages/core/src/lighting/ambientOcclusion/shaders/ScalableAmbientOcclusion.glsl b/packages/core/src/lighting/ambientOcclusion/shaders/ScalableAmbientOcclusion.glsl index 287f1f58b..b12655ff2 100644 --- a/packages/core/src/lighting/ambientOcclusion/shaders/ScalableAmbientOcclusion.glsl +++ b/packages/core/src/lighting/ambientOcclusion/shaders/ScalableAmbientOcclusion.glsl @@ -7,7 +7,7 @@ varying vec2 v_uv; uniform vec4 renderer_texelSize; // x: 1/width, y: 1/height, z: width, w: height -uniform sampler2D renderer_BlitTexture; // Camera_DepthTexture +uniform highp sampler2D renderer_BlitTexture; // Camera_DepthTexture // float inc = (1.0f / (SAMPLE_COUNT - 0.5f)) * SPIRAL_TURNS * 2.0 * PI // const vec2 angleIncCosSin = vec2(cos(inc), sin(inc)) @@ -50,7 +50,7 @@ float depthToViewZ(float depth) { // reconstructing normal from depth buffer // https://atyuwen.github.io/posts/normal-reconstruction // https://wickedengine.net/2019/09/22/improved-normal-reconstruction-from-depth/ -vec3 computeViewSpaceNormal(vec2 uv, sampler2D depthTexture, float depth, vec3 viewPos, vec2 texel, vec2 invProjScaleXY) { +vec3 computeViewSpaceNormal(vec2 uv, highp sampler2D depthTexture, float depth, vec3 viewPos, vec2 texel, vec2 invProjScaleXY) { vec3 normal = vec3(0.0); #if SSAO_QUALITY == 0 || SSAO_QUALITY == 1 vec2 uvdx = uv + vec2(texel.x, 0.0); diff --git a/packages/rhi-webgl/src/GLCapability.ts b/packages/rhi-webgl/src/GLCapability.ts index 4df9158e0..3aa8cbd3b 100644 --- a/packages/rhi-webgl/src/GLCapability.ts +++ b/packages/rhi-webgl/src/GLCapability.ts @@ -72,6 +72,11 @@ export class GLCapability { return this._maxAntiAliasing; } + get isFragmentHighPrecision(): boolean { + const gl = this._rhi.gl; + return gl.getShaderPrecisionFormat(gl.FRAGMENT_SHADER, gl.HIGH_FLOAT).precision !== 0; + } + get rhi() { return this._rhi; }