• 9
• 10
• 9
• 10
• 10
• ### Similar Content

• I am developing a mini golf game in Scenekit. I have applied dynamic physics body to the ball and static physics body to the grass surface and the brick walls show in this image.
Issue:
When I apply the force to the ball, the ball’s linear and angular speeds change as shown in the graphs.  The ball’s speeds don’t reduce to zero (so that the ball can stop) but remains constant after certain value.
Ball linear speed graph
Ball angular speed graph
Analysis Tests:
When I increase the values to both the rolling friction and the friction, the ball speed is reduced quickly but remains constant after certain value (similar to the above graphs). When I increase the values of the linear damping and the angular damping, the ball speed behavior is same as the point #1. When I set the gravity value to -9.8 m/s2, the ball’s linear speed remains constant after 0.1 m/s. If I reduce the gravity value to -5 m/s2, the ball’s linear speed remains constant after 0.05 m/s. The friction, linear friction, linear damping and angular damping are same throughout the motion of the ball.
There is 1 millimeter overlapping between the ball and the surface of the golf course.
Questions:
From the analysis test #3, I think the gravity is causing the constant ball speed issue. Is my assumption correct? If yes, how can I fix the issue? I can’t remove the gravity field as without the gravity field the ball will not roll along the grass and it will slide. Why the friction and the damping properties are not affecting the ball speed after certain value?
Are there any other physics properties can cause such issue?
From the analysis test #5, are there any chances that the ball is receiving upward push to correct the position of the ball?
Solutions:
If I increase the physics timestep from 60 FPS to 200 FPS, the issue is resolved. I am not able to understand how this change can fix this issue? After reducing the gravity value to -1 m/s2 and physics simulation speed to 4 (4 times fast physics simulation), the issue is fixed. Again, I am not able to understand how this change fix the issue? I would appreciate any suggestions and thoughts on this topic. Thank you.
• By stale
I'm continuing to learn more about terrain rendering, and so far I've managed to load in a heightmap and render it as a tessellated wireframe (following Frank Luna's DX11 book). However, I'm getting some really weird behavior where a large section of the wireframe is being rendered with a yellow color, even though my pixel shader is hard coded to output white.

The parts of the mesh that are discolored changes as well, as pictured below (mesh is being clipped by far plane).

Here is my pixel shader. As mentioned, I simply hard code it to output white:
float PS(DOUT pin) : SV_Target { return float4(1.0f, 1.0f, 1.0f, 1.0f); } I'm completely lost on what could be causing this, so any help in the right direction would be greatly appreciated. If I can help by providing more information please let me know.

# DX11 Why won't my falloff work for this dot product based spotlight?

## Recommended Posts

I made a spotlight that

1. Projects 3d models onto a render target from each light POV to simulate shadows

2. Cuts a circle out of the square of light that has been projected onto the render target

as a result of the light frustum, then only lights up the pixels inside that circle

(except the shadowed parts of course), so you dont see the square edges of the projected frustum.

After doing an if check to see if the dot product of light direction and light to vertex vector is greater than .95

to get my initial cutoff, I then multiply the light intensity value inside the resulting circle by the same dot product value,

which should range between .95 and 1.0.

This should give the light inside that circle a falloff from 100% lit to 0% lit toward the edge of the circle. However,

there is no falloff. It's just all equally lit inside the circle. Why on earth, I have no idea. If someone could take a gander

and let me know, please help, thank you so much.

float CalculateSpotLightIntensity(
float3 LightPos_VertexSpace,
float3 LightDirection_WS,
float3 SurfaceNormal_WS)
{
//float3 lightToVertex = normalize(SurfacePosition - LightPos_VertexSpace);
float3 lightToVertex_WS = -LightPos_VertexSpace;

float dotProduct = saturate(dot(normalize(lightToVertex_WS), normalize(LightDirection_WS)));

// METALLIC EFFECT (deactivate for now)
float metalEffect = saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace)));
if(dotProduct > .95 /*&& metalEffect > .55*/)
{
return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace)));
//return saturate(dot(SurfaceNormal_WS, normalize(LightPos_VertexSpace))) * dotProduct;
//return dotProduct;
}
else
{
return 0;
}
}

float4 LightPixelShader(PixelInputType input) : SV_TARGET
{
float2 projectTexCoord;
float depthValue;
float lightDepthValue;
float4 textureColor;

// Set the bias value for fixing the floating point precision issues.
float bias = 0.001f;

// Set the default output color to the ambient light value for all pixels.
float4 lightColor = cb_ambientColor;

/////////////////// NORMAL MAPPING //////////////////
float4 bumpMap = shaderTextures[4].Sample(SampleType, input.tex);

// Expand the range of the normal value from (0, +1) to (-1, +1).
bumpMap = (bumpMap * 2.0f) - 1.0f;

// Change the COORDINATE BASIS of the normal into the space represented by basis vectors tangent, binormal, and normal!
float3 bumpNormal = normalize((bumpMap.x * input.tangent) + (bumpMap.y * input.binormal) + (bumpMap.z * input.normal));

//////////////// LIGHT LOOP ////////////////
for(int i = 0; i < NUM_LIGHTS; ++i)
{
// Calculate the projected texture coordinates.
projectTexCoord.x =  input.vertex_ProjLightSpace[i].x / input.vertex_ProjLightSpace[i].w / 2.0f + 0.5f;
projectTexCoord.y = -input.vertex_ProjLightSpace[i].y / input.vertex_ProjLightSpace[i].w / 2.0f + 0.5f;

if((saturate(projectTexCoord.x) == projectTexCoord.x) && (saturate(projectTexCoord.y) == projectTexCoord.y))
{
// Sample the shadow map depth value from the depth texture using the sampler at the projected texture coordinate location.
depthValue = shaderTextures[6 + i].Sample(SampleTypeClamp, projectTexCoord).r;

// Calculate the depth of the light.
lightDepthValue = input.vertex_ProjLightSpace[i].z / input.vertex_ProjLightSpace[i].w;

// Subtract the bias from the lightDepthValue.
lightDepthValue = lightDepthValue - bias;

float lightVisibility = shaderTextures[6 + i].SampleCmp(SampleTypeComp, projectTexCoord, lightDepthValue );

// Compare the depth of the shadow map value and the depth of the light to determine whether to shadow or to light this pixel.
// If the light is in front of the object then light the pixel, if not then shadow this pixel since an object (occluder) is casting a shadow on it.
if(lightDepthValue < depthValue)
{
// Calculate the amount of light on this pixel.
float lightIntensity = saturate(dot(bumpNormal, normalize(input.lightPos_LS[i])));

if(lightIntensity > 0.0f)
{
// Determine the final diffuse color based on the diffuse color and the amount of light intensity.
float spotLightIntensity = CalculateSpotLightIntensity(
input.lightPos_LS[i], // NOTE - this is NOT NORMALIZED!!!
cb_lights[i].lightDirection,
bumpNormal/*input.normal*/);

lightColor += cb_lights[i].diffuseColor*spotLightIntensity* .18f; // spotlight
//lightColor += cb_lights.diffuseColor*lightIntensity* .2f; // square light
}
}
}
}

// Saturate the final light color.
lightColor = saturate(lightColor);
// lightColor = saturate( CalculateNormalMapIntensity(input, lightColor, cb_lights[0].lightDirection));

// TEXTURE ANIMATION -  Sample pixel color from texture at this texture coordinate location.
input.tex.x += textureTranslation;

// BLENDING
float4 color1 = shaderTextures[0].Sample(SampleTypeWrap, input.tex);
float4 color2 = shaderTextures[1].Sample(SampleTypeWrap, input.tex);
float4 alphaValue = shaderTextures[3].Sample(SampleTypeWrap, input.tex);
textureColor = saturate((alphaValue * color1) + ((1.0f - alphaValue) * color2));

// Combine the light and texture color.
float4 finalColor = lightColor * textureColor;

/////// TRANSPARENCY /////////
//finalColor.a = 0.2f;

return finalColor;
}

Light_vs.hlsl

Light_ps.hlsl

##### Share on other sites

Hi,

Those calculations seem correct at first glance. But something is missing. With only a dot(normal, lightDirection) you won't get a smooth spotlight attenuation for the cutoff. You also want to calculate a spotlight attenuation factor. My code:

float3 L = light.worldPosition - surfaceWorldPosition; // light-vector
float dist = length(L); // distance from surface to light

float SpotFactor = dot(L, light.directionWorldSpace); // spotlight lookAt vector
float spotCutOff = light.coneAngleCos; // cos(spotLightFieldOfView)

// ...

// pointlight-like attenuation factor
float att = (light.energy * (light.range / (light.range + 1 + dist)));
float attenuation = (att * (light.range - dist) / light.range);

// spotlight-specific attenuation factor:
// this is resposible for smooth gradient of spotlight cutoff circle
attenuation *= saturate((1.0 - (1.0 - SpotFactor) * 1.0 / (1.0 - spotCutOff)));

diffuse *= attenuation;
specular *= attenuation;

In the above code, spotCutoff would be your hardcoded 0.95 value, SpotFactor is your "dotProduct" valriable. Good luck!

##### Share on other sites
18 hours ago, turanszkij said:

Hi,

Those calculations seem correct at first glance. But something is missing. With only a dot(normal, lightDirection) you won't get a smooth spotlight attenuation for the cutoff. You also want to calculate a spotlight attenuation factor. My code:


float3 L = light.worldPosition - surfaceWorldPosition; // light-vector
float dist = length(L); // distance from surface to light

float SpotFactor = dot(L, light.directionWorldSpace); // spotlight lookAt vector
float spotCutOff = light.coneAngleCos; // cos(spotLightFieldOfView)

// ...

// pointlight-like attenuation factor
float att = (light.energy * (light.range / (light.range + 1 + dist)));
float attenuation = (att * (light.range - dist) / light.range);

// spotlight-specific attenuation factor:
// this is resposible for smooth gradient of spotlight cutoff circle
attenuation *= saturate((1.0 - (1.0 - SpotFactor) * 1.0 / (1.0 - spotCutOff)));

diffuse *= attenuation;
specular *= attenuation;

In the above code, spotCutoff would be your hardcoded 0.95 value, SpotFactor is your "dotProduct" valriable. Good luck!

Thanks, will try it out!

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account