如何使混合模式 MULTIPLY 不使 p5js 中的所有图像变黑

How to make the blend mode MULTIPLY not make all the image black in p5js

我有这个代码笔:https://codepen.io/giorgiomartini/pen/OjQpKd?editors=0010

我在绘制一些形状和一些文本的地方,现在我想在形状和文本之间添加一个径向叠加层。

所以我创建了一个 drawgradient 函数并在形状和文本之间调用它:

function drawGradient() {
  blendMode(MULTIPLY)
  for (let r = canvasX; r > 0; --r) {
    let lightnes = map(r,0,canvasX,255,0)
    fill(0, 0, lightnes)
    ellipse(0, 0, r*1.8, r*2)
  }
}

我希望这个渐变具有乘法混合模式,这样它可以使渐变中像素较暗的整体变暗一些。

但我得到的只是全黑覆盖...

在 photoshop 或 gimp 中,如果您使用乘法混合模式添加黑白径向渐变,它会使渐变中有较暗像素的背景变暗。但在 p5js 中,它只会使所有内容变黑。

知道我做错了什么吗?

这是mouseClicked函数,在底部,你可以看到正在调用的渐变函数:

function mouseClicked(){

    blendMode(BLEND)
    const colsArray = randomColor({luminosity: 'light', format: 'hsl',count: 4}) 
    background(colsArray[0])
    translate(width/2, height/2)



    //////////////////////////////////////////////////////////////////          amt              initial       range
    const arrayOfRandomNumsOfFirstProbStepX  = createArrayOfRandomNums(amtOfSpotsInFirstProb,startProbStep,firstProbStepX)
    const arrayOfRandomNumsOfFirstProbStepY  = createArrayOfRandomNums(amtOfSpotsInFirstProb,startProbStep,firstProbStepY)

    const arrayOfRandomNumsOfSecondProbStepX = createArrayOfRandomNums(amtOfSpotsInSecondProb,startProbStep,secondProbStepX) 
    const arrayOfRandomNumsOfSecondProbStepY = createArrayOfRandomNums(amtOfSpotsInSecondProb,startProbStep,secondProbStepY)

    drawLinesAtRandomspots(6,random(50),colsArray)

    //args => element, arrayOfRandomNumsOfProbStepX, arrayOfRandomNumsOfProbStepY, elmntSizeMin, elmntSizeMax,rot, colors
    drawElmntsOnSomeProbabilityStep('ellipse',arrayOfRandomNumsOfFirstProbStepX, arrayOfRandomNumsOfFirstProbStepY , 10, 80, true, colsArray )
    drawElmntsOnSomeProbabilityStep('rect',arrayOfRandomNumsOfSecondProbStepX, arrayOfRandomNumsOfSecondProbStepY, 5, 30, true, colsArray)   
   drawGradient()
     addText() 

}

如果您想要的效果是线性渐变,那么在屏幕上绘制一堆椭圆似乎有点奇怪。

ellipse(0, 0, r*1.8, r*2)

您希望这条线做什么?

相反,我认为如果您绘制一系列线条,每次稍微深一点或浅一点,会更有意义。这是一个例子:

function drawGradient() {
  blendMode(MULTIPLY);
  for (let lineX = 0; lineX < width; lineX++) {
    let lightness = map(lineX, 0, width, 0, 255);
    stroke(0, lightness)
    line(lineX, 0, lineX, height)
  }
}

这会创建一个从浅到深渐变的水平渐变。

编辑: 如果你想要一个径向渐变,现在你要在彼此的顶部绘制大量的黑眼圈,所以它们是 "stacking"只是变得完全黑色。您需要结合绘制更少的圆圈(例如,每 10 个像素而不是每 1 个像素)并将它们画得更浅。这是一个例子:

function drawGradient() {
  blendMode(MULTIPLY);
  for (let r = 600; r > 0; r-=10) {
    let lightness = map(r, 0, 600, 20, 0);
    fill(0, lightness);
    noStroke();
    ellipse(0, 0, r, r);
  }
}

此代码每 10 个像素绘制一个圆圈,最暗的圆圈的 alpha 为 20 而不是 255。这会导致更轻的梯度。您必须使用准确的值才能获得您想要的效果。

如果您有后续问题,请 post MCVE 而不是您的整个项目。只需几个硬编码形状和一个渐变函数就足够了,只要我们可以运行。到目前为止,您的代码有点难以调试,因为它包含一堆与问题没有直接关系的东西。祝你好运。

clear() 放在 draw() 函数的开头将清除缓冲区中的像素。这使您可以使用 blendMode(MULTIPLY) 而不会在前几帧后重叠的形状变黑。