비트 맵 알파 베벨 알고리즘?


14

알파를 범프 맵으로 사용하여 비트 맵에 경사 효과를 추가하는 알고리즘을 만들려고합니다.

어떻게 이런 식으로 갈까요? 스페 큘러 라이팅을 시도했지만 음영이 아닌 하이라이트 만 얻습니다.

내가 말하는 효과는 다음과 같습니다 (Photoshop을 사용하여 만든). 여기에 이미지 설명을 입력하십시오

이들 모두는 사용하여 수행되었다 size: 30px(비트 맵의 윤곽에서 경사의 깊이), angle 130, altitude 50.

왼쪽에서 오른쪽, 위에서 아래로 :

  1. 끌 하드 베벨
  2. 끌 소프트 베벨
  3. 부드러운 경사
  4. 치즐 하드 soften: 16px-흐린 경사?

이러한 각 효과를 만들려고하는데 기본 베벨을 만드는 방법은 무엇입니까? 그 경사에서 이들 각각에 무엇을 가져 가야합니까?

답변:


10

이것은 거리 변환의 컨볼 루션으로 달성 할 수 있습니다.

마스크 가장자리에 거리 변환을 사용하십시오. 그런 다음이 거리 변환을 임계 값으로하여 거리를 넘어서 값을 제거하십시오. 음영을 얻는 비결은 거리 변환 결과를 다음과 같은 커널로 변환하는 것입니다.

[ -1.0  -1.0  -1.0
  -1.0   0.0   0.0
  -1.0   0.0   1.0 ]

이렇게하면 올바른 방향으로 시작할 수 있습니다.

#include "opencv/cv.h"
#include "opencv/highgui.h"

using namespace cv;
using namespace std;

int main() {
    Mat mask, dist, bevel;
    mask = Mat::zeros(200, 400, CV_8U);
    rectangle(mask, Point(30,30), Point(180,180), Scalar(255), -1);
    circle(mask, Point(30,30), 50, Scalar(0), -1);
    circle(mask, Point(180,180), 50, Scalar(0), -1);
    circle(mask, Point(300,100), 75, Scalar(255), -1);
    imshow("1",mask);

여기에 이미지 설명을 입력하십시오

    //find edges and invert image for distance transform
    Canny(mask, dist, 50, 150);
    dist = 255-dist;
    distanceTransform(dist, dist, CV_DIST_L2, CV_DIST_MASK_5);
    threshold(dist, dist, 20, 20, CV_THRESH_TRUNC);
    blur(dist, dist, Size(3,3));
    dist.convertTo(bevel, CV_8U);
    equalizeHist(bevel, bevel);
    imshow("2",bevel);

여기에 이미지 설명을 입력하십시오

    //convolve with secret sauce
    float d[] = {-1,-2,-3,
                 -2, 0, 0,
                 -3, 0, 1 };
    Mat kernel(3, 3, CV_32F, d);
    kernel = kernel - mean(kernel)[0];
    filter2D(dist, dist, CV_32F, kernel);

    //normalize filtering result to [-1, 1]
    double maxVal;
    minMaxLoc(dist, NULL, &maxVal);
    dist = 128 * dist / maxVal;

    //convert and display result
    dist.convertTo(bevel, CV_8U, 1, 128);
    bevel = bevel.mul(mask)/255;
    imshow("3", bevel);

여기에 이미지 설명을 입력하십시오

    waitKey(0);
}

굉장해 보여요! 부드럽게 만드는 것은 흐릿한 것처럼 보이지만 어떻게 "부드러운 경사"를 만들 수 있습니까?
Shedokan

Smooth Bevel은 컨벌루션 전에 거리 마스크를 흐리게하고, Soften은 컨벌루션 후에 결과를 흐리게합니다.
Matt M.

4

Photoshop의 Bevel 및 Emboss는 다음과 같이 예상대로 작동합니다.

1) 임시 8 비트 단일 채널 이미지에서 거리 변환 계산

  • Chisel은 모따기 메트릭 (크기에 따라 3x3, 5x5 또는 7x7)과 함께 유클리드 거리 변환을 사용합니다. 원하는 경우 정확한 유클리드 거리 변환을 사용할 수 있습니다. 나는 안티 에일리어싱 ( "선형 시간의 거리 변환 계산을위한 일반 알고리즘", MEIJSTER)이 가능하기 때문에 Meijster의 것을 선호합니다.

  • 스무스 베벨은 Chamfer 5-7-11 거리 변환과 박스 블러의 두 가지 적용으로 범프 맵을 생성합니다.

2) 중간 거리 변환 이미지에 범프 매핑을 적용합니다. Blinn의 독창적 인 기술이 적합합니다.

3) 부드럽게하기 위해 표면 법선에서 컨볼 루션을 수행하거나 커널을 사용하여 필터링 할 수 있습니다.

4) 범프 맵을 사용하여 표면 법선을 전역 광원과 결합하여 -1에서 1까지의 값으로 조명 강도를 계산합니다. 음수 값은 그림자, 양수 값은 하이라이트, 절대 값은 빛의 크기입니다 출처.

5) 2 개의 8 비트 단일 채널 임시 이미지 (하이라이트 강도 및 섀도우)가 계산됩니다. 거기에서 각 마스크를 사용하여 색상, 혼합 모드 및 불투명도를 사용하여 레이어에 색조를 지정하는 것은 사소한 문제입니다. 하나는 강조 표시에 대한 마스크이고 다른 하나는 그림자에 대한 마스크입니다.

이 중 일부를 구현하기위한 Visual Basic 소스 코드는 다음에서 찾을 수 있습니다.

http://www.Planet-Source-Code.com/vb/scripts/ShowCode.asp?txtCodeId=51640&lngWId=1

자세한 내용은 오픈 소스 LayerEffects 프로젝트를 방문하십시오.

https://github.com/vinniefalco/LayerEffects.git

나는 이것이 누군가를 돕기를 바랍니다.


감사합니다. 언급 한 가우스 거리 변환에 매우 관심이 있습니다. 사용 가능한 코드를 알고 있습니까? 수식을 잘 읽을 수 없습니다. :(
Shedokan

이미 게시 한 정보 외에 GDT에 대한 정보를 찾지 못했습니다.
Vinnie Falco

"2) 거리 변환 이미지에 범프 매핑 적용"의 의미는 무엇입니까? 거리 변환은 거리 (각 픽셀 당 1 개 숫자)를 제공하는 반면 범프 매핑에는 법선 (각 픽셀 당 2 개 숫자)이 필요합니다 ... 무슨 말을하는지 알고 있습니까?
Ivan Kuckir

@IvanKuckir 더 명확해야합니다. 거리 변환을 높이 맵으로 처리하고 인접한 수직 및 수평 값에서 dx / dy를 계산하여 표면 법선을 계산할 수 있습니다. 이 두 숫자는 범프 매핑에 필요한 표준을 제공합니다.
Vinnie Falco
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.