Skip to content

Commit ff415d4

Browse files
authored
Fix: SpotlightMaterial sync shader code with drei + update example (#78)
* fix: sync shader code with drei * fix: update spotlight example
1 parent 9c07f55 commit ff415d4

File tree

2 files changed

+43
-39
lines changed

2 files changed

+43
-39
lines changed

.storybook/stories/volumetricSpotlight.stories.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,9 +127,6 @@ function setupSpotlight() {
127127
* Create depthTexture and DepthRender target
128128
*/
129129
function updateDepthTargets() {
130-
renderer.getSize(rendererSize)
131-
rendererSize.multiplyScalar(renderer.getPixelRatio())
132-
133130
if (depthTexture) depthTexture.dispose()
134131
depthTexture = new DepthTexture(volumeParams.depthResolution, volumeParams.depthResolution)
135132
depthTexture.format = DepthFormat
@@ -151,8 +148,8 @@ function updateDepthTargets() {
151148
window.addEventListener('resize', depthOnResize)
152149
} else {
153150
volumeMaterial.depth = null
154-
volumeMaterial.resolution.set(0, 0)
155151
window.removeEventListener('resize', depthOnResize)
152+
volumeMaterial.resolution.set(0, 0)
156153
}
157154
}
158155

@@ -173,7 +170,7 @@ function renderDepth() {
173170
function depthOnResize() {
174171
renderer.getSize(rendererSize)
175172
rendererSize.multiplyScalar(renderer.getPixelRatio())
176-
volumeMaterial.resolution.copy(renderer.getSize(rendererSize))
173+
volumeMaterial.resolution.copy(rendererSize)
177174
}
178175

179176
/**
@@ -259,7 +256,7 @@ function addSpotLightGui(gui: GUI) {
259256
})
260257

261258
volFolder.add(volumeParams, 'useDepth').onChange(updateDepthTargets)
262-
volFolder.add(volumeParams, 'depthResolution', 128, 2048, 1).onChange(updateDepthTargets)
259+
volFolder.add(volumeParams, 'depthResolution', 128, 2048, 128).onChange(updateDepthTargets)
263260
}
264261

265262
/**

src/materials/SpotLightMaterial.ts

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { Color, Vector2, Vector3, REVISION, type Texture } from 'three'
1+
import { Color, Vector2, Vector3, type Texture } from 'three'
22
import { shaderMaterial } from '../core/shaderMaterial'
3+
import { version } from '../helpers/constants'
34

45
type SpotLightMaterialProps = {
56
depth: Texture | null
@@ -31,67 +32,73 @@ export const SpotLightMaterial = shaderMaterial<SpotLightMaterialProps>(
3132
},
3233
/* glsl */ `
3334
varying vec3 vNormal;
34-
varying vec3 vWorldPosition;
3535
varying float vViewZ;
3636
varying float vIntensity;
3737
uniform vec3 spotPosition;
3838
uniform float attenuation;
3939
40+
#include <common>
41+
#include <logdepthbuf_pars_vertex>
42+
4043
void main() {
4144
// compute intensity
42-
vNormal = normalize( normalMatrix * normal );
43-
vec4 worldPosition = modelMatrix * vec4( position, 1.0 );
44-
vWorldPosition = worldPosition.xyz;
45+
vNormal = normalize(normalMatrix * normal);
46+
vec4 worldPosition = modelMatrix * vec4(position, 1);
4547
vec4 viewPosition = viewMatrix * worldPosition;
4648
vViewZ = viewPosition.z;
47-
float intensity = distance(worldPosition.xyz, spotPosition) / attenuation;
48-
intensity = 1.0 - clamp(intensity, 0.0, 1.0);
49-
vIntensity = intensity;
50-
// set gl_Position
51-
gl_Position = projectionMatrix * viewPosition;
5249
50+
vIntensity = 1.0 - saturate(distance(worldPosition.xyz, spotPosition) / attenuation);
51+
52+
gl_Position = projectionMatrix * viewPosition;
53+
54+
#include <logdepthbuf_vertex>
5355
}`,
5456
/* glsl */ `
55-
#include <packing>
56-
5757
varying vec3 vNormal;
58-
varying vec3 vWorldPosition;
58+
varying float vViewZ;
59+
varying float vIntensity;
60+
5961
uniform vec3 lightColor;
60-
uniform vec3 spotPosition;
61-
uniform float attenuation;
6262
uniform float anglePower;
6363
uniform sampler2D depth;
6464
uniform vec2 resolution;
6565
uniform float cameraNear;
6666
uniform float cameraFar;
67-
varying float vViewZ;
68-
varying float vIntensity;
6967
uniform float opacity;
7068
71-
float readDepth( sampler2D depthSampler, vec2 coord ) {
72-
float fragCoordZ = texture2D( depthSampler, coord ).x;
73-
float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);
69+
#include <packing>
70+
#include <logdepthbuf_pars_fragment>
71+
72+
float readDepth(sampler2D depthSampler, vec2 uv) {
73+
float fragCoordZ = texture(depthSampler, uv).r;
74+
75+
// https://github.com/mrdoob/three.js/issues/23072
76+
#ifdef USE_LOGDEPTHBUF
77+
float viewZ = 1.0 - exp2(fragCoordZ * log(cameraFar + 1.0) / log(2.0));
78+
#else
79+
float viewZ = perspectiveDepthToViewZ(fragCoordZ, cameraNear, cameraFar);
80+
#endif
81+
7482
return viewZ;
7583
}
7684
77-
void main() {
78-
float d = 1.0;
79-
bool isSoft = resolution[0] > 0.0 && resolution[1] > 0.0;
80-
if (isSoft) {
81-
vec2 sUv = gl_FragCoord.xy / resolution;
82-
d = readDepth(depth, sUv);
83-
}
84-
float intensity = vIntensity;
85-
vec3 normal = vec3(vNormal.x, vNormal.y, abs(vNormal.z));
86-
float angleIntensity = pow( dot(normal, vec3(0.0, 0.0, 1.0)), anglePower );
87-
intensity *= angleIntensity;
85+
void main() {
86+
#include <logdepthbuf_fragment>
87+
88+
vec3 normal = vec3(vNormal.x, vNormal.y, abs(vNormal.z));
89+
float angleIntensity = pow(dot(normal, vec3(0, 0, 1)), anglePower);
90+
float intensity = vIntensity * angleIntensity;
91+
8892
// fades when z is close to sampled depth, meaning the cone is intersecting existing geometry
93+
bool isSoft = resolution[0] > 0.0 && resolution[1] > 0.0;
8994
if (isSoft) {
90-
intensity *= smoothstep(0., 1., vViewZ - d);
95+
vec2 uv = gl_FragCoord.xy / resolution;
96+
intensity *= smoothstep(0.0, 1.0, vViewZ - readDepth(depth, uv));
9197
}
98+
9299
gl_FragColor = vec4(lightColor, intensity * opacity);
93100
94101
#include <tonemapping_fragment>
95-
#include <${parseInt(REVISION.replace(/\D+/g, '')) >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>
102+
#include <${version >= 154 ? 'colorspace_fragment' : 'encodings_fragment'}>
96103
}`
97104
)

0 commit comments

Comments
 (0)