日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于光线追踪的Mental Ray鱼眼镜头的编程实现 作者:华文广

發(fā)布時間:2025/7/25 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于光线追踪的Mental Ray鱼眼镜头的编程实现 作者:华文广 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

基于光線追蹤的Mental Ray魚眼鏡頭的編程實現(xiàn)

作者:華文廣 ????????????????????????????????????????????????????????????????????????????????? 日期2010/12/3

一、什么是魚眼鏡頭

從攝影識知來講,魚眼鏡頭是一種焦距約在6-16毫米之間的短焦距超廣角攝影鏡頭,“魚眼鏡頭”是它的俗稱。為使鏡頭達到最大的攝影視角,這種攝影鏡頭的前鏡片直徑且呈拋物狀向鏡頭前部凸出,與魚的眼睛頗為相似,“魚眼鏡頭”因此而得名。


??? 魚眼鏡頭最大的作用是增大視角范圍,視角一般可達到220·或230·,這為近距離拍攝大范圍景物創(chuàng)造了條件;魚眼鏡頭在接近被攝物拍攝時能造成非常強烈的透視效果,強調(diào)被攝物近大遠小的對比,使所攝畫面具有一種震撼。如下圖所示:

??? 在現(xiàn)實應(yīng)用中,也有很多地方會用到魚眼鏡頭,最常見的就是球幕投影。圖片經(jīng)過魚眼變形之后,再反投回到球幕上,就能得到正常的視覺效果。

二、在Mental Ray中模擬魚眼鏡頭的實現(xiàn)

在MAYA中,相機的鏡頭都是平面的。要想渲染出魚眼效果,就得做一些特別處理。在網(wǎng)上,我們也能找到幾種不同的解決方案。方案一,使用天空盒技術(shù),就是分別渲染前后左右上下六個面組成一個天空盒,然后再在天空盒里面放一個球進行境面反射,這種方案有個優(yōu)點就是渲染速度比較快,如果配置合理,完全可以達到實時的要求。關(guān)于這種實現(xiàn)方案,這個網(wǎng)址http://strlen.com/gfxengine/fisheyequake/上有比較長詳細的介紹。然而,這個技術(shù)也有一些不缺點,比如,如果場景的燈光與攝像機的視線方向有光,那么六張圖的明暗效果就沒辦法平滑過渡。方案二、使用多圖拼接技術(shù),就是從不同角度拍一系列圖片,然后用拼接軟件,把這些圖片自動拼成一張360度全景圖,Autodesk Stitcher Unlimited就是一個非常優(yōu)秀的全景圖制作工具,當然,這個方案對于制作人員來說,工作量也是相當巨大的。

?

?

在這里我們詳細介紹一下第三種解決方案,就是基于光線追蹤的魚眼鏡頭的模擬實現(xiàn)。我們知道,Mental Ray是一款非常出色的基于光線追蹤的渲染工具。正常情況下,攝像機發(fā) ??

a

??

?


射出來的光線是沿直線方向投射到場景中去的,如果a所示:

如果我們能截獲這個光線,然后改變它的前進方向,便能很容易實現(xiàn)魚眼效果,如圖b所示,在相機前加入一個半球形的鏡頭,然后再根據(jù)光的折射原理,計算新的光線方向。以下就是魚眼鏡頭的實現(xiàn)代碼:

?

#include "math.h"

#include <mi_version.h>

#include <shader.h>

#include <geoshader.h>???????

?

#include <stdio.h>

#include <math.h>

#include "shader.h"

?

#define EPSILON 0.00001

?

// 定義一個輸入?yún)?shù)結(jié)構(gòu)體,用于從MAYA屬性窗口來改變該變量

struct ben_fisheye_lens_FOV {

???????? miScalar FOV_Angle; // Fisheye FOV 視野角度

?

};

?

extern "C" DLLEXPORT int ben_fisheye_lens_version(void) {return(1);}

extern "C" DLLEXPORT miBoolean ben_fisheye_lens(

???????????????????????????????????? miColor ?*result,

???????????????????????????????????? miState ?*state,

???????????????????????????????????? register ?struct ?ben_fisheye_lens_FOV *params)

{

???????? miScalar fov_angle_deg = *mi_eval_scalar(&params->FOV_Angle);

???????? miGeoScalar fov_angle_rad;

?

???????? miVector ray;

???????? miGeoScalar x, y, r, phi, theta;

?

???????? // 單位化 [-1,1]...

???????? x = (2.0 * state->raster_x) / state->camera->x_resolution - 1.0;

???????? y = (2.0 * state->raster_y) / state->camera->y_resolution - 1.0;

?

???????? // 根據(jù)像素坐標,來計算該像素離中心的半。

???????? r = MI_SQRT( ( x * x ) + ( y * y ) );

?

???????? if ( r < 1.0 ) {

?????????????????? // 根據(jù)球面坐標公式來計算 phi...

?????????????????? if ( (r > -EPSILON) && (r < EPSILON) ) {

??????????????????????????? phi = 0.0;

?????????????????? } else {

?

??????????????????????????? if ( x < EPSILON ) {

???????????????????????????????????? phi = M_PI - asin( y / r );

??????????????????????????? } else {

???????????????????????????????????? phi = asin( y / r );

??????????????????????????? }

?????????????????? }

?

?????????????????? // 把輸入的角度值轉(zhuǎn)換為弧度

?????????????????? fov_angle_rad = fov_angle_deg * M_PI / 180.0;

??????????????????

?????????????????? // 計算 theta...

?????????????????? theta = r * ( fov_angle_rad / 2.0 );

?

?????????????????? // 計算新的光線的方向,沿球面法線方向

?????????????????? ray.x = (float)(sin(theta) * cos(phi));

?????????????????? ray.y = (float)(-sin(theta) * sin(phi));

??????????????????

?????????????????? // 這里我們假定相機的視線方向是 -Z 軸

?????????????????? ray.z = (float)(-cos(theta));

?

?????????????????? // 把光線轉(zhuǎn)換為相機空間

?????????????????? mi_vector_from_camera(state, &ray, &ray);

?????????????????? // 發(fā)射新的改變方向之后的光線

?????????????????? return(mi_trace_eye(result, state, &state->org, &ray));

???????? } else {

?????????????????? result->r = result->g =

??????????????????????????? result->b = result->a = 0;

?????????????????? return(miFALSE);

???????? }

?

} /* end of ben_fisheye_lens() */

?

?

把以上代碼放在VC++中編譯成一個ben_fisheye_lens .dll,這樣一個基于Mental Ray 的魚眼鏡頭就開發(fā)完成了。

我們知道,光線追蹤的光線發(fā)射是從相機窗口的每個像素出發(fā)的,那么,基于像素的二維的圖像坐標,如何轉(zhuǎn)換成球面坐標系的角度坐標呢?這里Paul Bourke給我們提供了一個方案:

?

?

?

?

逆向運算如下:

u = r cos(phi) + 0.5
v = r sin(phi) + 0.5

轉(zhuǎn)換成球面坐標。

r = atan2(sqrt(x*x+y*y),p.z) / pi
phi = atan2(y,x)

?

三、安裝和使用

安裝我們編譯好的魚眼鏡頭插件。首先,用記事本新建一個ben_fisheye_lens.mi文件,然后把下面腳本寫入到這個mi文件中去:

declare shader

??????? color "ben_fisheye_lens" (

?????????????????? scalar " FOV_Angle ",?????? #: softmin 0.0 softmax 360.0 default 180.0

??????? )

???????? apply lens

??? version 1

end declare

?

完成之后,把ben_fisheye_lens.dll文件拷貝到:/Mayax.x/mentalray/lib文件夾,把ben_fisheye_lens.mi文件拷貝到/Mayax.x/mentalray/include文件甲。

?

打開MAYA,你就可以在mental ray的Shader中看到你所編譯的魚眼鏡頭了,新建一個鏡頭shader然后指定到MAYA的相機屬性的鏡頭參數(shù)中去,這個你渲出來的圖片,就會有魚眼效果了。

?

?


???????? 以上是一個簡單的例子,用來解析如何編寫一個Mental Ray 的鏡頭。事實上,如果我們能理解透徹光線追蹤的原理,我們可以用其它你所相要的方式來改變光線的方線,從而實現(xiàn)不同的鏡頭效果,如環(huán)幕鏡頭,球幕鏡頭,天空盒鏡頭等等。

環(huán)幕全景鏡頭效果圖

?

《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的基于光线追踪的Mental Ray鱼眼镜头的编程实现 作者:华文广的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。