1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-23 23:14:47 +01:00

fix D3D11 shaders and samplers

This commit is contained in:
XProger 2019-04-18 04:43:47 +03:00
parent 97ca877ac3
commit 4c1c742d34
6 changed files with 109 additions and 78 deletions

View File

@ -52,6 +52,8 @@ void D3DCHECK(HRESULT res) {
#define D3DCHECK(res) res
#endif
#define MAX_SAMPLERS 5
namespace GAPI {
using namespace Core;
@ -73,6 +75,8 @@ namespace GAPI {
ID3D11RasterizerState *RS[cmMAX]; // [cullMode]
ID3D11DepthStencilState *DS[2][2]; // [depthTest][depthWrite]
ID3D11SamplerState *samplers[MAX_SAMPLERS];
// Shader
#include "shaders/d3d11/shaders.h"
@ -272,13 +276,12 @@ namespace GAPI {
ID3D11ShaderResourceView *SRV;
ID3D11RenderTargetView *RTV;
ID3D11DepthStencilView *DSV;
ID3D11SamplerState *sampler;
int width, height, depth, origWidth, origHeight, origDepth;
TexFormat fmt;
uint32 opt;
Texture(int width, int height, int depth, uint32 opt) : tex2D(NULL), tex3D(NULL), SRV(NULL), RTV(NULL), DSV(NULL), sampler(NULL), width(width), height(height), depth(depth), origWidth(width), origHeight(height), origDepth(depth), fmt(FMT_RGBA), opt(opt) {}
Texture(int width, int height, int depth, uint32 opt) : tex2D(NULL), tex3D(NULL), SRV(NULL), RTV(NULL), DSV(NULL), width(width), height(height), depth(depth), origWidth(width), origHeight(height), origDepth(depth), fmt(FMT_RGBA), opt(opt) {}
void init(void *data) {
ASSERT((opt & OPT_PROXY) == 0);
@ -389,8 +392,6 @@ namespace GAPI {
}
ASSERT(SRV);
initSampler();
}
void deinit() {
@ -399,48 +400,6 @@ namespace GAPI {
SAFE_RELEASE(SRV);
SAFE_RELEASE(RTV);
SAFE_RELEASE(DSV);
SAFE_RELEASE(sampler);
}
void initSampler() {
SAFE_RELEASE(sampler);
D3D11_SAMPLER_DESC desc;
memset(&desc, 0, sizeof(desc));
bool mipmaps = (opt & OPT_MIPMAPS) != 0;
bool filter = (opt & OPT_NEAREST) == 0;
if (mipmaps && (opt & (OPT_VOLUME | OPT_CUBEMAP | OPT_NEAREST)) == 0 && (Core::support.maxAniso > 0)) {
desc.MaxAnisotropy = min(int(Core::support.maxAniso), 8);
} else {
desc.MaxAnisotropy = 1;
}
if (desc.MaxAnisotropy > 1) {
desc.Filter = D3D11_FILTER_ANISOTROPIC;
} else {
if (filter) {
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
} else {
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
}
}
if (fmt == FMT_SHADOW) {
desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
desc.ComparisonFunc = D3D11_COMPARISON_LESS;
} else {
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
}
desc.AddressU =
desc.AddressV =
desc.AddressW = (opt & OPT_REPEAT) ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
desc.MinLOD = 0;
desc.MaxLOD = D3D11_FLOAT32_MAX;
device->CreateSamplerState(&desc, &sampler);
}
void generateMipMap() {
@ -466,10 +425,8 @@ namespace GAPI {
if (opt & OPT_VERTEX) {
deviceContext->VSSetShaderResources(sampler, 1, &SRV);
deviceContext->VSSetSamplers(sampler, 1, &this->sampler);
}
deviceContext->PSSetShaderResources(sampler, 1, &SRV);
deviceContext->PSSetSamplers(sampler, 1, &this->sampler);
}
}
@ -562,6 +519,66 @@ namespace GAPI {
} items[MAX_RENDER_BUFFERS];
} rtCache;
void deinitSamplers() {
for (int i = 0; i < COUNT(samplers); i++) {
SAFE_RELEASE(samplers[i]);
}
}
ID3D11SamplerState* initSampler(bool filter, bool aniso, bool wrap, bool cmp) {
D3D11_SAMPLER_DESC desc;
memset(&desc, 0, sizeof(desc));
if (aniso && (Core::support.maxAniso > 0)) {
desc.MaxAnisotropy = min(int(Core::support.maxAniso), 8);
} else {
desc.MaxAnisotropy = 1;
}
if (desc.MaxAnisotropy > 1) {
desc.Filter = D3D11_FILTER_ANISOTROPIC;
} else {
if (filter) {
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
} else {
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT;
}
}
if (cmp) {
desc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
desc.ComparisonFunc = D3D11_COMPARISON_LESS;
} else {
desc.ComparisonFunc = D3D11_COMPARISON_NEVER;
}
desc.AddressU =
desc.AddressV =
desc.AddressW = wrap ? D3D11_TEXTURE_ADDRESS_WRAP : D3D11_TEXTURE_ADDRESS_CLAMP;
desc.MinLOD = 0;
desc.MaxLOD = D3D11_FLOAT32_MAX;
ID3D11SamplerState *sampler;
device->CreateSamplerState(&desc, &sampler);
return sampler;
}
void initSamplers() {
deinitSamplers();
/*
0 - smpDefault
1 - smpPoint
2 - smpPointWrap
3 - smpLinear
4 - smpCmp
*/
samplers[0] = initSampler(true, true, false, false); // TODO settings dependent
samplers[1] = initSampler(false, false, false, false);
samplers[2] = initSampler(false, false, true, false);
samplers[3] = initSampler(true, false, false, false);
samplers[4] = initSampler(true, false, false, true);
}
void init() {
memset(&rtCache, 0, sizeof(rtCache));
@ -628,6 +645,7 @@ namespace GAPI {
#undef BLEND_FUNC
}
// init raster state
{
D3D11_RASTERIZER_DESC desc;
memset(&desc, 0, sizeof(desc));
@ -641,6 +659,7 @@ namespace GAPI {
device->CreateRasterizerState(&desc, &RS[cmFront]);
}
// init depth stencil states
{
D3D11_DEPTH_STENCIL_DESC desc;
memset(&desc, 0, sizeof(desc));
@ -656,6 +675,10 @@ namespace GAPI {
}
}
}
// init samplers
memset(samplers, 0, sizeof(samplers));
initSamplers();
}
void resetDevice() {
@ -666,6 +689,9 @@ namespace GAPI {
SAFE_RELEASE(rtCache.items[i].RTV);
SAFE_RELEASE(rtCache.items[i].DSV);
}
deinitSamplers();
rtCache.count = 0;
}
@ -747,6 +773,9 @@ namespace GAPI {
deviceContext->RSSetState(RS[cmNone]);
depthTest = depthWrite = dirtyDepthState = true;
colorWrite = dirtyBlendState = true;
deviceContext->VSGetSamplers(0, COUNT(samplers), samplers);
deviceContext->PSGetSamplers(0, COUNT(samplers), samplers);
}
void cacheRenderTarget(ID3D11RenderTargetView **RTV, ID3D11DepthStencilView **DSV, int width, int height) {

View File

@ -37,11 +37,11 @@ struct VS_INPUT {
};
#ifdef _GAPI_D3D11
SamplerState smpDefault : register(s0);
SamplerState smpPoint : register(s1);
SamplerState smpLinear : register(s2);
SamplerState smpAniso : register(s3);
SamplerComparisonState smpCmp : register(s4);
SamplerState smpDefault : register(s0);
SamplerState smpPoint : register(s1);
SamplerState smpPointWrap : register(s2);
SamplerState smpLinear : register(s3);
SamplerComparisonState smpCmp : register(s4);
Texture2D sDiffuse : register(t0);
#ifdef NORMAL_AS_3D
@ -54,13 +54,14 @@ struct VS_INPUT {
TextureCube sEnvironment : register(t4);
Texture2D sMask : register(t5);
#define SAMPLE_2D (T,uv) T.Sample(smpDefault, uv)
#define SAMPLE_2D_POINT (T,uv) T.Sample(smpPoint, uv)
#define SAMPLE_2D_LINEAR (T,uv) T.Sample(smpLinear, uv)
#define SAMPLE_2D_ANISO (T,uv) T.Sample(smpAniso, uv)
#define SAMPLE_2D_CMP (T,uv) T.SampleCmp(smpCmp, uv.xy, uv.z)
#define SAMPLE_3D (T,uv) T.Sample(smpLinear, uv)
#define SAMPLE_CUBE (T,uv) T.Sample(smpLinear, uv)
#define SAMPLE_2D(T,uv) T.Sample(smpDefault, uv)
#define SAMPLE_2D_POINT(T,uv) T.Sample(smpPoint, uv)
#define SAMPLE_2D_POINT_WRAP(T,uv) T.Sample(smpPointWrap, uv)
#define SAMPLE_2D_LINEAR(T,uv) T.Sample(smpLinear, uv)
#define SAMPLE_2D_CMP(T,uv) T.SampleCmp(smpCmp, uv.xy, uv.z)
#define SAMPLE_2D_LOD0(T,uv) T.SampleLevel(smpLinear, uv, 0)
#define SAMPLE_3D(T,uv) T.Sample(smpLinear, uv)
#define SAMPLE_CUBE(T,uv) T.Sample(smpLinear, uv)
#else
sampler2D sDiffuse : register(s0);
sampler2D sNormal : register(s1);
@ -69,13 +70,14 @@ struct VS_INPUT {
samplerCUBE sEnvironment : register(s4);
sampler2D sMask : register(s5);
#define SAMPLE_2D (T,uv) tex2D(T, uv)
#define SAMPLE_2D_POINT (T,uv) tex2D(T, uv)
#define SAMPLE_2D_LINEAR (T,uv) tex2D(T, uv)
#define SAMPLE_2D_ANISO (T,uv) tex2D(T, uv)
#define SAMPLE_2D_CMP (T,uv) ((tex2Dlod(T, uv.xy) => uv.z) ? 1 : 0)
#define SAMPLE_3D (T,uv) tex3D(T, uv)
#define SAMPLE_CUBE (T,uv) texCUBE(T, uv)
#define SAMPLE_2D(T,uv) tex2D(T, uv)
#define SAMPLE_2D_POINT(T,uv) tex2D(T, uv)
#define SAMPLE_2D_POINT_WRAP(T,uv) tex2D(T, uv)
#define SAMPLE_2D_LINEAR(T,uv) tex2D(T, uv)
#define SAMPLE_2D_LOD0(T,uv) tex2Dlod(T, float4(uv.xy, 0, 0))
#define SAMPLE_2D_CMP(T,uv) ((tex2D(T, uv.xy) => uv.z) ? 1 : 0)
#define SAMPLE_3D(T,uv) tex3D(T, uv)
#define SAMPLE_CUBE(T,uv) texCUBE(T, uv)
#endif
float4 uParam : register( c0 );
@ -143,9 +145,9 @@ float calcCausticsV(float3 coord) {
return 0.5 + abs(sin(dot(coord.xyz, 1.0 / 1024.0) + uParam.x)) * 0.75;
}
float3 calcNormalF(float2 tcR, float2 tcB, float base) {
float dx = SAMPLE_2D_LINEAR(sNormal, tcR).x - base;
float dz = SAMPLE_2D_LINEAR(sNormal, tcB).x - base;
float3 calcHeightMapNormal(float2 tcR, float2 tcB, float base) {
float dx = SAMPLE_2D_LOD0(sNormal, tcR).x - base;
float dz = SAMPLE_2D_LOD0(sNormal, tcB).x - base;
return normalize( float3(dx, 64.0 / (1024.0 * 8.0), dz) );
}
@ -181,7 +183,7 @@ float SHADOW(float2 p) {
#elif SHADOW_DEPTH
return SAMPLE_2D_POINT(sShadow, float4(p, 0, 0)).x;
#else
return unpack(SAMPLE_2D_POINT(sShadow, float4(p, 0, 0)));
return unpack(SAMPLE_2D_POINT(sShadow, p));
#endif
}

View File

@ -43,7 +43,7 @@ VS_OUTPUT main(VS_INPUT In) {
if (OPT_AMBIENT) {
Out.ambient = calcAmbient(Out.normal.xyz);
} else {
Out.ambient = min(uMaterial.yyy, In.aLight);
Out.ambient = min(uMaterial.yyy, In.aLight.xyz);
}
float4 lum, att, light;
@ -69,7 +69,7 @@ VS_OUTPUT main(VS_INPUT In) {
Out.light.xyz += Out.ambient + uLightColor[0].xyz * light.x;
}
Out.diffuse = float4(In.aColor * (uMaterial.x * 1.8), 1.0);
Out.diffuse = float4(In.aColor.xyz * (uMaterial.x * 1.8), 1.0);
Out.diffuse *= uMaterial.w;

View File

@ -27,8 +27,8 @@ VS_OUTPUT main(VS_INPUT In) {
float3 rCoord = float3(coord.x, coord.y, 0.0) * uPosScale[1].xzy;
float2 uv = getInvUV(rCoord.xy, uTexParam).xy;
float2 info = SAMPLE_2D_LINEAR(sNormal, float4(uv, 0, 0)).xy;
float3 normal = calcNormalV(uv, info.x).xzy;
float2 info = SAMPLE_2D_LOD0(sNormal, uv).xy;
float3 normal = calcHeightMapNormal(float2(uv.x + uTexParam.x, uv.y), float2(uv.x, uv.y - uTexParam.y), info.x).xzy;
float3 light = float3(0.0, 0.0, 1.0);
float3 refOld = refract(-light, float3(0.0, 0.0, 1.0), 0.75);

View File

@ -47,7 +47,7 @@ half4 main(VS_OUTPUT In) : COLOR0 {
float3 viewVec = normalize(In.viewVec.xyz);
float base = SAMPLE_2D_LINEAR(sNormal, In.texCoord).x;
float3 normal = calcNormalF(In.texCoordR, In.texCoordB, base);
float3 normal = calcHeightMapNormal(In.texCoordR, In.texCoordB, base);
float2 dudv = mul(uViewProj, float4(normal.x, 0.0, normal.z, 0.0)).xy * uParam.z;
float3 rv = reflect(-viewVec, normal);

View File

@ -44,7 +44,7 @@ float4 main(VS_OUTPUT In/*, float2 pixelCoord: VPOS*/) : COLOR0 {
float3 p0 = uViewPos.xyz - viewVec * t;
float3 p1 = In.coord.xyz;
float dither = SAMPLE_2D_POINT(sMask, float4(pixelCoord * (1.0 / 8.0), 0.0, 0.0)).x;
float dither = SAMPLE_2D_POINT_WRAP(sMask, pixelCoord * (1.0 / 8.0)).x;
float3 delta = (p1 - p0) / RAY_STEPS;
float3 pos = p0 + delta * dither;
@ -53,7 +53,7 @@ float4 main(VS_OUTPUT In/*, float2 pixelCoord: VPOS*/) : COLOR0 {
for (float i = 0.0; i < RAY_STEPS; i++) {
float3 wpos = (pos - uPosScale[0].xyz) / uPosScale[1].xyz;
float2 tc = wpos.xz * 0.5 + 0.5;
float light = SAMPLE_2D_LINEAR(sReflect, float4(tc, 0, 0)).x;
float light = SAMPLE_2D_LINEAR(sReflect, tc).x;
sum += light * (1.0 - (clamp(wpos.y, -1.0, 1.0) * 0.5 + 0.5));
pos += delta;
}