몬테카를로법을 이용한 확산 반사광을 고려한 레이마칭
소개
레이마칭에서는, 물체에 충돌한 레이를 reflect()로 반사시켜, 다시 충돌한 다른 물체의 색을 합성하는 것으로 경면 반사를 실현할 수 있습니다
그러나 단순한 경면 반사만으로는 각 물체의 반사율을 설정할 수 없으며 아래 그림과 같은 표현을 할 수 없습니다.
거울 반사만으로 레이 마칭
확산 반사광을 고려한 레이 마칭
이번은 몬테카를로법을 이용하여 확산 반사광도 고려한 레이마칭을 실시합니다
또한 framebuffer를 사용하여 구현합니다.
확산 반사광이란?
확산 반사(diffuse reflection)란, 평탄하지 않은 거친 표면으로부터의 빛의 반사로, 입사광이 다양한 각도로 반사하고 있는 것처럼 보인다. 난반사(란반샤)라고도 한다.
몬테카를로법이란?
몬테카를로법(몬테카를로 쪽, 영국: Monte Carlo method, MC)이란 시뮬레이션이나 수치 계산을 난수를 이용해 실시하는 수법의 총칭.
구현 절차
offScreen-fragmentShader
먼저 다음과 같이 각 물체의 반사율을 설정합니다.
const float sphereReflectRatio=0.9;
다음에, 마칭내에서 물체에 충돌했을 때에, 레이의 선단 좌표와 프레임수에 근거한 난수가 반사율보다 낮은 경우는 단순한 경면 반사, 그 이외에서는 확산 반사로 설정합니다
if(distance==sphereDistFunc(rPos-sphereCenter,sphereSize)){
color=sphereColor;
ray=random(rPos*frameCount)<sphereReflectRatio?normalize(reflect(ray,normal)):normalize(random3(rPos*frameCount));
}
마지막으로, 지금까지 오프 스크린 렌더링하여 온 텍스처의 평균을 출력하도록 합니다.
color=(color+texture(tex,vec2(vTextureCoord.x,-vTextureCoord.y)).rgb*(frameCount-1.0))/frameCount;
텍스가 마지막까지 텍스처의 평균이라고 생각해
전회까지의 평균에, 현재의 프레임수로부터 1을 뺀 수를 곱하는 것으로 전회까지의 텍스처의 합계를 계산할 수 있습니다
거기에 현재의 출력을 더해 프레임수로 나누는 것으로 평균 결과를 출력할 수 있다고 하는 것입니다
자바스크립트
JavaScript 측에서는, 오프 스크린 렌더링에 의해 지금까지의 텍스처의 평균을 출력하는 프로그램과, 최종적으로 렌더링하는 프로그램으로 나눕니다
const renderLoop = () => {
gl.useProgram(offRenderProg);
gl.bindFramebuffer(gl.FRAMEBUFFER, fBuffer[dist].f);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindTexture(gl.TEXTURE_2D, fBuffer[1 - dist].t);
gl.uniform2fv(offRenderUniLocation[0], [canvas.width, canvas.height]);
gl.uniform1i(offRenderUniLocation[1], 0);
gl.uniform1f(offRenderUniLocation[2], frameCount);
set_attribute([vPosition, vTextureCoord],offRenderAttLocation,offRenderAttStride);
gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.useProgram(prog);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindTexture(gl.TEXTURE_2D, fBuffer[dist].t);
gl.uniform1i(uniLocation[0], 0);
set_attribute([vPosition, vTextureCoord], attLocation, attStride);
gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);
dist = 1 - dist;
gl.flush();
frameCount++;
}
offRenderProg가 평균을 출력하는 프로그램으로, prog가 최종적으로 렌더링하는 프로그램입니다
루프가 돌 때마다 레이 마칭을 수행합니다. 이 때 프레임 수에 기초한 난수로 무작위 반사를 수행하므로 매번 다른 결과를 얻을 수 있습니다. 한 번 한 번의 결과는 더러운 것입니다 (아래 그림과 같이됩니다). 그러나 이러한 평균을 출력하면 확산 반사광의 결과를 얻을 수 있습니다.
끝에
샘플은 여기
h tps://우케 y시마. 기주 b. 이오/몬테카 rぉ/
시간이 지남에 따라 화질이 깨끗해집니다.
여러가지 고리 누르는 실장이 많습니다. 더 이런 편이 좋다는 조언을 기다리고 있습니다!
Reference
이 문제에 관하여(몬테카를로법을 이용한 확산 반사광을 고려한 레이마칭), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ukeyshima/items/e156bd9a71b07fef82e3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
const float sphereReflectRatio=0.9;
if(distance==sphereDistFunc(rPos-sphereCenter,sphereSize)){
color=sphereColor;
ray=random(rPos*frameCount)<sphereReflectRatio?normalize(reflect(ray,normal)):normalize(random3(rPos*frameCount));
}
color=(color+texture(tex,vec2(vTextureCoord.x,-vTextureCoord.y)).rgb*(frameCount-1.0))/frameCount;
JavaScript 측에서는, 오프 스크린 렌더링에 의해 지금까지의 텍스처의 평균을 출력하는 프로그램과, 최종적으로 렌더링하는 프로그램으로 나눕니다
const renderLoop = () => {
gl.useProgram(offRenderProg);
gl.bindFramebuffer(gl.FRAMEBUFFER, fBuffer[dist].f);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindTexture(gl.TEXTURE_2D, fBuffer[1 - dist].t);
gl.uniform2fv(offRenderUniLocation[0], [canvas.width, canvas.height]);
gl.uniform1i(offRenderUniLocation[1], 0);
gl.uniform1f(offRenderUniLocation[2], frameCount);
set_attribute([vPosition, vTextureCoord],offRenderAttLocation,offRenderAttStride);
gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.useProgram(prog);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindTexture(gl.TEXTURE_2D, fBuffer[dist].t);
gl.uniform1i(uniLocation[0], 0);
set_attribute([vPosition, vTextureCoord], attLocation, attStride);
gl.drawElements(gl.TRIANGLES, index.length, gl.UNSIGNED_SHORT, 0);
dist = 1 - dist;
gl.flush();
frameCount++;
}
offRenderProg가 평균을 출력하는 프로그램으로, prog가 최종적으로 렌더링하는 프로그램입니다
루프가 돌 때마다 레이 마칭을 수행합니다. 이 때 프레임 수에 기초한 난수로 무작위 반사를 수행하므로 매번 다른 결과를 얻을 수 있습니다. 한 번 한 번의 결과는 더러운 것입니다 (아래 그림과 같이됩니다). 그러나 이러한 평균을 출력하면 확산 반사광의 결과를 얻을 수 있습니다.
끝에
샘플은 여기
h tps://우케 y시마. 기주 b. 이오/몬테카 rぉ/
시간이 지남에 따라 화질이 깨끗해집니다.
여러가지 고리 누르는 실장이 많습니다. 더 이런 편이 좋다는 조언을 기다리고 있습니다!
Reference
이 문제에 관하여(몬테카를로법을 이용한 확산 반사광을 고려한 레이마칭), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/ukeyshima/items/e156bd9a71b07fef82e3
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(몬테카를로법을 이용한 확산 반사광을 고려한 레이마칭), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ukeyshima/items/e156bd9a71b07fef82e3텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)