Skip to main content
remarks added about sign of normal.y and texture wrapping of a cone
Source Link
philB
  • 333
  • 2
  • 11
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
    //Note: with my DirectX setting I observed that I needed to make normal.y=-normal.y for correct lightning
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(NUV<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(NUV>0)) uv.r = intersect.z+0.65f;//outer left
    //for a proper uv cone wrapping : 
    //uv = float2(1-intersect.z, atan(intersect.y/intersect.x*sign(normal.x))*HalfInvPi+0.25f);
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(NUV<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(NUV>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
    //Note: with my DirectX setting I observed that I needed to make normal.y=-normal.y for correct lightning
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(NUV<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(NUV>0)) uv.r = intersect.z+0.65f;//outer left
    //for a proper uv cone wrapping : 
    //uv = float2(1-intersect.z, atan(intersect.y/intersect.x*sign(normal.x))*HalfInvPi+0.25f);
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
added 2 characters in body
Source Link
philB
  • 333
  • 2
  • 11
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(DU<0NUV<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(DU>0NUV>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(DU<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(DU>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(NUV<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(NUV>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
added 64 characters in body
Source Link
philB
  • 333
  • 2
  • 11
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(DU<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(DU>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(DU<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(DU>0)) uv.r = intersect.z+0.65f;//outer left
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
#define NormN 2.0f/sqrt(5.0f);
static const float3 LDir = normalize(float3(-1,1, -1));//Light dir

cbuffer cbCone: register(b6)
{
    matrix WVP;
    matrix InvRot;
    float4 TCamPos;
};

struct VS_INPUT // a generic type I'm using for my meshes
{
    float3 Pos : POSITION;
    float3 Norm : NORMAL;
    float4 Col : COLOR0;
    float2 Tex : TEXCOORD0;
};

struct PS_INPUT 
{
    float4 Pos : SV_POSITION;
    float3 MPos: TEXCOORD0;
    float Depth: TEXCOORD1;
    float3 Dir : TEXCOORD2;       
};


PS_INPUT VSCone(VS_INPUT v) 
{
    PS_INPUT o;
    o.Pos = mul(float4(v.Pos,1), WVP);
    o.Depth = o.Pos.w;
    o.MPos = v.Pos.xyz;
    o.MPos.z += 0.5f; 
    o.Dir = TCamPos-v.Pos.xyz;
    return o;
};

struct PS_Out 
{
    float4 colour : SV_TARGET0;
    float depth : SV_DEPTH;
};

PS_Out PSCone(PS_INPUT i) 
{
    PS_Out o;
    float a =     dot(i.Dir.xy,  i.Dir.xy)  - 0.25f * i.Dir.z  * i.Dir.z;
    float b = 2 * dot(i.MPos.xy, i.Dir.xy)  - 0.5f  * i.MPos.z * i.Dir.z;
    float c =     dot(i.MPos.xy, i.MPos.xy) - 0.25f * i.MPos.z * i.MPos.z;
    float disc = b*b - 4 * a * c;
    clip(disc);
    float step = sqrt(disc);
    float invA = 1.0f/a;
    float t = (-b + step)*0.5f*invA;
    float NUV = 1;
    if ((t < 0) || (i.MPos.z + t * i.Dir.z > 1))  
    {
        t -= step*invA;
        NUV = -1;// keep track of inverted step for normal and uv coordinate calculs
    }
    float3 intersect = i.MPos + t * i.Dir;
    clip(intersect.z * (1-intersect.z));
    float3 normal = float3(normalize(intersect.xy), 0.5f)* NormN*NUV;
    normal = normalize( mul(normal, (float3x3)InvRot));
//Set colors as 0 or 1 based on intersect.xy values
    o.colour.r = (intersect.x>0)?0.5:1;
    o.colour.g = (intersect.y>0)?0.5:1;
    o.colour.b = (t<0.5)?0:1;
    o.colour.a = 1;
    //calculate uv based on intersect.yz values
    float2 uv = float2(1-intersect.z, 0.5f-intersect.y);
    //to make direct3D word readable on innerL and outerR faces otherwise direct3D is D3tcerid
    if ((intersect.x<0)&&(DU<0)) uv.r = intersect.z+0.65f;//inner right
    if ((intersect.x>0)&&(DU>0)) uv.r = intersect.z+0.65f;//outer left
    //txDiffuse is the Direct3D texture material in slot 0
    o.colour*=dot(normal, LDir)*txDiffuse.Sample(sLinear,uv,0);
    o.depth.r = eye_to_nonlinear_depth(i.Depth * (1.0f - t));
    return o;
}
Source Link
philB
  • 333
  • 2
  • 11
Loading