-
Notifications
You must be signed in to change notification settings - Fork 36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ShaderDescription entryPoint different to "main" #4
Comments
@pzgulyas EDIT: Oops, I see now that you're describing a different issue than I initially thought. There is a parallel issue in the Vulkan backend that prevents it from working with different entry point names at the moment. Could you provide more info about how you are producing the SPIR-V that causes this issue? |
I have my glsl sources, and do a ReadAllBytes on them. So it is the same way how you describe it here in the README.md Usage section. EDIT: Oh, sorry, not exactly. I have the glsl sources in the files, not the compiled bytecode. Hmmm, maybe that was the problem? But it still works with "main" and ReadAllBytes. EDIT2: Just to add some code how I thought: byte[] vertexShader = File.ReadAllBytes("sky.vert");
byte[] fragmentShader = File.ReadAllBytes("sky.frag");
Shader[] SkyShader = factory.CreateFromSpirv(
new ShaderDescription(ShaderStages.Vertex, vertexShader, "main"),
new ShaderDescription(ShaderStages.Fragment, fragmentShader, "main"));
Shader[] CloudsShader = factory.CreateFromSpirv(
new ShaderDescription(ShaderStages.Vertex, vertexShader, "main"),
new ShaderDescription(ShaderStages.Fragment, fragmentShader, "clouds")); or something similar. |
As far as I know, there's no way to use an entrypoint other than "main()" in GLSL. So unless I'm missing something, you'll need to specify "main" in the ShaderDescription since that's what the code will have. This isn't true for HLSL (it lets you specify any function name you want), so that's what I initially thought you were referring to. Could you provide a sample GLSL shader that would exhibit this problem? |
Below is a sample of my technical experiment. Not that this particular one could not be easily exploded into multiple files, but I also have some more difficult ones. :-) Sky.frag#version 450
#extension GL_ARB_separate_shader_objects : enable
#extension GL_ARB_shading_language_420pack : enable
layout(location = 0) in vec3 InNormal;
layout(location = 1) in vec2 InTexCoords;
layout(set = 2, binding = 0) uniform PerBatchFragment {
vec4 lightVector; // Direction vector to sun, w = 1/length of vector
vec4 overcast; // x = alpha, y = contrast, z = brightness, w = !Overcast.y && !Overcast.z
vec3 skyColor;
float time; // Used for moving textures across the sky
vec3 fogColor;
float cloudColor;
vec4 fog;
vec2 windDisplacement;
vec2 moonColor;
vec2 moonTexCoord;
vec2 padding;
};
layout(set = 1, binding = 0) uniform texture2D PrimaryTexture;
layout(set = 1, binding = 1) uniform texture2D SecondaryTexture;
layout(set = 1, binding = 2) uniform sampler SkySampler;
layout(location = 0) out vec4 OutColor;
// This function adjusts brightness, saturation and contrast
// By Romain Dura aka Romz
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con)
{
// Increase or decrease theese values to adjust r, g and b color channels separately
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
float intensityf = dot(brtColor, LumCoeff);
vec3 intensity = vec3(intensityf, intensityf, intensityf);
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
void main()
{
// Get the color information for the current pixel
OutColor = texture(sampler2D(PrimaryTexture, SkySampler), InTexCoords);
vec2 texCoords = vec2((1.0 - InTexCoords.x) + time, InTexCoords.y);
vec4 starColor = texture(sampler2D(SecondaryTexture, SkySampler), texCoords);
// Adjust sky color brightness for time of day
OutColor *= skyColor.x;
// Stars
OutColor = mix(starColor, OutColor, skyColor.y);
// Fogging
OutColor.rgb = mix(OutColor.rgb, fogColor.rgb, clamp((1 - InNormal.y) * fog.x, 0, 1));
// Calculate angular difference between LightVector and vertex normal, radians
float dotproduct = dot(lightVector.xyz, InNormal);
float angleRcp = 1 / acos(dotproduct * lightVector.w / length(InNormal));
// Sun glow
// Coefficients selected by the author to achieve the desired appearance - fot limits the effect
OutColor += angleRcp * fog.y;
// increase orange at sunset - fog limits the effect
if (lightVector.x < 0)
{
OutColor.r += skyColor.z * angleRcp * fog.z;
OutColor.g += OutColor.r * fog.w;
}
// Keep alpha opaque
OutColor.a = 1.0;
}
void moon()
{
// Get the color information for the current pixel
vec2 texCoords = vec2(moonTexCoord.x + InTexCoords.x * 0.5, moonTexCoord.y + InTexCoords.y * 0.25);
OutColor = texture(sampler2D(PrimaryTexture, SkySampler), texCoords);
vec4 moonMask = texture(sampler2D(SecondaryTexture, SkySampler), InTexCoords);
// Fade moon during daylight
OutColor.a *= moonColor.x;
// Fogging
OutColor.rgb = mix(OutColor.rgb, fogColor.rgb, clamp((1 - InNormal.y) * fog.x, 0, 1));
// Mask stars behind dark side (mask fades in)
OutColor.a += moonMask.r * moonColor.y;
}
void clouds()
{
// Get the color information for the current pixel
// Cloud map is tiled. Tiling factor: 4
// Move cloud map to suit wind conditions
vec2 texCoords = vec2(InTexCoords.x * 4 + windDisplacement.x, InTexCoords.y * 4 + windDisplacement.y);
OutColor = texture(sampler2D(PrimaryTexture, SkySampler), texCoords);
float alpha = OutColor.a;
// Fogging
OutColor.rgb = mix(OutColor.rgb, fogColor.rgb, clamp((1 - InNormal.y) * fog.x, 0, 1));
// Adjust amount of overcast by adjusting alpha
if (overcast.w != 0)
{
alpha += overcast.x;
// Reduce contrast and brightness
vec3 color = ContrastSaturationBrightness(OutColor.xyz, 1.0, overcast.z, overcast.y); // Brightness and saturation are really need to be exchanged?
OutColor = vec4(color, alpha);
}
else
{
alpha *= overcast.x;
}
// Adjust cloud color brightness for time of day
OutColor *= cloudColor;
OutColor.a = alpha;
} var shaderBytes = File.ReadAllText(shaderFile)
.Replace("void main()", "void origmain()")
.Replace($"void {shaderEntry}()", "void main()")
.Select(c => (byte)c).ToArray(); |
Okay, I'm able to compile that shader using the following glslangvalidator command:
The confusing part is this I expect that I will fix this when I finish up the HLSL support, which will hopefully be soon. HLSL has better support for defining multiple shaders in a single file, so being able to control which entry point is used will be more valuable there, anyways. |
When I try to load a shader with an entryPoint of the ShaderDescription set to something else than "main", I get a null reference exception in CreateFromSpirv, no matter if that function actually exists in shader or not.
(Since includes are quite mystical to mee, how they are supposed to work in glsl and also here, my idea was to just shovel everything into a single file, and generating different actual shaders by setting different entry points, but it doesn't work with this parameter.)
The text was updated successfully, but these errors were encountered: