A Quick Note
This question assumes you have some knowledge about the overall rendering process and do not need clarification on rendering objects with HLSL
and a DeviceContext
. I use the SharpDX
libraries to write my code in C#
but I can read C++
and convert it if needed.
Overview
I am currently trying to create a prefab for a point light in my engine at work. I currently have a working directional light and can adapt from that if needed. Originally this post included some code from a pixel shader that I found on StackOverflow, but @DMGregory pointed out issues with it. I also attempted to follow a pixel shader supplied in the book Real-Time 3D Rendering with DirectX and HLSL (chapter 7 page 117); however, the HLSL in that seems to be a bit outdated since I can't use the following functions:
lit
get_vector_color_contribution
get_scalar_color_contribution
These seem to be no longer supported with ps_5_0
(the HLSL
won't compile) and I can't find any documentation that provides updated equivalents. The exact error message during compilation is:
error X3004: undeclared identifier 'get_vector_color_contribution`.
This same message is presented with all three functions.
When I attempted the pixel shader found on StackOverflow, it didn't do what I expected. I eventually discovered that this is because it wasn't sampling textures. Correcting that is simple enough, but this would have to be applied per object and makes it difficult for multiple point lights. This doesn't really fit my idea of simplicity.
My Idea
I would prefer to create a point light shader that is applied to all objects capable of being illuminated in a single pass; however, I fear this isn't possible or would be incredibly difficult to achieve.
Since it is a lot of code to show the entire process, I will just include a couple relevant samples and hopefully that will help shed some light on what I currently do when rendering objects:
public class SceneObject {
public Vector3 Position { get; set; }
public PixelShader PixelShader { get; set; }
public virtual void Render() { }
}
public class PointLight : SceneObject {
public float Radius { get; set; }
public float Intensity { get; set; }
public Color Diffuse { get; set; }
public Color Ambient { get; set; }
public Color Specular { get; set; }
}
public class Scene {
private void ChangeShader(SceneObject obj, bool setToCurrent) {
if (setToCurrent)
currentPixelShader = context3D.PixelShader.Get();
if (currentPixelShader.DebugName != obj.PixelShader.DebugName)
context3D.PixelShader.Set(obj.PixelShader);
}
public void Render(SceneObject obj, bool renderChildren = true) {
if (!obj.Enabled)
return;
if (obj is PointLight)
SetPointLightBuffer((PointLight)obj);
if (obj.PixelShader != null)
ChangeShader(obj, false);
SetObjectBuffer(obj);
if (obj.HasTexture)
UpdateMaterialBuffer(true);
obj.Render();
if (obj.HasTexture)
UpdateMaterialBuffer(false);
if (renderChildren)
foreach (SceneObject child in obj.Children)
Render(child);
}
ChangeShader(obj, true);
}
There are things missing from the code I've supplied above, but this is intentional as it is a lot of code. Each object renders itself in the appropriate way. The Scene
class manages the DeviceContext
and other important things such as the constant buffers used by the shaders, this allows greater flexibility for future developers instead of having to learn all of the underlying DirectX
code, they can focus on creating objects with prefabs instead.
Goal
The overall goal is to achieve the most simplistic implementation of a point light that I can get, to where any object that is capable of being illuminated is illuminated when in range of the light. I believe this is going to be a post process pixel shader, but I could be wrong.
Question
What is the step by step (proper) process for rendering a point light object into a scene?
Note
I don't really need code samples to answer this question unless the supplied shader is incorrect. I can figure the code out, so long as you're detailed enough about the process in your answer.
get_vector_color_contribution
as defined here in your shader code? It doesn't look like it uses anything unusual that would be unsupported, just a little multiplication. \$\endgroup\$get_vector_color_contribution
anywhere in the shader code you've tried to compile. It's not a built-in function, just a regular user-defined function. Have you tried declaring the function like the error message tells you to? \$\endgroup\$