//設成只畫背面、開啟depth test glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); glDepthMask(GL_TRUE); glEnable(GL_DEPTH_TEST); |
glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, shadowMapTexture); glActiveTexture(GL_TEXTURE0); //之後畫模型時將模型的貼圖放在slot 0 |
float → float
float4 → vec4
線性內插 lerp() → mix()
很多函式都同名,如normalize、dot、clamp。
float4x3 → mat3x4
矩陣的行數和列數寫法相反。
mul(float4, float4x3) → vec4*mat3x4
向量與矩陣相乘HLSL必須用mul函式,GLSL可以用乘號。
//要先除以w float3 shadowMapPos = IN.shadowMapPos.xyz/IN.shadowMapPos.w; //此時xy=-1~1,轉換成0~1且y要反向 shadowMapPos.xy = shadowMapPos.xy*float2(0.5,-0.5) + 0.5; |
//要先除以w vec3 shadowMapPos = varShadowMapPos.xyz/varShadowMapPos.w; //此時xyz=-1~1,轉換成0~1,跟D3D不同的是y不需要反向 shadowMapPos = shadowMapPos*0.5 + 0.5; |
//programID代表OpenGL的program物件 glUseProgram(programID); int location=glGetUniformLocation(programID, "shadowMapSampler"); glUniform1i(location, 1); |
//Direct3D float3 shadowMapPos=IN.shadowMapPos.xyz/IN.shadowMapPos.w; shadowMapPos.xy = shadowMapPos.xy*float2(0.5,-0.5)+0.5; return float4(shadowMapPos.xyz,1); //OpenGL vec3 shadowMapPos=varShadowMapPos.xyz/varShadowMapPos.w; shadowMapPos = shadowMapPos*0.5+0.5; gl_FragColor=vec4(shadowMapPos.xyz,1); |
//Direct3D float3 shadowMapPos=IN.shadowMapPos.xyz/IN.shadowMapPos.w; shadowMapPos.xy = shadowMapPos.xy*float2(0.5,-0.5)+0.5; float4 depth = shadowMap1.Sample(defaultSampler, shadowMapPos.xy); return float4(depth.rrr,1); //OpenGL vec3 shadowMapPos=varShadowMapPos.xyz/varShadowMapPos.w; shadowMapPos = shadowMapPos*0.5+0.5; vec4 depth = texture(defaultSampler2, shadowMapPos.xy); gl_FragColor=vec4(depth.rrr,1); |
//這樣寫會錯 glGenSamplers(1, &samplerObj); glSamplerParameteri(samplerObj, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameteri(samplerObj, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); …… glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); //解法一 glGenSamplers(1, &samplerObj); glSamplerParameteri(samplerObj, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameteri(samplerObj, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); …… glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0); //解法二 glGenSamplers(1, &samplerObj); glSamplerParameteri(samplerObj, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glSamplerParameteri(samplerObj, GL_TEXTURE_MIN_FILTER, GL_LINEAR); …… glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); |
D3D11_TEXTURE2D_DESC td; td.ArraySize = 6; td.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; td.Format = DXGI_FORMAT_R16_TYPELESS; …… //之後用CreateTexture2D()建立ID3D11Texture2D物件 |
//要建立這些物件 ID3D11ShaderResourceView* srView; ID3D11DepthStencilView* dsView[6]; ID3D11DepthStencilView** dsViewPtr=dsView; //texture是已經建好的ID3D11Texture2D物件 D3D11_SHADER_RESOURCE_VIEW_DESC srDesc; ZeroMemory(&srDesc, sizeof(D3D11_SHADER_RESOURCE_VIEW_DESC)); srDesc.Format=DXGI_FORMAT_R16_UNORM; srDesc.ViewDimension=D3D11_SRV_DIMENSION_TEXTURECUBE; srDesc.TextureCube.MipLevels=1; device->CreateShaderResourceView(texture, &srDesc, &srView); D3D11_DEPTH_STENCIL_VIEW_DESC dsDesc; ZeroMemory(&dsDesc, sizeof(D3D11_DEPTH_STENCIL_VIEW_DESC)); dsDesc.Format=DXGI_FORMAT_D16_UNORM; dsDesc.ViewDimension=D3D11_DSV_DIMENSION_TEXTURE2DARRAY; dsDesc.Texture2DArray.ArraySize=1; //用迴圈建立六個depth stencil view for(int i=0;i<6;i++){ dsDesc.Texture2DArray.FirstArraySlice=i; device->CreateDepthStencilView(texture, &dsDesc, dsViewPtr); dsViewPtr++; } |
float rotMatix[9]; //暫存的旋轉矩陣 for(int i=0;i<6;i++){ //套用depth stencil view context->OMSetRenderTargets(0, NULL, dsView[i]); context->ClearDepthStencilView(dsView[i], 0.0, DEPTH_CLEAR_VALUE,0); //計算旋轉矩陣,這一步還未完成 oneCubeFace(rotMatix, this->rotTr, FACE_DIR[i],FACE_TOP_DIR[i]); //用uniform buffer把shadow map位置傳給shader PerSceneUniform* data=(PerSceneUniform*)mapUniformBuffer( sppl->perSceneUniform, sizeof(SP3DCamera)); this->calcViewProj(rotMatix, &data->camera); unmapUniformBuffer(sppl->perSceneUniform); //畫出物件 ListIter iter; for(iter=objList->begin();iter!=objList->end();iter=iter->next()){ SP3DObjBase* obj=(SP3DObjBase*)iter->data; if(obj->flags & _3DOBJ_VISIBLE){ obj->draw(SP3DObjBase::DRAWTYPE_ZPASS); } } } |
context->PSSetShaderResources(2,1, &srView); |
Texture2D<float4> texture1:register(t0); //一般貼圖 Texture2D<float> shadowMap1:register(t1); //平面shadow map TextureCube<float> cubeShadowMap1:register(t2); //cube shadow map |
//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比較的值 |
//shadowMapPos是vertex shader算出來,像素在shadow map裡的位置 //對照:讀取平面shadow map的方法 float3 shadowMapPos=shadowMapPos.xyz/shadowMapPos.w; shadowMapPos.xy= shadowMapPos.xy*float2(0.5,-0.5) + 0.5; //SampleCmpLevelZero參數為(sampler, 貼圖坐標, 要跟shadow map比較的值) float notInShadow=shadowMap1.SampleCmpLevelZero( shadowMapSampler, shadowMapPos.xy, shadowMapPos.z); //cubemap要這樣寫 float3 absValue=abs(shadowMapPos.xyz); float maxComponent = max(absValue.x, max(absValue.y, absValue.z)); float notInShadow=cubeShadowMap1.SampleCmpLevelZero( shadowMapSampler, shadowMapPos.xyz, shadowMapPos.w/maxComponent); |
活動與參展 (0)
└活動與參展資訊 (1)
└活動與製作後記 (11)
└販售會遊戲團調查 (14)
遊戲團隊「電子妖精實驗室」 (0)
└重要消息 (4)
└Cyber Sprite遊戲秘密 (2)
└製作進度 (26)
創作 (0)
└繪圖 (24)
└程式 (51)
└故事、劇本 (3)
Lobster0627 給 各位巴友:
大家可以多多來我的YT頻道看看哦(*´∀`)~♥https://www.youtube.com/@lobstersandwich0627看更多我要大聲說2小時前