Skip to content

Commit 9784306

Browse files
committed
.
1 parent 57b54ad commit 9784306

File tree

3 files changed

+89
-111
lines changed

3 files changed

+89
-111
lines changed

src/lib/data/tasks.json

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

src/lib/data/tasks/VolumeRaymarching.md

Lines changed: 86 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -153,152 +153,131 @@ out vec4 fragColor;
153153
uniform vec3 cameraPosition;
154154
uniform vec3 cameraDirection;
155155
uniform sampler3D volumeTexture;
156-
uniform ivec2 iResolution; // <-- aspect correction
156+
uniform ivec2 iResolution;
157157
158-
const float stepSize = 0.005;
158+
const float stepSize = 0.001;
159159
const int maxSteps = 1024;
160160
const vec3 lightDir = normalize(vec3(1.0, 1.0, 0.0));
161161
const float orthoScale = 0.5;
162162
163-
// Gradient computation
164-
vec3 computeGradient(vec3 uvw) {
165-
float h = 0.005;
166-
float fx1 = texture(volumeTexture, clamp(uvw + vec3(h,0,0), 0.0, 1.0)).r;
167-
float fx2 = texture(volumeTexture, clamp(uvw - vec3(h,0,0), 0.0, 1.0)).r;
168-
float fy1 = texture(volumeTexture, clamp(uvw + vec3(0,h,0), 0.0, 1.0)).r;
169-
float fy2 = texture(volumeTexture, clamp(uvw - vec3(0,h,0), 0.0, 1.0)).r;
170-
float fz1 = texture(volumeTexture, clamp(uvw + vec3(0,0,h), 0.0, 1.0)).r;
171-
float fz2 = texture(volumeTexture, clamp(uvw - vec3(0,0,h), 0.0, 1.0)).r;
172-
return -vec3(fx1 - fx2, fy1 - fy2, fz1 - fz2);
163+
vec3 ComputeGradient(vec3 UVW) {
164+
vec3 H = 1.0 / vec3(textureSize(volumeTexture, 0)); // Texelgröße
165+
166+
float Fx1 = texture(volumeTexture, clamp(UVW + vec3(H.x, 0.0, 0.0), 0.0, 1.0)).r; // +x Probe
167+
float Fx2 = texture(volumeTexture, clamp(UVW - vec3(H.x, 0.0, 0.0), 0.0, 1.0)).r; // -x Probe
168+
169+
float Fy1 = texture(volumeTexture, clamp(UVW + vec3(0.0, H.y, 0.0), 0.0, 1.0)).r; // +y Probe
170+
float Fy2 = texture(volumeTexture, clamp(UVW - vec3(0.0, H.y, 0.0), 0.0, 1.0)).r; // -y Probe
171+
172+
float Fz1 = texture(volumeTexture, clamp(UVW + vec3(0.0, 0.0, H.z), 0.0, 1.0)).r; // +z Probe
173+
float Fz2 = texture(volumeTexture, clamp(UVW - vec3(0.0, 0.0, H.z), 0.0, 1.0)).r; // -z Probe
174+
175+
return normalize(-vec3(Fx1 - Fx2, Fy1 - Fy2, Fz1 - Fz2)); // Zentraldiff, Negation
173176
}
174177
175-
// Transfer function
176-
vec4 transferFunction(float f, float gradMag) {
177-
// Representative CT numbers (HU)
178-
const float f_air = -750.0;
179-
const float f_tissue = 50.0;
180-
const float f_bone = 700.0;
181-
182-
// Assigned alpha values (Opacity)
183-
const float a_air = 0.0; // Transparent
184-
const float a_tissue = 0.2; // Medium opacity
185-
const float a_bone = 1.0; // Strong opacity
186-
187-
// Assigned colors
188-
const vec3 c_air = vec3(0.0); // Air
189-
const vec3 c_tissue = vec3(0.9, 0.7, 0.6); // Skin-tone
190-
const vec3 c_bone = vec3(1.0, 1.0, 0.95); // White/Ivory
191-
192-
// initial
178+
vec4 TransferFunction(float F, float gradientMagnitude) {
179+
const float huAir = -750.0;
180+
const float huTissue = 50.0;
181+
const float huBone = 700.0;
182+
183+
const float alphaAir = 0.0;
184+
const float alphaTissue = 0.02;
185+
const float alphaBone = 1.0;
186+
187+
const vec3 colorAir = vec3(0.0);
188+
const vec3 colorTissue = vec3(0.9, 0.7, 0.6);
189+
const vec3 colorBone = vec3(1.0, 1.0, 0.95);
190+
193191
float alpha = 0.0;
194-
vec3 color = c_air;
195-
196-
if (f >= f_air && f <= f_tissue) {
197-
// Between air and soft tissue
198-
float t = (f - f_air) / (f_tissue - f_air);
199-
alpha = mix(a_air, a_tissue, t);
200-
color = mix(c_air, c_tissue, t);
201-
} else if (f >= f_tissue && f <= f_bone) {
202-
// Between tissue and bone
203-
float t = (f - f_tissue) / (f_bone - f_tissue);
204-
alpha = mix(a_tissue, a_bone, t);
205-
color = mix(c_tissue, c_bone, t);
206-
} else if (f > f_bone) {
207-
// Denser than bone
208-
alpha = a_bone;
209-
color = c_bone;
192+
vec3 Color = colorAir;
193+
194+
if (F >= huAir && F <= huTissue) {
195+
float T = (F - huAir) / (huTissue - huAir); // Air >Tissue Mix
196+
alpha = mix(alphaAir, alphaTissue, T);
197+
Color = mix(colorAir, colorTissue, T);
198+
} else if (F >= huTissue && F <= huBone) {
199+
float T = (F - huTissue) / (huBone - huTissue); // Tissue > Bone Mix
200+
alpha = mix(alphaTissue, alphaBone, T);
201+
Color = mix(colorTissue, colorBone, T);
202+
} else if (F > huBone) {
203+
alpha = alphaBone; // Bone+
204+
Color = colorBone;
210205
}
211206
212-
// Multiply opacity by gradient magnitude
213-
// alpha = clamp(alpha * gradMag * 2.0, 0.0, 1.0);
207+
// hermit Interpolation zwischen 0 und 1, lower bound, upper bound, source Wert
208+
alpha *= smoothstep(0.05, 0.2, gradientMagnitude); // Übergang mit Gradient verstärken
214209
215-
return vec4(color, alpha);
210+
return vec4(Color, alpha);
216211
}
217212
213+
vec3 PhongShade(vec3 N, vec3 BaseColor, vec3 ViewDir, vec3 lightDir) {
214+
const vec3 Ka = vec3(0.5); // Ambient
215+
const vec3 Kd = vec3(0.5); // Diffus
216+
const vec3 Ks = vec3(1.0); // Spekular
217+
const float NExp = 20.0; // Rauheit
218218
219-
// Phong shading
220-
vec3 phongShade(vec3 N, vec3 baseColor, vec3 viewDir, vec3 lightDir) {
221-
const vec3 ka = vec3(0.5);
222-
const vec3 kd = vec3(0.6);
223-
const vec3 ks = vec3(0.3);
224-
const float n = 20.0;
225-
226-
vec3 H = normalize(viewDir + lightDir);
227-
float diff = max(dot(N, lightDir), 0.0);
228-
float spec = pow(max(dot(N, H), 0.0), n);
219+
vec3 H = normalize(ViewDir + lightDir); // Halfvector
220+
float Diff = max(dot(N, lightDir), 0.0); // Diffus
221+
float Spec = pow(max(dot(N, H), 0.0), NExp); // Spekular
229222
230-
return baseColor * (ka + kd * diff) + ks * spec;
223+
return BaseColor * (Ka + Kd * Diff) + Ks * Spec;
231224
}
232225
233-
// Ray generation (aspect-corrected)
234-
void generateRay(out vec3 rayOrigin, out vec3 rayDir) {
235-
// compute aspect ratio from iResolution
236-
float aspect = float(iResolution.x) / float(iResolution.y);
237-
238-
// If vUv is already in -1..1, you may not want to remap; here we follow the existing use
239-
// and simply scale the X component to correct for aspect.
240-
vec2 uv = vUv;
241-
uv.x *= aspect;
226+
void GenerateRay(out vec3 rayOrigin, out vec3 rayDir) {
227+
float Aspect = float(iResolution.x) / float(iResolution.y); // Seitenverhältnis aus Uniform
228+
vec2 UV = vUv;
229+
UV.x *= Aspect; // Korrigiert X-Skalierung
242230
231+
// Orthogonale Basis bilden
243232
vec3 forward = normalize(cameraDirection);
244-
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
245-
vec3 up = cross(right, forward);
233+
vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
234+
vec3 up = cross(right, forward);
246235
247236
rayDir = forward;
248-
// scale the right offset by the corrected uv.x
249-
rayOrigin = cameraPosition + uv.x * right * orthoScale + uv.y * up * orthoScale;
237+
rayOrigin = cameraPosition + UV.x * right * orthoScale + UV.y * up * orthoScale; // Ortho Offset
250238
}
251239
252-
// Sample volume
253-
vec4 sampleVolume(vec3 uvw, vec3 rayDir) {
254-
float f = texture(volumeTexture, uvw).r - 1100.0; // texture is raised by 1100
255-
vec3 grad = computeGradient(uvw);
256-
float gradMag = length(grad);
240+
vec4 SampleVolume(vec3 UVW, vec3 rayDir) {
241+
float F = texture(volumeTexture, UVW).r - 1100.0; // HU-Korrektur weil Textur Werte um 1100 angehoben
242+
vec3 Grad = ComputeGradient(UVW); // Gradient berechnen für Phong Normale
243+
float gradientMagnitude = length(Grad);
257244
258-
// Call transfer function to get material properties
259-
vec4 material = transferFunction(f, gradMag);
260-
261-
vec3 shaded = phongShade(normalize(grad), material.rgb, normalize(-rayDir), lightDir);
245+
vec4 Mat = TransferFunction(F, gradientMagnitude); // Materialdaten
246+
vec3 Shaded = PhongShade(normalize(Grad), Mat.rgb, normalize(-rayDir), lightDir); // Beleuchtung
262247
263-
return vec4(shaded, material.a);
248+
return vec4(Shaded, Mat.a); // Farbe + alpha
264249
}
265250
266251
void main() {
267252
vec3 rayOrigin, rayDir;
268-
generateRay(rayOrigin, rayDir);
253+
GenerateRay(rayOrigin, rayDir); // Strahl erzeugen
269254
270-
float tNear = 0.01; // Start slightly away from the camera
271-
float tFar = 2.0; // March a distance guaranteed to pass through the volume
255+
float TNear = 0.01; // Start
256+
float TFar = 2.0; // Ende
272257
273-
vec3 colorAccum = vec3(0.0);
274-
float alphaAccum = 0.0;
258+
vec3 ColorAccum = vec3(0.0); // Farbspeicher
259+
float alphaAccum = 0.0; // alphaakkumulation
275260
276-
// Calculate number of steps based on the assumed marching length
277-
float rayLength = tFar - tNear;
278-
int steps = min(int(rayLength / stepSize), maxSteps);
261+
float RayLength = TFar - TNear;
262+
int Steps = min(int(RayLength / stepSize), maxSteps); // Schrittanzahl
279263
280-
// Ray marching loop
281-
// Back-to-front compositing
282-
for (int i = steps - 1; i >= 0; --i) {
283-
float t = tNear + float(i) * stepSize;
284-
vec3 p = rayOrigin + rayDir * t;
285-
vec3 uvw = p + 0.5;
264+
for (int I = Steps - 1; I >= 0; --I) { // Rückwärtslauf wegen Back to Front
265+
float T = TNear + float(I) * stepSize; // Distanz auf dem Strahl
266+
vec3 P = rayOrigin + rayDir * T; // Punkt im Raum
267+
vec3 UVW = P + 0.5; // Sample In Texturraum
286268
287-
// Bounding box check (to ensure we only sample the texture)
288-
// This acts as an implicit boundary for the volume.
289-
if (any(lessThan(uvw, vec3(0.0))) || any(greaterThan(uvw, vec3(1.0))))
269+
if (any(lessThan(UVW, vec3(0.0))) || any(greaterThan(UVW, vec3(1.0)))) // Bounds check
290270
continue;
291271
292-
vec4 s = sampleVolume(uvw, rayDir);
293-
float a = s.a;
294-
vec3 c = s.rgb;
272+
vec4 S = SampleVolume(UVW, rayDir); // Volume Abtasten
273+
float A = S.a;
274+
vec3 C = S.rgb;
295275
296-
// 'Over' operator
297-
colorAccum = c * a + colorAccum * (1.0 - a);
298-
alphaAccum = a + alphaAccum * (1.0 - a);
276+
ColorAccum = C * A + ColorAccum * (1.0 - A); // Over Operator
277+
alphaAccum = A + alphaAccum * (1.0 - A); // alpha add
299278
}
300279
301-
fragColor = vec4(colorAccum, 1.0);
280+
fragColor = vec4(ColorAccum, 1.0);
302281
}
303282
```
304283

src/lib/renderer/ShaderTaskMaterial.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,12 @@ export class ShaderTaskMaterial extends THREE.RawShaderMaterial {
3939
super({
4040
vertexShader: params.vertexShader,
4141
fragmentShader: params.fragmentShader,
42-
uniforms: {}, // This correctly initializes the *inherited* `this.uniforms`
42+
uniforms: {}, // This initializes the inherited `this.uniforms`
4343
glslVersion: THREE.GLSL3
4444
});
4545

4646
this.vertexShader = params.vertexShader;
4747
this.fragmentShader = params.fragmentShader;
48-
// `this.uniforms` is now correctly initialized to {} by the `super()` call.
4948
this.needsUpdate = true;
5049

5150
if (params.inputs) {

0 commit comments

Comments
 (0)