前面讲了球形环境映射,然而目前采用更多的是立方体环境映射.国际惯例:上图先:

1.反射:

2.折射

3.fresnel(反射+折射)

4.色散

好了,大概讲下原理,

立方体纹理我就不多讲了,它以一个3维向量(x,y,z)为输入,然后比较x,y,z的绝对值,假设X的绝对值最大,但是X是负值,那么就找到-X那一面,用Y,Z的坐标X的绝对值得到2D纹理坐标(u,v)最后用(u,v)去-X面的图片去采样, 输出最后的颜色,

Which face to sample is determined by the sign of the coordinate having the
largest absolute value. The other two coordinates are divided by the largest coordinate
and remapped to the range [0,1] using the formulas listed in Table 7.1 to
produce 2D texture coordinates s′,t′ . These coordinates are then used to sample
the two-dimensional texture map for the corresponding face of the cube texture
map.

好了,讲下反射

可以根据I和N算去R,然后用R去查找立方体贴图

公式为:R = I - 2N(N·I)

折射

这里是一次折射,理想情况下应该是两次折射,进去一次出来一次

由于一次折射效果就行了而且比较简单,我们这里采用了一次折射

有个斯涅尔定律(Snell's law)对折射非常重要

折射的推导公式为:

公式为:

如果I不是单位化的,可以先单位化下再算,最后算出T的长度再乘以I的长度就得到最终的T

或者用书上的另一方法来推导也行

fresnel(折射+反射)

菲涅尔效应(Fresnel Effect):当光到达材质的交界面时,一部分光被反射,而另一部分将发生折射,这个现象称为Fresnel Effect.

那么这两个部分占的比重如何去确定呢?

一般来说,当入射光线与法向量重合时,这时反射应占主导,当成180度时,折射应占主导.

这里有一个近似的公式,我们不追求物理上的精确,只要效果行就OK.

Chromatic Dispersion(色散):

refraction depends on the
surface normal, incident angle, and ratio of indices of refraction.In addition to these factors, the amount of
refraction also depends on the wavelength of the incident light. For example, red light gets refracted more
than blue light. This phenomenon is known as chromatic dispersion, and it is what happens when white light
enters a prism and emerges as a rainbow.

色散是基于不同波长的光在介质中折射率不同而产生的,这里我们只模拟算红,绿,蓝三种不同光的折射率

呵呵,原理大概就是这样了.

得抓紧了,多写几个shader,为自己的海洋打下坚实基础,最近我可能会写一个水面(牵涉到RRT),还有投影纹理,还有移位贴图(displacement mapping),敬请期待吧

对了,差点了贴源代码了:

/*------------------------------------------------------------
3D_Shader_CubeEnvMapping.cpp -- achieve cubic environment mapping
(c) Seamanj.2013/8/28
------------------------------------------------------------*/
//phase1 : add teapot
//phase2 : add camera
//phase3 : add cube environment mapping shader
//phase4 : add sky box
//phase5 : add refraction and chromatic dispersion shaders
#include "DXUT.h"
#include "resource.h" #define phase1 1
#define phase2 1
#define phase3 1
#define phase4 1
#define phase5 1
#if phase1
// Global variables
ID3DXMesh* pTeapotMesh = 0;
#endif
#if phase2
#include "DXUTcamera.h"
CModelViewerCamera g_Camera;
#endif
#if phase3
#include "SDKmisc.h"//加载文件时会用到
ID3DXEffect* g_pEffect = NULL; // D3DX effect interface
PDIRECT3DCUBETEXTURE9 g_pCubeEnvTex = 0;
D3DXHANDLE g_hReflectionTech = 0;
D3DXHANDLE g_hWorldViewProj = NULL; // Handle for world+view+proj matrix in effect
D3DXHANDLE g_hWorld = NULL;
D3DXHANDLE g_hWorldInv = NULL;
D3DXHANDLE g_hEyePosition = NULL;
D3DXHANDLE g_hCubeEnvTex = NULL;
#endif
#if phase4
// Vertex Buffer
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL;
// Index Buffer
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
#endif #if phase5
enum TECHNIQUE_IDS
{
REFLECTION,
REFRACTION,
FRESNEL,
DISPERSION
}; int g_nCurrentTechID = REFLECTION;
#define IDC_COMBO_TECH 1
#include "DXUTgui.h"
CDXUTDialogResourceManager g_dlg_resource_manager;
CDXUTDialog g_control_dlg;
D3DXHANDLE g_hRefractionTech = 0;
D3DXHANDLE g_hFresnelTech = 0;
D3DXHANDLE g_hDispersionTech = 0;
D3DXHANDLE g_hEtaRatio = 0;
D3DXHANDLE g_hFresnelBias = 0;
D3DXHANDLE g_hFresnelScale = 0;
D3DXHANDLE g_hFresnelPower = 0;
D3DXHANDLE g_hRGBEtaRatio = 0;
#endif
//--------------------------------------------------------------------------------------
// Rejects any D3D9 devices that aren't acceptable to the app by returning false
//--------------------------------------------------------------------------------------
bool CALLBACK IsD3D9DeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat,
bool bWindowed, void* pUserContext )
{
// Typically want to skip back buffer formats that don't support alpha blending
IDirect3D9* pD3D = DXUTGetD3D9Object();
if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,
AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING,
D3DRTYPE_TEXTURE, BackBufferFormat ) ) )
return false; return true;
} //--------------------------------------------------------------------------------------
// Before a device is created, modify the device settings as needed
//--------------------------------------------------------------------------------------
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, void* pUserContext )
{
#if phase2
pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
#endif
return true;
} //--------------------------------------------------------------------------------------
// Create any D3D9 resources that will live through a device reset (D3DPOOL_MANAGED)
// and aren't tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9CreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
#if phase3
HRESULT hr;
#endif
#if phase5
V_RETURN(g_dlg_resource_manager.OnD3D9CreateDevice(pd3dDevice));
#endif
#if phase2
// Setup the camera's view parameters
D3DXVECTOR3 vecEye( 0.0f, 0.0f, -5.0f );
D3DXVECTOR3 vecAt ( 0.0f, 0.0f, -0.0f );
g_Camera.SetViewParams( &vecEye, &vecAt );
FLOAT fObjectRadius=1;
//摄像机缩放的3个参数
g_Camera.SetRadius( fObjectRadius * 3.0f, fObjectRadius * 0.5f, fObjectRadius * 10.0f );
g_Camera.SetEnablePositionMovement( false );
#endif
#if phase1
D3DXCreateTeapot( pd3dDevice, &pTeapotMesh, 0);
#endif
#if phase3
// Create vertex shader
WCHAR str[MAX_PATH];
// Read the D3DX effect file
V_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"CubeEnvMapping.fx" ) );
// Create the effect
LPD3DXBUFFER pErrorBuff;
V_RETURN( D3DXCreateEffectFromFile(
pd3dDevice, // associated device
str, // effect filename
NULL, // no preprocessor definitions
NULL, // no ID3DXInclude interface
D3DXSHADER_DEBUG, // compile flags
NULL, // don't share parameters
&g_pEffect, // return effect
&pErrorBuff // return error messages
) );
//pErrorBuff
// Get handle
g_hReflectionTech = g_pEffect->GetTechniqueByName("ReflectionTechnique");
g_hWorldViewProj = g_pEffect->GetParameterByName(0, "g_mWorldViewProj");
g_hWorld = g_pEffect->GetParameterByName(0, "g_mWorld");
g_hWorldInv = g_pEffect->GetParameterByName(0, "g_mWorldInv");
g_hEyePosition = g_pEffect->GetParameterByName(0, "g_eyePosition");
g_hCubeEnvTex = g_pEffect->GetParameterByName(0, "g_txCubeEnvMap"); // Set texture:
//D3DXCreateCubeTextureFromFile(pd3dDevice, L"CloudyHillsCubemap.dds", &g_pCubeEnvTex);
D3DXCreateCubeTextureFromFile(pd3dDevice, L"grassenvmap1024.dds", &g_pCubeEnvTex);
#endif
#if phase5
g_hRefractionTech = g_pEffect->GetTechniqueByName("RefractionTechnique");
g_hFresnelTech = g_pEffect->GetTechniqueByName( "FresnelTechnique" );
g_hDispersionTech = g_pEffect->GetTechniqueByName( "DispersionTechnique" );
g_hEtaRatio = g_pEffect->GetParameterByName(0, "g_fEtaRatio");
g_hFresnelBias = g_pEffect->GetParameterByName(0, "g_fFresnelBias");
g_hFresnelScale = g_pEffect->GetParameterByName(0, "g_fFresnelScale");
g_hFresnelPower = g_pEffect->GetParameterByName(0, "g_fFresnelPower");
g_hRGBEtaRatio = g_pEffect->GetParameterByName(0, "g_fRGBEtaRatio");
#endif
return S_OK;
} #if phase4
struct MyVertexFormat
{
FLOAT x, y, z;
FLOAT u, v, w;
};
#define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0) )
static HRESULT initVertexIndexBuffer(IDirect3DDevice9* pd3dDevice)
{
static const MyVertexFormat Vertices[] =
{
//+X
{ 1, -1, -1, 1, -1, -1 },
{ 1, -1, 1, 1, -1, 1 },
{ 1, 1, 1 , 1, 1, 1 },
{ 1, 1, -1, 1, 1, -1 },
//-X
{ -1, -1, -1,-1, -1, -1 },
{ -1, 1, -1, -1, 1, -1 },
{ -1, 1, 1 , -1, 1, 1 },
{ -1, -1, 1, -1, -1, 1},
//+Y
{ -1, 1, -1 ,-1, 1, -1 },
{ 1, 1, -1 ,1, 1, -1 },
{ 1, 1, 1 ,1, 1, 1},
{ -1, 1, 1 ,-1, 1, 1 },
//-Y
{ -1, -1, -1,-1, -1, -1 },
{ -1, -1, 1,-1, -1, 1 },
{ 1, -1, 1,1, -1, 1 },
{ 1, -1, -1, 1, -1, -1},
//Z
{ -1, -1, 1,-1, -1, 1 },
{ -1, 1, 1,-1, 1, 1 },
{ 1, 1, 1,1, 1, 1 },
{ 1, -1, 1,1, -1, 1 },
//-Z
{ -1, -1, -1,-1, -1, -1 },
{ 1, -1, -1,1, -1, -1 },
{ 1, 1, -1,1, 1, -1 },
{ -1, 1, -1,-1, 1, -1 }
};
if (FAILED(pd3dDevice->CreateVertexBuffer(sizeof(Vertices),
0, FVF_VERTEX,
D3DPOOL_DEFAULT,
&g_pVB, NULL))) {
return E_FAIL;
}
void* pVertices;
if (FAILED(g_pVB->Lock(0, 0, /* map entire buffer */
&pVertices, 0))) {
return E_FAIL;
}
memcpy(pVertices, Vertices, sizeof(Vertices));
g_pVB->Unlock(); // Create and initialize index buffer
static const WORD Indices[] =
{
0, 1, 2,
0, 2, 3, 4, 5, 6,
4, 6, 7, 8, 9, 10,
8,10, 11, 12,13,14,
12,14,15, 16,17,18,
16,18,19, 20,21,22,
20,22,23
};
if (FAILED(pd3dDevice->CreateIndexBuffer(sizeof(Indices),
D3DUSAGE_WRITEONLY,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,
&g_pIB, NULL))) {
return E_FAIL;
}
void* pIndices;
if (FAILED(g_pIB->Lock(0, 0, /* map entire buffer */
&pIndices, 0))) {
return E_FAIL;
}
memcpy(pIndices, Indices, sizeof(Indices));
g_pIB->Unlock();
return S_OK;
} #endif
//--------------------------------------------------------------------------------------
// Create any D3D9 resources that won't live through a device reset (D3DPOOL_DEFAULT)
// or that are tied to the back buffer size
//--------------------------------------------------------------------------------------
HRESULT CALLBACK OnD3D9ResetDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc,
void* pUserContext )
{
#if phase3
HRESULT hr;
if( g_pEffect )
V_RETURN( g_pEffect->OnResetDevice() );
#endif
#if phase5
V_RETURN(g_dlg_resource_manager.OnD3D9ResetDevice());
// set dialog position and size
g_control_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350);
g_control_dlg.SetSize(170, 300);
#endif
#if phase2
pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE );
//关闭光照处理, 默认情况下启用光照处理
pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );
//Setup the camera's projection parameters
float fAspectRatio = pBackBufferSurfaceDesc->Width / ( FLOAT )pBackBufferSurfaceDesc->Height; g_Camera.SetProjParams( D3DX_PI / 2, fAspectRatio, 0.1f, 5000.0f );
g_Camera.SetWindow( pBackBufferSurfaceDesc->Width, pBackBufferSurfaceDesc->Height );
g_Camera.SetButtonMasks( MOUSE_LEFT_BUTTON, MOUSE_WHEEL, MOUSE_RIGHT_BUTTON );
#endif
#if !phase4
return S_OK;
#else
#if phase1
return initVertexIndexBuffer(pd3dDevice);
#endif
#endif
} //--------------------------------------------------------------------------------------
// Handle updates to the scene. This is called regardless of which D3D API is used
//--------------------------------------------------------------------------------------
void CALLBACK OnFrameMove( double fTime, float fElapsedTime, void* pUserContext )
{
#if phase2
g_Camera.FrameMove( fElapsedTime );
#endif
} //--------------------------------------------------------------------------------------
// Render the scene using the D3D9 device
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9FrameRender( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )
{
HRESULT hr; // Clear the render target and the zbuffer
V( pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_ARGB( 0, 45, 50, 170 ), 1.0f, 0 ) ); // Render the scene
if( SUCCEEDED( pd3dDevice->BeginScene() ) )
{ #if phase3
UINT iPass, cPasses;
D3DXMATRIXA16 mWorldViewProjection,mWorld,mWorldInv;
#if !phase5
V(g_pEffect->SetTechnique(g_hReflectionTech));
#else
switch( g_nCurrentTechID )
{
case REFLECTION:
V( g_pEffect->SetTechnique( g_hReflectionTech ) );
break; case REFRACTION:
V( g_pEffect->SetTechnique( g_hRefractionTech ) );
V( g_pEffect->SetFloat(g_hEtaRatio, 1.5f) );
break;
case FRESNEL:
V( g_pEffect->SetTechnique( g_hFresnelTech ) );
V( g_pEffect->SetFloat(g_hFresnelBias, 0.0f) );
V( g_pEffect->SetFloat(g_hFresnelScale, 1.0f) );
V( g_pEffect->SetFloat(g_hFresnelPower, 4.0f) );
break;
case DISPERSION:
V( g_pEffect->SetTechnique( g_hDispersionTech ) );
V( g_pEffect->SetFloat(g_hFresnelBias, -0.3f) );
V( g_pEffect->SetFloat(g_hFresnelScale, 1.0f) );
V( g_pEffect->SetFloat(g_hFresnelPower, 4.0f) );
float RGBEtaRatio[3] = {1.1f, 1.2f, 1.3f};
V( g_pEffect->SetFloatArray(g_hRGBEtaRatio, RGBEtaRatio, 3) );
break;
}
#endif V( g_pEffect->Begin( &cPasses, 0 ) );
for( iPass = 0; iPass < cPasses; iPass++ )
{
V( g_pEffect->BeginPass( iPass ) );
//set WorldViewProject matrix
mWorldViewProjection = *g_Camera.GetWorldMatrix() * *g_Camera.GetViewMatrix() *
*g_Camera.GetProjMatrix();
V( g_pEffect->SetMatrix( g_hWorldViewProj, &mWorldViewProjection) );
//set WorldView matrix
mWorld = *g_Camera.GetWorldMatrix() ;
V( g_pEffect->SetMatrix( g_hWorld, &mWorld) );
//set WorldViewInv matrix
mWorldInv = *D3DXMatrixInverse(&mWorldInv, 0, &mWorld);
V( g_pEffect->SetMatrix( g_hWorldInv, &mWorldInv) );
//set texture
V( g_pEffect->SetTexture( g_hCubeEnvTex, g_pCubeEnvTex) );
//set eye position
V( g_pEffect->SetFloatArray( g_hEyePosition, (const float*)(g_Camera.GetEyePt()), 3) ); #if phase1
pTeapotMesh->DrawSubset( 0 );
#endif
V( g_pEffect->EndPass() );
}
V( g_pEffect->End() );
#endif
#if phase4 pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
// Set world matrix
D3DXMATRIX M;
D3DXMatrixIdentity( &M ); // M = identity matrix
D3DXMatrixScaling(&M,2000, 2000, 2000);
pd3dDevice->SetTransform(D3DTS_WORLD, &M) ;
//这里三角形更像是世界坐标中静止的物体(比如墙)因为按W它会相对与摄像机会动,不像茶壶总在摄像机前面,相对于摄像机静止
// Set view matrix
D3DXMATRIX view = *g_Camera.GetViewMatrix() ;
pd3dDevice->SetTransform(D3DTS_VIEW, &view) ;
// Set projection matrix
D3DXMATRIX proj = *g_Camera.GetProjMatrix() ;
pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CCW);
pd3dDevice->SetTransform(D3DTS_PROJECTION, &proj) ;
pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(MyVertexFormat));
pd3dDevice->SetIndices(g_pIB);//sets the current index buffer.
pd3dDevice->SetFVF(FVF_VERTEX);//Sets the current vertex stream declaration.
pd3dDevice->SetTexture(0, g_pCubeEnvTex);
pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, 24, 0, 12); #endif
#if phase5
V(g_control_dlg.OnRender(fElapsedTime));
#endif
V( pd3dDevice->EndScene() );
}
} //--------------------------------------------------------------------------------------
// Handle messages to the application
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
bool* pbNoFurtherProcessing, void* pUserContext )
{
#if phase2
g_Camera.HandleMessages( hWnd, uMsg, wParam, lParam );
#endif
#if phase5
*pbNoFurtherProcessing = g_dlg_resource_manager.MsgProc(hWnd, uMsg, wParam, lParam);
if(*pbNoFurtherProcessing)
return 0;
*pbNoFurtherProcessing = g_control_dlg.MsgProc(hWnd, uMsg, wParam, lParam);
if(*pbNoFurtherProcessing)
return 0;
#endif
return 0;
} //--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
#if phase3
if( g_pEffect )
g_pEffect->OnLostDevice();
#endif
#if phase4
SAFE_RELEASE(g_pVB);
SAFE_RELEASE(g_pIB);
#endif
#if phase5 g_dlg_resource_manager.OnD3D9LostDevice(); #endif
} //--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
#if phase1
SAFE_RELEASE(pTeapotMesh);
#endif
#if phase3
SAFE_RELEASE(g_pEffect);
SAFE_RELEASE(g_pCubeEnvTex);
#endif
#if phase5
g_dlg_resource_manager.OnD3D9DestroyDevice();
#endif
}
#if phase5
//--------------------------------------------------------------------------------------
// Handle events for controls
//--------------------------------------------------------------------------------------
void CALLBACK OnGUIEvent(UINT event, int control_id, CDXUTControl* control, void* user_context)
{ switch(control_id)
{
case IDC_COMBO_TECH:
{
DXUTComboBoxItem* pSelectedItem = ( ( CDXUTComboBox* )control )->GetSelectedItem();
if( pSelectedItem )
g_nCurrentTechID = ( int )( INT_PTR )pSelectedItem->pData;
break;
}
}
} //--------------------------------------------------------------------------------------
// Initialize dialogs
//--------------------------------------------------------------------------------------
void InitDialogs()
{
int x = 35, y = 10, width = 125, height = 22;
g_control_dlg.Init(&g_dlg_resource_manager);
g_control_dlg.SetCallback(OnGUIEvent); y = 10;
g_control_dlg.AddComboBox(IDC_COMBO_TECH, x, y += 24, width, height);
g_control_dlg.GetComboBox(IDC_COMBO_TECH)->AddItem(L"Reflection", ( LPVOID )REFLECTION);
g_control_dlg.GetComboBox(IDC_COMBO_TECH)->AddItem(L"Refraction", ( LPVOID )REFRACTION);
g_control_dlg.GetComboBox(IDC_COMBO_TECH)->AddItem(L"Fresnel", ( LPVOID )FRESNEL);
g_control_dlg.GetComboBox(IDC_COMBO_TECH)->AddItem(L"Chromatic Dispersion", ( LPVOID )DISPERSION); }
#endif //--------------------------------------------------------------------------------------
// Initialize everything and go into a render loop
//--------------------------------------------------------------------------------------
INT WINAPI wWinMain( HINSTANCE, HINSTANCE, LPWSTR, int )
{
// Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif // Set the callback functions
DXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );
DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );
DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );
DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );
DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );
DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );
DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );
DXUTSetCallbackMsgProc( MsgProc );
DXUTSetCallbackFrameMove( OnFrameMove );
#if phase5
InitDialogs();
#endif
// TODO: Perform any application-level initialization here // Initialize DXUT and create the desired Win32 window and Direct3D device for the application
DXUTInit( true, true ); // Parse the command line and show msgboxes
DXUTSetHotkeyHandling( true, true, true ); // handle the default hotkeys
DXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screen
DXUTCreateWindow( L"3D_Shader_CubeEnvMapping" );
DXUTCreateDevice( true, 1024, 768 ); // Start the render loop
DXUTMainLoop(); // TODO: Perform any application-level cleanup here return DXUTGetExitCode();
}
/*--------------------------------------------------------------------------
CubeEnvMapping.fx -- cubic environment mapping shader
(c) Seamanj.2013/8/28
--------------------------------------------------------------------------*/ //--------------------------------------------------------------------------------------
// Global variables
//--------------------------------------------------------------------------------------
float4x4 g_mWorldViewProj;
float4x4 g_mWorld;
float4x4 g_mWorldInv;
float3 g_eyePosition;
texture g_txCubeEnvMap;
float g_fEtaRatio;
float g_fFresnelBias;
float g_fFresnelScale;
float g_fFresnelPower; float3 g_fRGBEtaRatio;
//-----------------------------------------------------------------------------
// Sampler
//-----------------------------------------------------------------------------
samplerCUBE g_samCubeEnvMap =
sampler_state
{
Texture = <g_txCubeEnvMap>;
MinFilter = Linear;
MagFilter = Linear;
MipFilter = Linear;
}; //--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct Reflection_VS_Output {
float4 position : POSITION;
float3 Reflection : TEXCOORD0;
}; //--------------------------------------------------------------------------------------
// Vertex shader
//--------------------------------------------------------------------------------------
Reflection_VS_Output ReflectionVertexEntry(float4 position : POSITION,float3 normal : NORMAL)
{
Reflection_VS_Output OUT; OUT.position = mul ( position, g_mWorldViewProj); normal = mul ( normal, transpose((float3x3)g_mWorldInv));
normal = normalize(normal);
float3 positionW = mul(position, g_mWorld).xyz;
float3 I = positionW - g_eyePosition;
OUT.Reflection = reflect(I, normal);
return OUT;
}
struct Refraction_VS_Output {
float4 position : POSITION;
float3 Refraction : TEXCOORD0;
};
Refraction_VS_Output RefractionVertexEntry(float4 position : POSITION,float3 normal : NORMAL)
{
Refraction_VS_Output OUT; OUT.position = mul ( position, g_mWorldViewProj); normal = mul ( normal, transpose((float3x3)g_mWorldInv));
normal = normalize(normal);
float3 positionW = mul(position, g_mWorld).xyz;
float3 I = positionW - g_eyePosition;
OUT.Refraction = refract(I, normal, g_fEtaRatio);
return OUT;
}
struct Fresnel_VS_Output {
float4 position : POSITION;
float reflectionFactor : COLOR;
float3 Reflection : TEXCOORD0;
float3 Refraction : TEXCOORD1;
};
Fresnel_VS_Output FresnelVertexEntry(float4 position : POSITION,float3 normal : NORMAL)
{
Fresnel_VS_Output OUT; OUT.position = mul ( position, g_mWorldViewProj); normal = mul ( normal, transpose((float3x3)g_mWorldInv));
normal = normalize(normal);
float3 positionW = mul(position, g_mWorld).xyz;
float3 I = positionW - g_eyePosition;
OUT.reflectionFactor = g_fFresnelBias + g_fFresnelScale * pow(1 + dot(I, normal), g_fFresnelPower);
OUT.Reflection = reflect(I, normal);
OUT.Refraction = refract(I, normal, g_fEtaRatio);
return OUT;
}
struct Dispersion_VS_Output {
float4 position : POSITION;
float reflectionFactor : COLOR;
float3 Reflection : TEXCOORD0;
float3 RedRefraction : TEXCOORD1;
float3 GreenRefraction : TEXCOORD2;
float3 BlueRefraction : TEXCOORD3;
};
Dispersion_VS_Output DispersionVertexEntry(float4 position : POSITION,float3 normal : NORMAL)
{
Dispersion_VS_Output OUT; OUT.position = mul ( position, g_mWorldViewProj); normal = mul ( normal, transpose((float3x3)g_mWorldInv));
normal = normalize(normal);
float3 positionW = mul(position, g_mWorld).xyz;
float3 I = positionW - g_eyePosition;
OUT.reflectionFactor = g_fFresnelBias + g_fFresnelScale * pow(1 + dot(I, normal), g_fFresnelPower);
OUT.Reflection = reflect(I, normal);
OUT.RedRefraction = refract(I, normal, g_fRGBEtaRatio.x);
OUT.GreenRefraction = refract(I, normal, g_fRGBEtaRatio.y);
OUT.BlueRefraction = refract(I, normal, g_fRGBEtaRatio.z);
return OUT;
} //--------------------------------------------------------------------------------------
// Pixel shader
//--------------------------------------------------------------------------------------
float4 ReflectionPixelEntry(float3 Reflection : TEXCOORD0) : COLOR
{
return texCUBE(g_samCubeEnvMap, Reflection);
} float4 RefractionPixelEntry(float3 Refraction : TEXCOORD0) : COLOR
{
return texCUBE(g_samCubeEnvMap, Refraction);
} float4 FresnelPixelEntry(float reflectionFactor : COLOR,
float3 Reflection : TEXCOORD0,
float3 Refraction : TEXCOORD1) : COLOR
{
float4 reflectedColor = texCUBE(g_samCubeEnvMap, Reflection);
float4 refractedColor = texCUBE(g_samCubeEnvMap, Refraction);
float4 color = lerp( refractedColor, reflectedColor, reflectionFactor );
return color;
} float4 DispersionPixelEntry(float reflectionFactor : COLOR,
float3 Reflection : TEXCOORD0,
float3 RedRefraction : TEXCOORD1,
float3 GreenRefraction : TEXCOORD2,
float3 BlueRefraction : TEXCOORD3) : COLOR
{
float4 reflectedColor = texCUBE(g_samCubeEnvMap, Reflection);
float4 refractedColor;
refractedColor.x = texCUBE(g_samCubeEnvMap, RedRefraction).x;
refractedColor.y = texCUBE(g_samCubeEnvMap, GreenRefraction).y;
refractedColor.z = texCUBE(g_samCubeEnvMap, BlueRefraction).z;
refractedColor.w = 1;
float4 color = lerp( refractedColor, reflectedColor, reflectionFactor );
return color;
}
//--------------------------------------------------------------------------------------
// Renders scene to render target
//--------------------------------------------------------------------------------------
technique ReflectionTechnique
{
pass P0
{
VertexShader = compile vs_2_0 ReflectionVertexEntry();
PixelShader = compile ps_2_0 ReflectionPixelEntry();
}
}
technique RefractionTechnique
{
pass P0
{
VertexShader = compile vs_2_0 RefractionVertexEntry();
PixelShader = compile ps_2_0 RefractionPixelEntry();
}
}
technique FresnelTechnique
{
pass P0
{
VertexShader = compile vs_2_0 FresnelVertexEntry();
PixelShader = compile ps_2_0 FresnelPixelEntry();
}
}
technique DispersionTechnique
{
pass P0
{
VertexShader = compile vs_2_0 DispersionVertexEntry();
PixelShader = compile ps_2_0 DispersionPixelEntry();
}
}

可执行程序以及相关源代码请点击这里下载

3DShader之立方体环境映射(cubic environment mapping)的更多相关文章

  1. CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)

    CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction) 开始 如图所示,本文围绕GLSL里的sam ...

  2. 《The Cg Tutorial》阅读笔记——环境贴图 Environment Mapping

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4969956.html 环境贴图 Environment Mapping 一.简介 环 ...

  3. 3DShader之法线贴图(normal mapping)

    凹凸贴图(bump mapping)实现的技术有几种,normal mapping属于其中的一种,这里实现在物体的坐标系空间中实现的,国际惯例,上图先: 好了讲下原理 可以根据高度图生成法线量图,生成 ...

  4. 3DShader之移位贴图(Displacement Mapping)

    我们知道法线贴图是只是改了物体的法线属性,用来计算光照,但是并没有改变物体本身的网格.但是移位贴图就不一样了,它会移动物体的顶点.我用移位贴图做了个海洋,好了,上了图再讲: 注意看海的边缘的顶点,已经 ...

  5. Environment Perception: 3D Truss Environment Mapping and Parametric Expression Extraction

    Experiments Preparation roscore rosrun pcl_ros pcd_to_pointcloud ~/.ros/wh2_lg707070_1ms0.01_filtere ...

  6. (转)OpenGL学习——立方体贴图

    转自:https://learnopengl-cn.readthedocs.io/zh/latest/04%20Advanced%20OpenGL/06%20Cubemaps/ 我们之前一直使用的是2 ...

  7. 实时渲染基础(4)纹理(Texture)

    目录 纹理映射(Texture Mapping) 球形贴图(Spherical Map) 立方体贴图(Cube Map) 纹理走样问题 Mipmap 各向异性过滤(Ripmap) 纹理应用技术(Tex ...

  8. 从零3D基础入门XNA 4.0(2)——模型和BasicEffect

    [题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...

  9. 【ZZ】 DShader之位移贴图(Displacement Mapping)

    http://www.myexception.cn/other/1397638.html DShader之位移贴图(Displacement Mapping) www.MyException.Cn   ...

随机推荐

  1. KbmMW资源汇总(更新中…)

    KbmMW框架是收费的,不在此提供下载,如需购买,请自行联系作者Kim Madsen. 网址资源: 官网主页:http://www.components4programmers.com/product ...

  2. 发布Qt Quick桌面应用程序的方法

    这个对话框出现的原因可能是msvcrt.dll在XP这个版本没有vsprintf_s这样的动态库.目前还暂时没有找到好的解决思路,稍后我再单独研究一下,看这个事情该如何解决. 解决办法有很多,我没有一 ...

  3. 动态规划 最长公共子序列 LCS,最长单独递增子序列,最长公共子串

    LCS:给出两个序列S1和S2,求出的这两个序列的最大公共部分S3就是就是S1和S2的最长公共子序列了.公共部分 必须是以相同的顺序出现,但是不必要是连续的. 选出最长公共子序列.对于长度为n的序列, ...

  4. VC中TRACE()的用法

    个人总结:最近看网络编程是碰到了TRACE语句,不知道在哪里输出,查了一晚上资料也没找出来,今天终于在CSDN上找到了,真是个高地方啊,方法如下: 1.在MFC中加入TRACE语句 2.在TOOLS- ...

  5. 最新Android ADT, SDK, SDK_tool等官方下载说明(及时更新)

    1.Android SDK starter package SDK starter package http://dl.google.com/android/installer_r08-windows ...

  6. android应用如何启动另外一个apk应用

    在开发的过程中,经常会遇到在一个应用中启动另外一个apk应用的情况 问题的核心点在于我们要拿到第三方apk的package名称跟class名称, 如:package名称是com.funcity.tax ...

  7. javascript实现模仿迅雷电影评分

    效果图: 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...

  8. load、save方法、spark sql的几种数据源

    load.save方法的用法          DataFrame usersDF = sqlContext.read().load("hdfs://spark1:9000/users.pa ...

  9. 内联函数 inline

    (一)inline函数(摘自C++ Primer的第三版) 在函数声明或定义中函数返回类型前加上关键字inline即把min()指定为内联. inline int min(int first, int ...

  10. BZOJ 1455: 罗马游戏( 配对堆 + 并查集 )

    可并堆水题 --------------------------------------------------------- #include<bits/stdc++.h>   usin ...