refactored lensflare geometry shader
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user