//貼圖大小 const int TEX_W=64; const int TEX_H=64; const int TEX_PIXEL_NUM=TEX_W*TEX_H; //要建立的物件 ID3D11ShaderResourceView* cubeTexture; //create cube texture HRESULT hr; D3D11_TEXTURE2D_DESC td; td.Width=TEX_W; td.Height=TEX_H; td.MipLevels=1; td.ArraySize=6; //single image or cubemap td.Format=DXGI_FORMAT_B8G8R8A8_UNORM; td.SampleDesc.Count=1; //multisample sample number td.SampleDesc.Quality=0; td.Usage=D3D11_USAGE_DEFAULT; td.BindFlags=D3D11_BIND_SHADER_RESOURCE; td.CPUAccessFlags = 0; td.MiscFlags=D3D11_RESOURCE_MISC_TEXTURECUBE; ID3D11Texture2D* texture; hr=device->CreateTexture2D(&td, NULL, &texture); const uint32_t CUBE_FACES[]={0xffff0000, 0xff800000, 0xff00ff00, 0xff008000, 0xff0000ff,0xff000080}; //產生64×64 pixel的buffer uint32_t colorBuffer[TEX_PIXEL_NUM]; for(int i=0;i<6;i++){ for(int j=0;j<TEX_PIXEL_NUM;j++){ colorBuffer[j]=CUBE_FACES[i]; } colorBuffer[0]=0xffffffff; colorBuffer[1]=0xffffffff; colorBuffer[TEX_W]=0xffffffff; colorBuffer[TEX_W+1]=0xffffffff; colorBuffer[TEX_W-2]=0xff808080; colorBuffer[TEX_W-1]=0xff808080; colorBuffer[TEX_W*2-2]=0xff808080; colorBuffer[TEX_W*2-1]=0xff808080; colorBuffer[TEX_PIXEL_NUM-TEX_W-2]=0xff000000; colorBuffer[TEX_PIXEL_NUM-TEX_W-1]=0xff000000; colorBuffer[TEX_PIXEL_NUM-2]=0xff000000; colorBuffer[TEX_PIXEL_NUM-1]=0xff000000; context->UpdateSubresource(texture,i,NULL,colorBuffer, TEX_W*4, 0); } hr=device->CreateShaderResourceView(texture, NULL, &cubeTexture); texture->Release(); //扣掉CreateTexture2D()的reference count |
TextureCube<float4> cubeTexture1:register(t1); SamplerState defaultSampler:register(s0); struct DrawCubemapVsIn{ float2 pos:P; float3 cubeTexCoord:T; }; struct DrawCubemapVsOut{ float4 pos:SV_Position; float3 cubeTexCoord:T; }; void drawCubemapVS(in DrawCubeMapVsIn IN,out DrawCubeMapVsOut OUT){ OUT.pos=float4(IN.pos,0,1); OUT.cubeTexCoord=IN.cubeTexCoord; } float4 drawCubemapPS(in DrawCubeMapVsOut IN): SV_Target{ return cubeTexture1.Sample(defaultSampler, IN.cubeTexCoord); } |
struct DrawCubeVertex{ float pos[2]; //螢幕坐標 float cubeTexCoord[3]; //cubemap貼圖坐標 }; const DrawCubeVertex DRAW_CUBEMAP_VERTEX[]={ {-1, 0.25, 1, 1,-1}, //+X左邊 {-1, -0.25, 1,-1,-1}, {-0.5, 0.25, 1, 1, 1}, //+X與+Z的邊 {-0.5,-0.25, 1,-1, 1}, {0, 0.25, -1, 1,1}, //+Z與-X的邊 {0,-0.25, -1,-1,1}, {0.5, 0.25, -1, 1,-1}, //-X與-Z的邊 {0.5,-0.25, -1,-1,-1}, {1, 0.25, 1, 1,-1}, //-Z右邊 {1,-0.25, 1,-1,-1}, {1,-0.25, 0,0,0}, //dummy {-1,0.75, 0,0,0}, {-1, 0.75, -1, 1,-1}, //+Y face {-1, 0.25, 1, 1,-1}, {-0.5, 0.75,-1, 1, 1}, {-0.5, 0.25, 1, 1,1}, {-0.5, 0.25, 0,0,0}, //dummy {-1, -0.25, 0,0,0}, {-1, -0.25, 1, -1,-1}, //-Y face {-1, -0.75, -1, -1,-1}, {-0.5,-0.25, 1, -1, 1}, {-0.5,-0.75,-1, -1, 1}, }; const int DRAW_CUBEMAP_VERTEX_NUM = sizeof(DRAW_CUBEMAP_VERTEX)/sizeof(DrawCubeVertex); //幾何圖形設成triangle strip |
//貼圖大小 const int TEX_W=64; const int TEX_H=64; const int TEX_PIXEL_NUM=TEX_W*TEX_H; //要建立的物件 ID3D11ShaderResourceView* cubeTexture; ID3D11RenderTargetView* cubeRenderTarget[6]; //create cube texture HRESULT hr; D3D11_TEXTURE2D_DESC td; td.Width=TEX_W; td.Height=TEX_H; td.MipLevels=1; td.ArraySize=6; //single image or cubemap td.Format=DXGI_FORMAT_B8G8R8A8_UNORM; td.SampleDesc.Count=1; //multisample sample number td.SampleDesc.Quality=0; td.Usage=D3D11_USAGE_DEFAULT; //BindFlags跟上面不一樣 td.BindFlags=D3D11_BIND_SHADER_RESOURCE|D3D11_BIND_RENDER_TARGET; td.CPUAccessFlags = 0; td.MiscFlags=D3D11_RESOURCE_MISC_TEXTURECUBE; ID3D11Texture2D* texture; hr=device->CreateTexture2D(&td, NULL, &texture); D3D11_RENDER_TARGET_VIEW_DESC rtDesc; rtDesc.Format=DXGI_FORMAT_B8G8R8A8_UNORM; rtDesc.ViewDimension=D3D11_RTV_DIMENSION_TEXTURE2DARRAY; rtDesc.Texture2DArray.MipSlice=0; rtDesc.Texture2DArray.ArraySize=1; //六面各建立一個render target view for(int i=0;i<6;i++){ rtDesc.Texture2DArray.FirstArraySlice=i; hr=device->CreateRenderTargetView(texture, &rtDesc, cubeRenderTarget+i); } hr=device->CreateShaderResourceView(texture, NULL, &cubeTexture); texture->Release(); //扣掉CreateTexture2D()的reference count |
struct UpdateCubemapVsOut{ float4 pos:SV_Position; float2 screenCoord:P; }; void updateCubemapVS(in float2 pos:P, out UpdateCubemapVsOut OUT){ //將-1~1變為0~1 OUT.screenCoord=pos*0.5+0.5; OUT.pos=float4(pos,0,1); } float4 updateCubemapPS(in UpdateCubemapVsOut IN): SV_Target{ return float4(IN.screenCoord.x, 0, IN.screenCoord.y, 1); } |
const float UPDATE_CUBEMAP_VERTEX[]={ -1,1, -1,-1, 1,1, 1,-1, }; |
//貼圖大小 const int TEX_W=64; const int TEX_H=64; const int TEX_PIXEL_NUM=TEX_W*TEX_H; //要建立的物件 uint32_t texture; //create cube texture glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_CUBE_MAP,texture); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); const int CUBE_FACES[]={0xffff0000, 0xff800000, 0xff00ff00, 0xff008000, 0xff0000ff,0xff000080}; //產生64×64 pixel的buffer uint32_t colorBuffer[TEX_PIXEL_NUM]; for(int i=0;i<6;i++){ for(int j=0;j<TEX_PIXEL_NUM;j++){ colorBuffer[j]=CUBE_FACES[i]; } colorBuffer[0]=0xffffffff; colorBuffer[1]=0xffffffff; colorBuffer[TEX_W]=0xffffffff; colorBuffer[TEX_W+1]=0xffffffff; colorBuffer[TEX_W-2]=0xff808080; colorBuffer[TEX_W-1]=0xff808080; colorBuffer[TEX_W*2-2]=0xff808080; colorBuffer[TEX_W*2-1]=0xff808080; colorBuffer[TEX_PIXEL_NUM-TEX_W-2]=0xff000000; colorBuffer[TEX_PIXEL_NUM-TEX_W-1]=0xff000000; colorBuffer[TEX_PIXEL_NUM-2]=0xff000000; colorBuffer[TEX_PIXEL_NUM-1]=0xff000000; glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA8, TEX_W, TEX_H, 0, GL_BGRA, GL_UNSIGNED_BYTE, colorBuffer); } |
//====common //要用OpenGL 3.3的規格 //如果不加這行,會視為最早的1.0版編譯 #version 330 core //====drawCubemapVS layout(location=0) in vec2 pos; layout(location=1) in vec3 cubeTexCoord; varying vec3 varCubeTexCoord; void main(){ varCubeTexCoord=cubeTexCoord; gl_Position=vec4(pos,0,1); } //====drawCubemapPS varying vec3 varCubeTexCoord; uniform samplerCube cubeTexture1; void main(){ gl_FragColor=texture(cubeTexture1,varCubeTexCoord); } |
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); |
//貼圖大小 const int TEX_W=64; const int TEX_H=64; const int TEX_PIXEL_NUM=TEX_W*TEX_H; //要建立的物件 uint32_t texture; uint32_t framebuffer[6]; //create cube texture glGenTextures(1,&texture); glBindTexture(GL_TEXTURE_CUBE_MAP,texture); glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, 0); glGenFramebuffers(6,cubeFramebuffer); //六面各建立一個framebuffer物件 for(int i=0;i<6;i++){ glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, 0, GL_RGBA8, TEX_W, TEX_H, 0,GL_BGRA,GL_UNSIGNED_BYTE, 0); glBindFramebuffer(GL_FRAMEBUFFER,cubeFramebuffer[i]); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_CUBE_MAP_POSITIVE_X+i, texture, 0); } |
//====updateCubemapVS layout(location=0) in vec2 pos; varying vec2 varScreenCoord; void main(){ //將-1~1變為0~1 varScreenCoord=pos*0.5+0.5; gl_Position=vec4(pos,0,1); } //====updateCubemapPS varying vec2 varScreenCoord; void main(){ gl_FragColor=vec4(varScreenCoord.x,0,varScreenCoord.y,1); } |
const DrawCubeVertex DRAW_CUBEMAP_VERTEX[]={ {-1, 0.25, 1, 1, 1}, //+X左邊 {-1, -0.25, 1,-1, 1}, {-0.5, 0.25, 1, 1,-1}, //+X與-Z的邊 {-0.5,-0.25, 1,-1,-1}, {0, 0.25, -1, 1,-1}, //-Z與-X的邊 {0,-0.25, -1,-1,-1}, {0.5, 0.25, -1, 1, 1}, //-X與+Z的邊 {0.5,-0.25, -1,-1, 1}, {1, 0.25, 1, 1, 1}, //+Z右邊 {1,-0.25, 1,-1, 1}, {1,-0.25, 0,0,0}, //dummy {-1,0.75, 0,0,0}, {-1, 0.75, -1, 1, 1}, //+Y face {-1, 0.25, 1, 1, 1}, {-0.5, 0.75,-1, 1,-1}, {-0.5, 0.25, 1, 1,-1}, {-0.5, 0.25, 0,0,0}, //dummy {-1, -0.25, 0,0,0}, {-1, -0.25, 1, -1, 1}, //-Y face {-1, -0.75, -1, -1, 1}, {-0.5,-0.25, 1, -1,-1}, {-0.5,-0.75,-1, -1,-1}, }; |
//要把鏡頭面對這些方向 const float LOOKAT_DIR[6][3]={ {1,0,0}, //+X {-1,0,0}, //-X {0,1,0}, //+Y {0,-1,0}, //-Y {0,0,1}, //+Z {0,0,-1}, //-Z }; //上方,即旋轉後的Y軸 const float LOOKAT_TOP_DIR[6][3]={ {0,1,0}, {0,1,0}, {0,0,-1}, {0,0,1}, {0,1,0}, {0,1,0}, }; //第三個軸用外積求出 |
//float3 worldPos為頂點在世界坐標系的位置 OUT.shadowMapPos.xyz=mul(float4(worldPos,1), shadowMap.viewMatrix); float3 absValue=abs(OUT.shadowMapPos.xyz); float maxComponent = max(absValue.x, max(absValue.y, absValue.z)); OUT.shadowMapPos.w = maxComponent*shadowMap.projCoef.z+ shadowMap.projCoef.w; //shadowMapPos.xyz=鏡頭坐標系,w=要跟shadow map比較的值 |
//vertex shader只求出頂點在shadow map鏡頭坐標系的位置 OUT.shadowMapPos.xyz=mul(float4(worldPos,1), shadowMap.viewMatrix); OUT.shadowMapPos.w=0; //pixel shader float4 shadowMapPos=IN.shadowMapPos; float3 absValue=abs(shadowMapPos.xyz); float maxComponent = max(absValue.x, max(absValue.y, absValue.z)); //要與shadow map比較的值 shadowMapPos.w = maxComponent*shadowMap.projCoef.z + shadowMap.projCoef.w; shadowMapPos.w/=maxComponent; //仿照vertex shader算完後除以w的步驟 //用shadow sampler讀取貼圖 float notInShadow=cubeShadowMap1.SampleCmpLevelZero(shadowMapSampler, shadowMapPos.xyz, shadowMapPos.w); |
Windows Linux Windows App Android |
:Direct3D 11 feature level 10_0 :OpenGL 3.3 :Direct3D 11 feature level 9_3 :OpenGL ES 3.0 |
同標籤作品搜尋:Cyber Sprite|遊戲製作|程式|3D|Direct3D|OpenGL
留言共 0 篇留言
前一篇:【進度】3D背景—實裝影... 後一篇:C.S.Lab看板娘介紹...
活動與參展 (0)
└活動與參展資訊 (1)
└活動與製作後記 (11)
└販售會遊戲團調查 (14)
遊戲團隊「電子妖精實驗室」 (0)
└重要消息 (4)
└Cyber Sprite遊戲秘密 (2)
└製作進度 (26)
創作 (0)
└繪圖 (24)
└程式 (51)
└故事、劇本 (3)