The Sky Shader becomes a lump after post-processing


Figure 1 is the case when post-processing is not used, and in Figure 2 I use add-post-processing, and I only add the base render pass

This is a shared online case

https://codesandbox.io/p/sandbox/exciting-fog-nm5h3f

I can’t edit the codesandbox so I’m using a fiddle. Try it with the following code:

I’m like this because I need to use webgl anti-aliasing

const renderPass = new RenderPass(scene, camera);
let renderTargetOptions = { samples: 4 };
const size = renderer.getDrawingBufferSize(new THREE.Vector2());
const renderTarget = new THREE.WebGLRenderTarget(
size.width,
size.height,
renderTargetOptions
);
composer = new EffectComposer(renderer, renderTarget);
composer.setPixelRatio(window.devicePixelRatio);
composer.addPass(renderPass);
const outputPass = new OutputPass();
composer.addPass(outputPass);

If you create a custom render target, make sure it uses HalfFloatType as the texture type:

let renderTargetOptions = { samples: 4, type: THREE.HalfFloatType };

Otherwise the HDR workflow is broken.

@wenrenqiang you can try pasting the following code in the fiddle and should be able to see the sun.

This is your code with minor additions/changes suggested by @Mugen87.

You can replace the cdn.jsdelivr.net/npm with unpkg.com if that works better in your area.

HTML

<script type="importmap">
	{
		"imports": {
			"three": "https://cdn.jsdelivr.net/npm/three@0.170/build/three.module.js",
			"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170/examples/jsm/",
			"three/examples/jsm/": "https://cdn.jsdelivr.net/npm/three@0.170/examples/jsm/"
		}
	}
</script>

JS

import {
  WebGLRenderTarget,
  WebGLRenderer,
  Scene,
  PerspectiveCamera,
  HalfFloatType,
  MathUtils,
  Vector3,
  Vector2,
  ACESFilmicToneMapping,
} from "three";import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
import { Sky } from "three/examples/jsm/objects/Sky.js";
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
import { OutputPass } from "three/examples/jsm/postprocessing/OutputPass.js";

let renderer, scene, camera, controls;
let sky, effectController, sun, finalComposer;
init();
animate();

function init() {
  // renderer
  renderer = new WebGLRenderer( { antialias: true } );
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.autoClear = false;
  renderer.toneMapping = ACESFilmicToneMapping;
  renderer.toneMappingExposure = 0.5;
  document.body.appendChild(renderer.domElement);
  // scene
  scene = new Scene();

  // camera
  camera = new PerspectiveCamera(
    40,
    window.innerWidth / window.innerHeight,
    1,
    10000
  );
  controls = new OrbitControls(camera, renderer.domElement);
  initSKY();
  initPost();
}
function initSKY() {
  sun = new Vector3();
  effectController = {
    turbidity: 10,
    rayleigh: 3,
    mieCoefficient: 0.005,
    mieDirectionalG: 0.7,
    elevation: 2,
    azimuth: 180,
    exposure: renderer.toneMappingExposure,
  };
  sky = new Sky();
  sky.scale.setScalar(450000);
  scene.add(sky);
  guiChanged();
}
function initPost() {
  const renderPass = new RenderPass(scene, camera);
  let renderTargetOptions = { samples: 4, type: HalfFloatType };
  const size = renderer.getDrawingBufferSize(new Vector2());
  const renderTarget = new WebGLRenderTarget(
    size.width,
    size.height,
    renderTargetOptions
  );
  finalComposer = new EffectComposer(renderer, renderTarget);
  finalComposer.setPixelRatio(window.devicePixelRatio * 2);
  finalComposer.addPass(renderPass);
  const outputPass = new OutputPass();
  finalComposer.addPass(outputPass);
}

function animate() {
  requestAnimationFrame(animate);
  renderer.clear();
  // renderer.render(scene, camera);
  finalComposer.render();
}
function guiChanged() {
  const uniforms = sky.material.uniforms;
  uniforms["turbidity"].value = effectController.turbidity;
  uniforms["rayleigh"].value = effectController.rayleigh;
  uniforms["mieCoefficient"].value = effectController.mieCoefficient;
  uniforms["mieDirectionalG"].value = effectController.mieDirectionalG;
  const phi = MathUtils.degToRad(90 - effectController.elevation);
  const theta = MathUtils.degToRad(effectController.azimuth);
  sun.setFromSphericalCoords(1, phi, theta);
  uniforms["sunPosition"].value.copy(sun);
  renderer.toneMappingExposure = effectController.exposure;
  renderer.render(scene, camera);
}