I have a problem that I cant manage to figure out. I just added a point light to my project and it makes the textures go completely black. I have no idea why.
I think that it might be either the normal that is not updating correctly or it might be calculation of s.x, s.y and s.z.
I would be very happy if someone had time to take a look at it and help me. Thanks.
So. Here is my pixel shader :
Texture2D txDiffuse : register(t0);
SamplerState sampState;
cbuffer PointLight : register(b0)
{
float3 Pos;
float diff;
float amb;
float spec;
float range;
float intensity;
};
struct VS_IN
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Norm : NORMAL;
float4 Pos2 : POSITION;
};
float4 PS_main(VS_IN input) : SV_Target
{
float3 s = txDiffuse.Sample(sampState, input.Tex).xyz;
float3 lightPos = Pos;
float3 lightVector = lightPos - input.Pos2;
lightVector = normalize(lightVector);
float nDotL = dot(lightVector, input.Norm);
float diff1 = 0.8;
float amb1 = 0.1;
s.x = (s.x * diff * nDotL + s.x * amb);
s.y = (s.y * diff * nDotL + s.y * amb);
s.z = (s.z * diff * nDotL + s.z * amb);
return float4(s, 0.0);
};
Geometry shader :
cbuffer worldMatrix : register(b0)
{
matrix world;
}
cbuffer viewMatrix : register(b1)
{
matrix view;
}
cbuffer projectionMatrix : register(b2)
{
matrix projection;
}
struct VS_IN
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
};
struct VS_OUT
{
float4 Pos : SV_POSITION;
float2 Tex : TEXCOORD;
float4 Norm : NORMAL;
float4 Pos2 : POSITION;
};
[maxvertexcount(6)]
void main(triangle VS_IN input[3] : SV_POSITION, inout TriangleStream< VS_OUT > output2)
{
matrix wvp = mul(projection, mul(world, view));
matrix worldView = mul(world, view);
float4 normal = float4(cross(input[1].Pos - input[0].Pos, input[2].Pos - input[0].Pos), 0.0f);
normal = normalize(normal);
float4 rotNorm = mul(worldView, normal);
rotNorm = normalize(rotNorm);
VS_OUT output[3];
for (uint i = 0; i < 3; i++)
{
output[i].Pos = input[i].Pos;
output[i].Pos = mul(wvp, input[i].Pos);
output[i].Tex = input[i].Tex;
output[i].Norm = rotNorm;
output[i].Pos2 = mul(worldView, output[i].Pos);
output2.Append(output[i]);
}
output2.RestartStrip();
VS_OUT outputcopy[3];
for (uint i = 0; i < 3; i++)
{
outputcopy[i].Pos = input[i].Pos + (normal);
outputcopy[i].Pos = mul(wvp, outputcopy[i].Pos);
outputcopy[i].Tex = input[i].Tex;
outputcopy[i].Norm = rotNorm;
outputcopy[i].Pos2 = mul(worldView, outputcopy[i].Pos);
output2.Append(outputcopy[i]);
}
output2.RestartStrip();
}
Code to initializing the point light:
struct PointLight
{
Vector3 Pos;
float diff;
float amb;
float spec;
float range;
float intensity;
};
PointLight* pointLight = nullptr;
PointLight PL =
{
Vector3(0.0f, 0.0f, -3.0f),
0.8f,
0.2f,
0.0f,
100.0f,
1.0f
};
pointLight = &PL;
D3D11_BUFFER_DESC lightBufferDesc;
memset(&lightBufferDesc, 0, sizeof(lightBufferDesc));
lightBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
lightBufferDesc.Usage = D3D11_USAGE_DEFAULT;
lightBufferDesc.StructureByteStride = 0;
lightBufferDesc.MiscFlags = 0;
lightBufferDesc.ByteWidth = sizeof(PointLight);
D3D11_SUBRESOURCE_DATA pointLightData;
memset(&pointLightData, 0, sizeof(pointLightData));
pointLightData.pSysMem = &PL;
gDevice->CreateBuffer(&lightBufferDesc, &pointLightData, &lightBuffer);
and in render() i run
gDeviceContext->PSSetConstantBuffers(0, 1, &lightBuffer);
Texture will be black if s.x, s.y, s.z equal to zero.
s.x = (s.x * diff * nDotL + s.x * amb);
s.y = (s.y * diff * nDotL + s.y * amb);
s.z = (s.z * diff * nDotL + s.z * amb);
Try to change diff and amb with a non-zero constant so that you can be sure that you set contant buffer correctly or not. If after you change them, it's still black then it must be nDotL and/or sampled texture that is zero. Then try with non-zero constant for texture sample. If they're still causing texture to look black then your light vector calculation is the culprit.
Related
(This Image is What I want to implement)
I am attempting Post Processing using Compute Shader to implement Light Shaft for multiple Spot Lights in the DX12 framework.
The first thing I tried was the method at the following link:https://gitlab.com/tomasoh/100_procent_more_volume/-/blob/master/shaders/volumetric.frag
It's a very complicated and hard-to-understand kind of shader, but it's basically built on the premise of using multiple lights, so it's a kind of example for the purpose.
However, since the game I'm making has 32 light source limitations, considering that excessive amount of Frame Drop will occur in the part of calculating Visibility by making Shadow Map for all light sources, I decided to implement Visibility as 1.0 Constant and did not get the desired result. (Of course it's a result.)
Down below is how I did this thing:
#include "lighting.hlsl"
Texture2D<float4> inputTexture : register(t0);
Texture2D<float> depthTexture : register(t1);
RWTexture2D<float4> outputTexture : register(u0);
#define PI 3.141592653589793238f
cbuffer VolumetricCB : register(b1)
{
float absorptionTau : packoffset(c0);
float3 absorptionColor : packoffset(c0.y);
int scatteringSamples : packoffset(c1.x);
float scatteringTau : packoffset(c1.y);
float scatteringZFar : packoffset(c1.z);
float3 scatteringColor : packoffset(c2);
matrix gInvProj : packoffset(c3);
matrix gInvView : packoffset(c7);
float3 gCameraPos : packoffset(c11);
Light gLights[NUM_LIGHTS] : packoffset(c12);
}
float random(float2 co)
{
return frac(sin(dot(co.xy, float2(12.9898, 78.233))) * 43758.5453123);
}
float3 PixelWorldPos(float depthValue, int2 pixel)
{
uint width, height;
inputTexture.GetDimensions(width, height);
float2 fPixel = float2(pixel.x, pixel.y);
float x = (fPixel.x / width * 2) - 1;
float y = (fPixel.y / height * (-2)) + 1;
float z = depthValue;
float4 ndcCoords = float4(x, y, z, 1.0f);
float4 p = mul(ndcCoords, gInvProj);
p /= p.w;
float4 worldCoords = mul(p, gInvView);
return worldCoords.xyz;
}
float3 absorptionTransmittance(float dist)
{
return absorptionColor * exp(-dist * (absorptionTau + scatteringTau));
}
float phaseFunction(float3 inDir, float3 outDir)
{
float cosAngle = dot(inDir, outDir) / (length(inDir) * length(outDir));
float x = (1.0 + cosAngle) / 2.0;
float x2 = x * x;
float x4 = x2 * x2;
float x8 = x4 * x4;
float x16 = x8 * x8;
float x32 = x16 * x16;
float nom = 0.5 + 16.5 * x32;
float factor = 1.0 / (4.0 * PI);
return nom * factor;
}
float3 volumetricScattering(float3 worldPosition, Light light)
{
float3 result = float3(0.0, 0.0, 0.0);
float3 camToFrag = worldPosition - gCameraPos;
if (length(camToFrag) > scatteringZFar)
{
camToFrag = normalize(camToFrag) * scatteringZFar;
}
float3 deltaStep = camToFrag / (scatteringSamples + 1);
float3 fragToCamNorm = normalize(gCameraPos - worldPosition);
float3 x = gCameraPos;
float rand = random(worldPosition.xy + worldPosition.z);
x += (deltaStep * rand);
for (int i = 0; i < scatteringSamples; ++i)
{
float visibility = 1.0;
float3 lightToX = x - light.Position;
float lightDist = length(lightToX);
float omega = 4 * PI * lightDist * lightDist;
float3 Lin = absorptionTransmittance(lightDist) * visibility * light.Diffuse * light.SpotPower / omega;
float3 Li = Lin * scatteringTau * scatteringColor * phaseFunction(normalize(lightToX), fragToCamNorm);
result += Li * absorptionTransmittance(distance(x, gCameraPos)) * length(deltaStep);
x += deltaStep;
}
return result;
}
[numthreads(32, 32, 1)]
void CS(uint3 dispatchID : SV_DispatchThreadID)
{
int2 pixel = int2(dispatchID.x, dispatchID.y);
float4 volumetricColor = float4(0.0, 0.0, 0.0, 1.0);
float depthValue = depthTexture[pixel].r;
float3 worldPosition = PixelWorldPos(depthValue, pixel);
float fragCamDist = distance(worldPosition, gCameraPos);
for (int i = 0; i < NUM_LIGHTS; ++i)
{
if (gLights[i].Type == SPOT_LIGHT && gLights[i].FalloffEnd > length(gLights[i].Position - worldPosition))
volumetricColor += float4(volumetricScattering(worldPosition, gLights[i]), 0.0);
}
outputTexture[pixel] = volumetricColor + inputTexture[pixel];
}
(AbsorptionTau = -0.061f, ScatteringTau = 0.059f)
All these Codes for that Tiny Spot...
The second method was shown in Chapter 13 of GPU GEM3.
It was a method of drawing only Light Source on a separate Render Target, processing the Render Target using Post Processing Shder to create light scattering, and then merging it with a back buffer. (At least that's how I understand it.)
However, this method was designed only for one very strong light, and to fix it, I modified the code as below, but it didn't work well.
[numthreads(32, 32, 1)]
void CS(uint3 dispatchID : SV_DispatchThreadID)
{
uint2 pixel = dispatchID.xy;
uint width, height;
inputTexture.GetDimensions(width, height);
float4 result = inputTexture[pixel];
for (int i = 0; i < NUM_LIGHTS; ++i)
{
if(gLights[i].Type == SPOT_LIGHT)
{
float2 texCoord = float2(pixel.x / width, pixel.y / height);
float2 deltaTexCoord = (texCoord - mul(mul(float4(gLights[i].Position, 1.0f), gView), gProj).xy);
deltaTexCoord *= 1.0f / NUM_SAMPLES * Density;
float3 color = inputTexture[pixel].rgb;
float illuminationDecay = 1.0f;
for (int j = 0; j < NUM_SAMPLES; j++)
{
texCoord -= deltaTexCoord;
uint2 modifiedPixel = uint2(texCoord.x * width, texCoord.y * height);
float3 sample = inputTexture[modifiedPixel].rgb;
sample *= illuminationDecay * Weight;
color += sample;
illuminationDecay *= Decay;
}
result += float4(color * Exposure, 1);
}
}
outputTexture[pixel] = result;
}
this just 'Blur' these light source map, and surely it's not what I wanted.
Is there a similar kind of example to the implementation that I want, or is there a simpler way to do this? I've spent a week on this issue, but I haven't achieved much.
edit :
I did it! but there's some error about direction of light volume.
[numthreads(32, 32, 1)]
void CS(uint3 dispatchID : SV_DispatchThreadID)
{
float4 result = { 0.0f, 0.0f, 0.0f, 0.0f };
uint2 pixel = dispatchID.xy;
uint width, height;
inputTexture.GetDimensions(width, height);
float2 texCoord = (float2(pixel) + 0.5f) / float2(width, height);
float depth = depthTexture[pixel].r;
float3 screenPos = GetPositionVS(texCoord, depth);
float3 rayEnd = float3(0.0f, 0.0f, 0.0f);
const uint sampleCount = 16;
const float stepSize = length(screenPos - rayEnd) / sampleCount;
// Perform ray marching to integrate light volume along view ray:
[loop]
for (uint i = 0; i < NUM_LIGHTS; ++i)
{
[branch]
if (gLights[i].Type == SPOT_LIGHT)
{
float3 V = float3(0.0f, 0.0f, 0.0f) - screenPos;
float cameraDistance = length(V);
V /= cameraDistance;
float marchedDistance = 0;
float accumulation = 0;
float3 P = screenPos + V * stepSize * dither(pixel.xy);
for (uint j = 0; j < sampleCount; ++j)
{
float3 L = mul(float4(gLights[i].Position, 1.0f), gView).xyz - P;
const float dist2 = dot(L, L);
const float dist = sqrt(dist2);
L /= dist;
//float3 viewDir = mul(float4(gLights[i].Direction, 1.0f), gView).xyz;
float3 viewDir = gLights[i].Direction;
float SpotFactor = dot(L, normalize(-viewDir));
float spotCutOff = gLights[i].outerCosine;
[branch]
if (SpotFactor > spotCutOff)
{
float attenuation = DoAttenuation(dist, gLights[i].Range);
float conAtt = saturate((SpotFactor - gLights[i].outerCosine) / (gLights[i].innerCosine - gLights[i].outerCosine));
conAtt *= conAtt;
attenuation *= conAtt;
attenuation *= ExponentialFog(cameraDistance - marchedDistance);
accumulation += attenuation;
}
marchedDistance += stepSize;
P = P + V * stepSize;
}
accumulation /= sampleCount;
result += max(0, float4(accumulation * gLights[i].Color * gLights[i].VolumetricStrength, 1));
}
}
outputTexture[pixel] = inputTexture[pixel] + result;
}
this is my compute shader, but when I doesn't multiply view matrix to direction, it goes wrong like this :
as you can see, street lamp's volume direction is good, but vehicle's headlight's volume direction is different from it's spot light direction.
and when I multiply view matrix to direction :
head lights gone wrong AND street lamp goes wrong too.
I still finding where's wrong in my cpu codes, but I haven't find anything.
this might be helpful. here's my shader code about spot lighting.
float CalcAttenuation(float d, float falloffStart, float falloffEnd)
{
return saturate((falloffEnd - d) / (falloffEnd - falloffStart));
}
float3 BlinnPhongModelLighting(float3 lightDiff, float3 lightVec, float3 normal, float3 view, Material mat)
{
const float m = mat.Exponent;
const float f = ((mat.IOR - 1) * (mat.IOR - 1)) / ((mat.IOR + 1) * (mat.IOR + 1));
const float3 fresnel0 = float3(f, f, f);
float3 halfVec = normalize(view + lightVec);
float roughness = (m + 8.0f) * pow(saturate(dot(halfVec, normal)), m) / 8.0f;
float3 fresnel = CalcReflectPercent(fresnel0, halfVec, lightVec);
float3 specular = fresnel * roughness;
specular = specular / (specular + 1.0f);
return (mat.Diffuse.rgb + specular * mat.Specular) * lightDiff;
}
float3 ComputeSpotLight(Light light, Material mat, float3 pos, float3 normal, float3 view)
{
float3 result = float3(0.0f, 0.0f, 0.0f);
bool bCompute = true;
float3 lightVec = light.Position - pos;
float d = length(lightVec);
if (d > light.FalloffEnd)
bCompute = false;
if (bCompute)
{
lightVec /= d;
float ndotl = max(dot(lightVec, normal), 0.0f);
float3 lightDiffuse = light.Diffuse * ndotl;
float att = CalcAttenuation(d, light.FalloffStart, light.FalloffEnd);
lightDiffuse *= att;
float spotFactor = pow(max(dot(-lightVec, light.Direction), 0.0f), light.SpotPower);
lightDiffuse *= spotFactor;
result = BlinnPhongModelLighting(lightDiffuse, lightVec, normal, view, mat);
}
return result;
}
I have a mesh with arbitrary normals and I have calculated them using standard method
Method to calculate the tangents..
void calcTangent(uint32_t idx1, uint32_t idx2, uint32_t idx3)
{
vertex v1 = _vertex[idx1];
vertex v2 = _vertex[idx2];
vertex v3 = _vertex[idx3];
float du1 = v3.Text.x - v1.Text.x;
float dv1 = v3.Text.y - v1.Text.y;
float du2 = v2.Text.x - v1.Text.x;
float dv2 = v2.Text.y - v1.Text.y;
float tx1 = v3.Pos.x - v1.Pos.x;
float ty1 = v3.Pos.y - v1.Pos.z;
float tz1 = v3.Pos.z - v1.Pos.z;
float tx2 = v2.Pos.x - v1.Pos.x;
float ty2 = v2.Pos.y - v1.Pos.z;
float tz2 = v2.Pos.z - v1.Pos.z;
float r = 1.0f / (du1 * dv2 - dv1 * du2);
float e1x = (dv2 * tx1 - dv1 * tx2) * r;
float e1y = (dv2 * ty1 - dv1 * ty2) * r;
float e1z = (dv2 * tz1 - dv1 * tz2) * r;
//Binormals
float e2x = (du1 * tx2 - du2 * tx1) * r;
float e2y = (du1 * ty2 - du2 * ty1) * r;
float e2z = (du1 * tz2 - du2 * tz1) * r;
XMFLOAT3 ot1 = Math::gramSchmidthF({ v1.Norm.x, v1.Norm.y, v1.Norm.z }, { e1x, e1y, e1z });
XMFLOAT3 ot2 = Math::gramSchmidthF({ v2.Norm.x, v2.Norm.y, v2.Norm.z }, { e1x, e1y, e1z });
XMFLOAT3 ot3 = Math::gramSchmidthF({ v3.Norm.x, v3.Norm.y, v3.Norm.z }, { e1x, e1y, e1z });
_vertex[idx1].Tangent = ot1;
_vertex[idx2].Tangent = ot2;
_vertex[idx3].Tangent = ot3;
}
the bitangent will not be passed to the shader, and will be calculated in PS..
vertex shader and pixel shaders..
struct VS_INPUT
{
float4 Position : POSITION;
float3 Normal : NORMAL;
float2 Texture : TEXCOORD;
float3 Tangent : TANGENT;
};
struct PS_INPUT
{
float4 Position : SV_POSITION;
float3 Normal : NORMAL;
float3 Tangent : TANGENT;
float3 Binormal : BINORMAL;
float2 Texture : TEXCOORD0;
float3 ViewDirection : TEXCOORD1;
};
PS_INPUT vertex_shader(VS_INPUT input)
{
PS_INPUT output = (PS_INPUT)0;
input.Position.w = 1.0f;
//transformations
output.Position = mul(input.Position, World);
output.Position = mul(output.Position, View);
output.Position = mul(output.Position, Projection);
//
output.Normal = normalize(mul(float4(input.Normal, 0), World).xyz);
output.Texture = input.Texture;
float3 worldPosition = mul(input.Position, World).xyz;
output.ViewDirection = normalize(CAMERA_POSITION - worldPosition);
//add the tangent and binormal
output.Tangent = normalize(mul(float4(input.Tangent, 0), World).xyz);
output.Binormal = normalize(cross(output.Normal, output.Tangent));
return output;
}
float4 ps(PS_INPUT input) : SV_Target
{
float4 OUT = (float4)0;
//texture normal
float3 sampledNormal = (2 * normalMapTexture.Sample(normalMapSampler, input.Texture).xyz) - 1.0; // Map normal from [0..1] to [-1..1]
//creating matrix
// Tangent
// Binormal
// Normal
float3x3 tbn = float3x3(input.Tangent, input.Binormal, input.Normal);
//convert tangent space to world space
sampledNormal = mul(sampledNormal, tbn); // Transform normal from normal map to world space
float3 viewDirection = normalize(input.ViewDirection);
//texture color
float4 color = colorTexture.Sample(samLinear, input.Texture); //getting the color from texture without normals..
//ambient color
float3 ambient = getVectorColorContribution(AMBIENT_COLOR, color.rgb); //mult AMBIENT_COLOR(.rgb) * AMBIENT_COLOR Intensity (.a) * color
float3 diffuse = (float3)0;
float3 specular = (float3)0;
float3 lightDirection = normalize(-LIGHT_DIR.xyz);
float n_dot_l = dot(sampledNormal, lightDirection);
//calculating the diffuse value
diffuse = saturate(n_dot_l) * LIGHT_COLOR.rgb * LIGHT_COLOR.a;
}
//changing the return types will change the result to basic or specular..
OUT.rgb = diffuse * color;
OUT.a = 1.0f;
return OUT;
}
Here it is the result, only using diffuse, to avoid specular errors..
please anyone knows why is this?
After a lot of digging, in DirectXMesh there is a function to calculate tangents right(ComputeTangentFrame) it saves the result in XMFLOAT4 tangent[3]array , works perfectly, so my problem was calculating tangents. Hope it helps anyone else..
Little Example using it:
uint32_t idx[3];
idx[0] = 0;
idx[1] = 1;
idx[2] = 2;
XMFLOAT3 pos[3];
pos[0] = Pos1;
pos[1] = Pos2;
pos[2] = Pos3;
XMFLOAT3 normals[3];
normals[0] = Normal1;
normals[1] = Normal2;
normals[2] = Normal3;
XMFLOAT2 t[3];
t[0] = TextureCoord1;
t[1] = TextureCoord2;
t[2] = TextureCoord3;
XMFLOAT4 tangent[3];
ComputeTangentFrame(idx,1, pos, normals,t,3, tangent);
I have a obj with normals and I want to use a surface bump map on it.
Can anyone help me how can I calculate the final normal map from the obj normals and the Bump map
my fragment shader is:
fragment float4 fragmentShaderObj(VertexOutObj interpolated [[stage_in]], const device Uniforms& uniforms [[ buffer(1) ]], texture2d_array<float> tex2D [[ texture(0) ]], sampler sampler2D [[ sampler(0) ]]) {
float4x4 mv_Matrix = uniforms.modelMatrix;
// Ambient
Light light = uniforms.light;
if(interpolated.mapB >= 0){
float3 norm = (2.0*tex2D.sample(sampler2D, interpolated.texCoord,interpolated.mapB).rgb-float3(1,1,1));
}
interpolated.normal = normalize(interpolated.normal);
float4 ambientColor = float4(light.color *interpolated.ka, 1);
//Diffuse
float3 normal_inv = float3(0,0,0)-interpolated.normal;
//float diffuseFactor1 = max(0.0,dot(interpolated.normal, light.direction));
float diffuseFactor1 = max(max(0.0,dot(interpolated.normal, light.direction)),dot(normal_inv, light.direction));
float4 diffuseColor = float4(light.color * diffuseFactor1*interpolated.kd ,1.0);
//Specular
float3 eye = normalize(interpolated.fragmentPosition);
float3 reflection = reflect(light.direction, interpolated.normal);
float specularFactor = max(0.0, dot(reflection, eye));
float4 specularColor = float4(light.color * interpolated.ns * specularFactor * interpolated.ks,1.0);
float4 color = tex2D.sample(sampler2D, interpolated.texCoord,interpolated.mapKd);
if(color.a < 0.1)
discard_fragment();
color.rgb = color.rgb * (ambientColor + diffuseColor + specularColor).rgb;
return color;
}
now how can I add that norm with the interpolated.normal. it can't be straight forward addition.
I've recently implemented shadows on my terrain project, using PCF filtering, however, the shadows on the slopes of the terrain appear incorrect, as you can see below:
How can I remove the artifacts caused on the slopes of the terrain? A quick search suggests implementing a slope based bias, but how would I calculate it?
Here is my pixel shader:
Texture2D shadowMap : register(t0);
SamplerComparisonState SampleTypeCmp : register(s0);
cbuffer SPerLightCB : register(b0)
{
float4 ambientColour;
float4 diffuseColour;
};
cbuffer SPerLightPosCB : register(b1)
{
float3 lightPos;
float padding;
};
struct PixelIn
{
float4 Pos : SV_POSITION;
float4 WPos : TEXCOORD0;
float4 LPos : TEXCOORD1;
float3 Normal : NORMAL;
};
float2 texOffset(int u, int v)
{
return float2(u * 1.0f / 1024.0f, v * 1.0f / 1024.0f);
}
float4 main(PixelIn pin) : SV_Target
{
//re-homogenize position after interpolation
pin.LPos.xyz /= pin.LPos.w;
//if position is not visible to the light - dont illuminate it
//results in hard light frustum
if (pin.LPos.x < -1.0f || pin.LPos.x > 1.0f ||
pin.LPos.y < -1.0f || pin.LPos.y > 1.0f ||
pin.LPos.z < 0.0f || pin.LPos.z > 1.0f)
{
return ambientColour;
}
//transform clip space coords to texture space coords (-1:1 to 0:1)
pin.LPos.x = pin.LPos.x / 2 + 0.5;
pin.LPos.y = pin.LPos.y / -2 + 0.5;
pin.LPos.z -= 0.001f; //apply bias
//PCF Sampling
float sum = 0.0f;
float x, y;
//perform PCF filtering
for (y = -1.5; y <= 1.5; y += 1.0)
{
for (x = -1.5; x <= 1.5; x += 1.0)
{
sum += shadowMap.SampleCmpLevelZero(SampleTypeCmp, pin.LPos.xy + texOffset(x, y), pin.LPos.z);
}
}
float shadowFactor = sum / 16.0;
//calculate ilumination
float3 L = normalize(lightPos - pin.WPos.xyz);
float ndotl = dot(normalize(pin.Normal), L);
return ambientColour + shadowFactor * diffuseColour * ndotl;
}
I'm trying to render my fluid simulator with liquid effect,
here is my render result:
but I want to get this result
here is my geometry and pixel shader
[maxvertexcount(4)]
void mainGS(point GSPS_INPUT gInput[1],inout TriangleStream<GSPS_OUTPUT> TriStream)
{
float size = 0.065;
matrix mv = View;
float3 right = normalize(float3(mv._11,mv._21,mv._31));
float3 up = normalize(float3(mv._12,mv._22,mv._32));
//
float3 posEye = mul( float4(gInput[0].Pos.xyz, 1.0),world).xyz;
//
float halfWidth = size/length(posEye);
float halfHeight = size/length(posEye);
//
float4 v[4];
v[0] = float4(gInput[0].Pos + halfWidth*right - halfHeight*up, 1.0f);
v[1] = float4(gInput[0].Pos + halfWidth*right + halfHeight*up, 1.0f);
v[2] = float4(gInput[0].Pos - halfWidth*right - halfHeight*up, 1.0f);
v[3] = float4(gInput[0].Pos - halfWidth*right + halfHeight*up, 1.0f);
//
//
GSPS_OUTPUT output;
[unroll]
for(int i=0; i<4; ++i)
{
//
output.Pos = mul(v[i], View);
output.PosW = (output.Pos.xyz);
output.Pos = mul(output.Pos, Projection);
output.Tex = gQuadTexC[i];
TriStream.Append(output);
}
TriStream.RestartStrip();
}
//pixel shader
float4 PS(GSPS_OUTPUT input) : SV_TARGET
{
float3 N;
N.xy = input.Tex*float2(2.0f,-2.0f) + float2(-1.0f,1.0f);
float mag = dot(N.xy, N.xy);
if (mag > 1.0)
{
discard;
}
N.z = sqrt(1.0f-mag);
N = N * 0.5 + 0.5;
float4 pixelPos = float4(input.PosW + N*(1/32), 1.0);
float4 clipSpacePos = mul(pixelPos, Projection);
float depthval = (clipSpacePos.z / clipSpacePos.w);
I found here this, but it's not fully explanation
Link