본문 바로가기
Project

[unity] sound project - 3 days

by 배애앰이 좋아 2020. 5. 25.
반응형

유니티 내에서 실험해본 결과 :

1) 거리에 따른 3D적인 사운드 효과 가능

2) 사운드 좌우 배치에 따른 좌우 위치 판단 가능

3) 듣는 이랑 사운드 사이에 벽이 있을 경우 사운드 감소 효과 없음

4) 소리 굴절, 반사에 따른 사운드 효과 없음

 

이 중에서 3, 4번을 직접 구현하고자 합니다. 

3번은 완성했지만 아직 글을 올리지 않아 추후 올릴 예정입니다. (sound project - 2 days 예정)

 

4번을 완성해가는 과정

 

1)

소리의 굴절과 반사를 표현하기 위해 반사와 굴절에 대해 조사를 해보았습니다.

빛과 소리는 유사하기 때문에 이를 바탕으로 "스넬의 법칙"을 

스넬의 법칙

찾아냈고 입사각과 반사각의 각도가 같은 부분이랑 굴절의 광선은 입사각보다 각도가 작은 부분을 중점으로 두었습니다. 처음에 사운드로부터 직선으로 ray를 쏘고 부딪히는 물체에서 법선 벡터를 구합니다. 이를 통해 입사 광선을 가정하고 둘의 벡터를 통해 각도를 구합니다. 

 

[1] 두 벡터 사이의 각도 구하기(0~180)

public static float GetAngle(Vector3 from, Vector3 to)
{
    Vector3 v = to - from;
    return Mathf.Atan2(v.y, v.x) * Mathf.Rad2Deg;
}

 

[2] 두 벡터 사이의 각도 구하기(0~360)

public static float CalculateAngle(Vector3 from, Vector3 to)
{    
    return Quaternion.FromToRotation(Vector3.up, to - from).eulerAngles.z;
}

 

하지만 직접 각도 구하는 방식도 이용하긴 하였지만 반사벡터를 구하기 위해서 유니티 내에서 제공하는 함수를 사용하여 반사 벡터를 구하였습니다.

 

[3] 유니티를 이용한 반사 벡터 구하기

Vector3 incomingVector = direct;
incomingVector = incomingVector.normalized;
Vector3 normalVector = collision.contacts[0].normal;
Vector3 reflectVector = Vector3.Reflect(incomingVector, normalVector);
reflectVector = reflectVector.normalized;

 

반사에 대해서는 위의 방식으로 해결하였습니다. 이번에 굴절을 구하는 방법에 대해 고민을 하였는데요. 기존까지는 굴절을 완전히 랜덤으로 주었지만 어느 정도 범위를 만들어주기 위해서 굴절각이 법선 벡터 기준과 입사 벡터 사이에 생성된다는 것을 중점으로 두었습니다. 그렇기 위해서 법선 벡터와 입사 벡터의 각도를 측정하여서 그 각도 내에서 랜덤으로 각도를 지정해주어서 벡터를 범위내에 만들어지도록 하였습니다. 

 

이때 조건은 한 바퀴를 180이라고 칠 때 90 이상 기준으로는 180-A가 두 벡터가 이루는 각이 되는 것이고 90이하일 경우에는 A가 두 벡터가 이루는 각이 됩니다. 무작위로 각도를 지정한 후에 벡터를 특정 각도로 이동시켜 줍니다. 그럼 어느 정도 굴절벡터를  만들어주었습니다. 

 

[4] 벡터값을 특정 각도로 이동하기

Quaternion v3Rotation = Quaternion.Euler(0f, 30f, 0f);  
Vector3 v3Direction = Vector3.forward; 
Vector3 v3RotatedDirection = v3Rotation * v3Direction ;

 

다음에는 여러개의 ray를 통해서 잘 작동하는지 시험해볼까 합니다.

 

최종 결과물 : 

파란 선 : 소리의 방향 / 빨간 선 : 범위에서 무작위로 지정된 굴절 방향

초록 선 : 충돌 물체의 법선 벡터 / 노란 선 : 충돌되지 못한 선 표시

벽의 회전 각도에 따라 뻗어나가는 방향이 따른 붉은 광선들.

 

참고 사이트 :

1) https://icechou.tistory.com/316

 

두 벡터 사이의 각도 0~360도로 구하기

내적을 이용하여 Acos으로 각도구하는 법도 있고 ( 0~ 180도) Atan를 이용하여 각도를 구하는 법도 있지만 (-180 ~ 180도) 1 2 3 4 5 public static float GetAngle(Vector3 from, Vector3 to) { Vector3 v = to -..

icechou.tistory.com

2) https://sjcy.tistory.com/entry/%EC%9C%A0%EB%8B%88%ED%8B%B0%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%B0%98%EC%82%AC-%EB%B2%A1%ED%84%B0-%EA%B5%AC%ED%95%98%EA%B8%B0

 

유니티를 이용한 반사 벡터 구하기

주로 당구나 벽에서 튕기는 물체의 반사 벡터를 구할때 유용한 계산법이다. void OnCollisionEnter(Collision collision) { // 입사벡터를 알아본다. (충돌할때 충돌한 물체의 입사 벡터 노말값) Vector3 incoming..

sjcy.tistory.com

 

반응형

댓글