3DShader之立方体环境映射(cubic environment mapping)

2023-11-10 20:58

本文主要是介绍3DShader之立方体环境映射(cubic environment mapping),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

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 blendingIDirect3D9* 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 phase2pDeviceSettings->d3d9.pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
#endifreturn 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 phase3HRESULT hr;
#endif
#if phase5V_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 phase1D3DXCreateTeapot( pd3dDevice, &pTeapotMesh, 0);
#endif#if phase3// Create vertex shaderWCHAR str[MAX_PATH];// Read the D3DX effect fileV_RETURN( DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"CubeEnvMapping.fx" ) );// Create the effect LPD3DXBUFFER pErrorBuff;V_RETURN( D3DXCreateEffectFromFile(pd3dDevice,		// associated devicestr,			// effect filenameNULL,			// no preprocessor definitionsNULL,			// no ID3DXInclude interfaceD3DXSHADER_DEBUG,	// compile flagsNULL,			// don't share parameters&g_pEffect,		// return effect&pErrorBuff			// return error messages) );//pErrorBuff// Get handleg_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 phase5g_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");
#endifreturn 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 bufferstatic 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 phase3HRESULT hr;if( g_pEffect )V_RETURN( g_pEffect->OnResetDevice() );
#endif
#if phase5V_RETURN(g_dlg_resource_manager.OnD3D9ResetDevice());// set dialog position and sizeg_control_dlg.SetLocation(pBackBufferSurfaceDesc->Width - 170, pBackBufferSurfaceDesc->Height - 350);g_control_dlg.SetSize(170, 300);
#endif
#if phase2pd3dDevice->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 !phase4return S_OK;
#else
#if phase1return 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 phase2g_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 sceneif( SUCCEEDED( pd3dDevice->BeginScene() ) ){#if phase3UINT iPass, cPasses;D3DXMATRIXA16 mWorldViewProjection,mWorld,mWorldInv;
#if !phase5V(g_pEffect->SetTechnique(g_hReflectionTech));
#elseswitch( 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;}
#endifV( g_pEffect->Begin( &cPasses, 0 ) );for( iPass = 0; iPass < cPasses; iPass++ ){V( g_pEffect->BeginPass( iPass ) );//set WorldViewProject matrixmWorldViewProjection = *g_Camera.GetWorldMatrix() * *g_Camera.GetViewMatrix() * *g_Camera.GetProjMatrix();V( g_pEffect->SetMatrix( g_hWorldViewProj, &mWorldViewProjection) );//set WorldView matrixmWorld = *g_Camera.GetWorldMatrix() ;V( g_pEffect->SetMatrix( g_hWorld, &mWorld) );//set WorldViewInv matrixmWorldInv = *D3DXMatrixInverse(&mWorldInv, 0, &mWorld);V( g_pEffect->SetMatrix( g_hWorldInv, &mWorldInv) );//set textureV( g_pEffect->SetTexture( g_hCubeEnvTex, g_pCubeEnvTex) );//set eye positionV( g_pEffect->SetFloatArray( g_hEyePosition, (const float*)(g_Camera.GetEyePt()), 3) );#if phase1pTeapotMesh->DrawSubset( 0 );
#endifV( g_pEffect->EndPass() );}V( g_pEffect->End() );
#endif
#if phase4pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);// Set world matrix  D3DXMATRIX M;D3DXMatrixIdentity( &M ); // M = identity matrixD3DXMatrixScaling(&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 phase5V(g_control_dlg.OnRender(fElapsedTime));
#endifV( pd3dDevice->EndScene() );}
}//--------------------------------------------------------------------------------------
// Handle messages to the application 
//--------------------------------------------------------------------------------------
LRESULT CALLBACK MsgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,bool* pbNoFurtherProcessing, void* pUserContext )
{
#if phase2g_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;
#endifreturn 0;
}//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9ResetDevice callback 
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9LostDevice( void* pUserContext )
{
#if phase3if( g_pEffect )g_pEffect->OnLostDevice();
#endif
#if phase4SAFE_RELEASE(g_pVB);SAFE_RELEASE(g_pIB);
#endif
#if phase5g_dlg_resource_manager.OnD3D9LostDevice();#endif
}//--------------------------------------------------------------------------------------
// Release D3D9 resources created in the OnD3D9CreateDevice callback 
//--------------------------------------------------------------------------------------
void CALLBACK OnD3D9DestroyDevice( void* pUserContext )
{
#if phase1SAFE_RELEASE(pTeapotMesh);
#endif
#if phase3SAFE_RELEASE(g_pEffect);SAFE_RELEASE(g_pCubeEnvTex);
#endif
#if phase5g_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 functionsDXUTSetCallbackD3D9DeviceAcceptable( IsD3D9DeviceAcceptable );DXUTSetCallbackD3D9DeviceCreated( OnD3D9CreateDevice );DXUTSetCallbackD3D9DeviceReset( OnD3D9ResetDevice );DXUTSetCallbackD3D9FrameRender( OnD3D9FrameRender );DXUTSetCallbackD3D9DeviceLost( OnD3D9LostDevice );DXUTSetCallbackD3D9DeviceDestroyed( OnD3D9DestroyDevice );DXUTSetCallbackDeviceChanging( ModifyDeviceSettings );DXUTSetCallbackMsgProc( MsgProc );DXUTSetCallbackFrameMove( OnFrameMove );
#if phase5InitDialogs();
#endif// TODO: Perform any application-level initialization here// Initialize DXUT and create the desired Win32 window and Direct3D device for the applicationDXUTInit( true, true ); // Parse the command line and show msgboxesDXUTSetHotkeyHandling( true, true, true );  // handle the default hotkeysDXUTSetCursorSettings( true, true ); // Show the cursor and clip it when in full screenDXUTCreateWindow( L"3D_Shader_CubeEnvMapping" );DXUTCreateDevice( true, 1024, 768 );// Start the render loopDXUTMainLoop();// TODO: Perform any application-level cleanup herereturn 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)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/385191

相关文章

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR

pip install pyaudio sounddevice error: externally-managed-environment

shgbitai@shgbitai-C9X299-PGF:~/pythonworkspace/ai-accompany$ pip install pyaudio sounddeviceerror: externally-managed-environment× This environment is externally managed╰─> To install Python package

Creating OpenAI Gym Environment from Map Data

题意:从地图数据创建 OpenAI Gym 环境 问题背景: I am just starting out with reinforcement learning and trying to create a custom environment with OpenAI gym. However, I am stumped with trying to create an enviro

Navicat Premium上出现Cannot create oci environment错误的解决办法

因为要连接运程的Orcale数据库,由于一些原因连不上,于是我把顶栏里的工具->选项->Oic(最最下面的一个)的oci.dll给替换了,然后就一直出现Cannot create oci environment这个错误 这是由于替换的oci.dll的版本不对,于是替换了各种版本有时候也会出现这个错误 最后就是因为版本不对,先看好安装的版本然后下载一个相对应的 下载地址:http://ww

【硬刚ES】ES基础(十二)多字段特性及Mapping中配置自定义Analyzer

本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的ES部分补充。

Servlet mapping specifies an unknown servlet name Action

看一下web.xml中<servlet-mapping>有没有配错

elasticsearch 2.3.4 java API 连接,ik分词器,设置集群节点,创建index,mapping的几种方式

1、默认集群连接 Client client = TransportClient.builder().build().addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("localhost"), 9300)); 2、自定义集群连接 Settings settings = S

【论文分享】MyTEE: Own the Trusted Execution Environment on Embedded Devices 23‘NDSS

目录 AbstractINTRODUCTIONBACKGROUNDARMv8 ArchitectureSecurity statesTrustZone extensionsVirtualization Communication with Peripherals MOTIVATIONATTACK MODEL AND ASSUMPTIONSYSTEM DESIGNOverviewExecu

Eclipse启动错误a java runtime environment

Windows下的Eclipse启动失败,如下图。 原因是找不到虚拟机,可能是Eclipse配置文件中的路径(一般是版本名)写错了,修改即可。 方法/步骤 打开eclipse文件中的eclipse.ini(后缀名如果看不到,可以通过查看属性 看到) 配置设置文件; 同时也打开java的jre文件。 仔细比较ecl

OpenGL/GLUT实践:绘制旋转的立方体与雪人世界——添加光照与SOIL方式添加纹理(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 运行效果2 实现过程2.1 几何转换2.1.1 窗口刷新2.1.2 绘制雪人场景2.1.2.1 绘制雪人2.1.2.2 绘制场景 2.1.3 键盘事件2.1.4 运行效果 2.2 颜色2.3 光照2.3.1 绘制正方体2.3.2 添加光源 2.4 材质2.4.1 方法一2.4.2 方法二 2.5 纹理2.5.1 SOIL环境