add z down shader filter

This commit is contained in:
Stewart Allen 2026-01-07 00:41:47 -05:00
commit da6561093f
2 changed files with 36 additions and 16 deletions

View file

@ -118,6 +118,8 @@ function addPaintOverlaySimple(material, paintPoints, paintColor = new THREE.Col
` `
); );
// Don't pass normals from vertex shader at all - we'll use fragment shader's normal
shader.vertexShader = ` shader.vertexShader = `
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
` + shader.vertexShader; ` + shader.vertexShader;
@ -135,6 +137,13 @@ function addPaintOverlaySimple(material, paintPoints, paintColor = new THREE.Col
` `
#include <dithering_fragment> #include <dithering_fragment>
// Compute world-space normal from position derivatives
vec3 posDx = dFdx(vWorldPosition);
vec3 posDy = dFdy(vWorldPosition);
vec3 worldNormal = normalize(cross(posDx, posDy));
// HARDCODED TEST: only paint if normal.z < 0 (downward facing)
if (worldNormal.z < 0.0) {
// Check if this fragment is within any paint sphere // Check if this fragment is within any paint sphere
bool painted = false; bool painted = false;
@ -155,6 +164,7 @@ function addPaintOverlaySimple(material, paintPoints, paintColor = new THREE.Col
// Blend paint color with existing fragment color (increased to 0.7 for visibility) // Blend paint color with existing fragment color (increased to 0.7 for visibility)
gl_FragColor.rgb = mix(gl_FragColor.rgb, paintColor, 0.7); gl_FragColor.rgb = mix(gl_FragColor.rgb, paintColor, 0.7);
} }
} // End normal check
// DEBUG: Uncomment to tint entire mesh when shader is active (proves shader is running) // DEBUG: Uncomment to tint entire mesh when shader is active (proves shader is running)
// if (paintCount > 0) { // if (paintCount > 0) {
@ -245,6 +255,8 @@ function addPaintOverlayTexture(material, paintPoints, paintColor = new THREE.Co
` `
); );
// Don't pass normals from vertex shader at all - we'll use fragment shader's normal
shader.vertexShader = ` shader.vertexShader = `
varying vec3 vWorldPosition; varying vec3 vWorldPosition;
` + shader.vertexShader; ` + shader.vertexShader;
@ -263,6 +275,13 @@ function addPaintOverlayTexture(material, paintPoints, paintColor = new THREE.Co
` `
#include <dithering_fragment> #include <dithering_fragment>
// Compute world-space normal from position derivatives
vec3 posDx = dFdx(vWorldPosition);
vec3 posDy = dFdy(vWorldPosition);
vec3 worldNormal = normalize(cross(posDx, posDy));
// HARDCODED TEST: only paint if normal.z < 0 (downward facing)
if (worldNormal.z < 0.0) {
bool painted = false; bool painted = false;
// Iterate through paint points stored in texture // Iterate through paint points stored in texture
@ -293,6 +312,7 @@ function addPaintOverlayTexture(material, paintPoints, paintColor = new THREE.Co
// Blend paint color with existing fragment color (increased to 0.7 for visibility) // Blend paint color with existing fragment color (increased to 0.7 for visibility)
gl_FragColor.rgb = mix(gl_FragColor.rgb, paintColor, 0.7); gl_FragColor.rgb = mix(gl_FragColor.rgb, paintColor, 0.7);
} }
} // End normal check
// DEBUG: Uncomment to tint entire mesh when shader is active (proves shader is running) // DEBUG: Uncomment to tint entire mesh when shader is active (proves shader is running)
// if (paintCount > 0) { // if (paintCount > 0) {

View file

@ -130,7 +130,7 @@ export function menu() {
separator: newBlank({ class:"set-sep", driven }), separator: newBlank({ class:"set-sep", driven }),
// sliceSupportTree: newBoolean(LANG.sp_tree_s, onBooleanClick, {title:LANG.sp_tree_s, trigger, show:isNotBelt}), // sliceSupportTree: newBoolean(LANG.sp_tree_s, onBooleanClick, {title:LANG.sp_tree_s, trigger, show:isNotBelt}),
// sliceSupportEnable: newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, show:isNotBelt}), // sliceSupportEnable: newBoolean(LANG.sp_auto_s, onBooleanClick, {title:LANG.sp_auto_l, show:isNotBelt}),
sliceSupportOutline: newBoolean(LANG.sp_outl_s, onBooleanClick, {title:LANG.sp_outl_l, show: () => !isTree() }), sliceSupportOutline: newBoolean(LANG.sp_outl_s, onBooleanClick, {title:LANG.sp_outl_l, xshow: () => !isTree() }),
separator: newBlank({ class:"set-sep", driven, show:manualSupport }), separator: newBlank({ class:"set-sep", driven, show:manualSupport }),
// sliceSupportGen: newRow([ // sliceSupportGen: newRow([
// ui.ssaGen = newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"}) // ui.ssaGen = newButton(LANG.sp_detect, onButtonClick, {class: "f-col grow a-center"})