refactored lensflare geometry shader

This commit is contained in:
turanszkij
2016-11-03 23:46:06 +01:00
parent 85ee9af8ff
commit 3f6e4efd8b
+43 -32
View File
@@ -1,27 +1,28 @@
#include "globals.hlsli"
// constant buffer
CBUFFER(LensFlareCB, CBSLOT_OTHER_LENSFLARE)
{
float4 xSunPos;
float4 xScreen;
float4 xSunPos; // light position
float4 xScreen; // screen dimensions
};
struct InVert{
float4 pos : SV_POSITION;
nointerpolation uint vid : VERTEXID;
struct InVert
{
float4 pos : SV_POSITION;
nointerpolation uint vid : VERTEXID;
};
struct VertextoPixel{
float4 pos : SV_POSITION;
float3 texPos : TEXCOORD0;
nointerpolation uint sel : TEXCOORD1;
nointerpolation float4 opa : TEXCOORD2;
float4 pos : SV_POSITION;
float3 texPos : TEXCOORD0; // texture coordinates (xy) + offset(z)
nointerpolation uint sel : TEXCOORD1; // texture selector
nointerpolation float4 opa : TEXCOORD2; // opacity + padding
};
//Texture2D<float> depth:register(t0);
//Texture2D flare[7]:register(t1);
inline void append(inout TriangleStream<VertextoPixel> triStream, VertextoPixel p1, uint selector, float2 posMod, float2 size){
// Append a screen space quad to the output stream:
inline void append(inout TriangleStream<VertextoPixel> triStream, VertextoPixel p1, uint selector, float2 posMod, float2 size)
{
float2 pos = (xSunPos.xy-0.5)*float2(2,-2);
float2 moddedPos = pos*posMod;
float dis = distance(pos,moddedPos);
@@ -43,20 +44,18 @@ inline void append(inout TriangleStream<VertextoPixel> triStream, VertextoPixel
p1.pos.xy=moddedPos+float2(size.x,size.y);
p1.texPos.xy=float2(1,1);
triStream.Append(p1);
//triStream.RestartStrip();
}
#define VERTEXCOUNT 4
// pre-baked offsets
// These values work well for me, but should be tweakable
static const float mods[] = { 1,0.55,0.4,0.1,-0.1,-0.3,-0.5 };
static const float mods[] = {1,0.55,0.4,0.1,-0.1,-0.3,-0.5};
//static const float size[] = {0.12,0.1,0.25,0.05,0.15,0.1,0.3};
[maxvertexcount(VERTEXCOUNT)]
[maxvertexcount(4)]
void main(point InVert p[1], inout TriangleStream<VertextoPixel> triStream)
{
VertextoPixel p1 = (VertextoPixel)0;
// Determine flare size from texture dimensions
float2 flareSize=float2(256,256);
[branch]
switch(p[0].vid){
@@ -84,25 +83,37 @@ void main(point InVert p[1], inout TriangleStream<VertextoPixel> triStream)
default:break;
};
// determine depthmap dimensions (could be screen dimensions from the constantbuffer)
float2 depthMapSize;
texture_depth.GetDimensions(depthMapSize.x,depthMapSize.y);
flareSize/=depthMapSize;
flareSize /= depthMapSize;
const float range = 10.5f;
// determine the flare opacity:
// These values work well for me, but should be tweakable
const float2 step = 1.0f / (depthMapSize*xSunPos.z);
const float2 range = 10.5f * step;
float samples = 0.0f;
float accdepth = 0.0f;
for (float y = -range; y <= range; y += 1.0f)
for (float x = -range; x <= range; x += 1.0f){
samples+=1.0f;
accdepth += (texture_depth.SampleCmpLevelZero(sampler_cmp_depth,xSunPos.xy+float2(x,y)/(depthMapSize*xSunPos.z),xSunPos.z).r ) ;
for (float y = -range.y; y <= range.y; y += step.y)
{
for (float x = -range.x; x <= range.x; x += step.x)
{
samples += 1.0f;
// texture_depth is non-linear depth (but it could work for linear too with linear reference value)
// SampleCmpLevelZero also makes a comparison by using a LESS_EQUAL comparison sampler
// It compares the reference value (xSunPos.z) to the depthmap value.
// Returns 0.0 if all samples in a bilinear kernel are greater than reference value
// Returns 1.0 if all samples in a bilinear kernel are less or equal than refernce value
// Can return in between values based on bilinear filtering
accdepth += (texture_depth.SampleCmpLevelZero(sampler_cmp_depth, xSunPos.xy + float2(x, y), xSunPos.z).r);
}
accdepth/=samples;
p1.pos=float4(0,0,0,1);
p1.opa=float4(accdepth,0,0,0);
}
accdepth /= samples;
p1.pos = float4(0, 0, 0, 1);
p1.opa = float4(accdepth, 0, 0, 0);
// Make a new flare if it is at least partially visible:
[branch]if( accdepth>0 )
append(triStream,p1,p[0].vid,mods[p[0].vid],flareSize);
}
}