Posted: 1st Feb 2023 20:57
So I've been messing around with ChatGPT, and it does a worryingly good job of AppGameKit code, though it favours the C version.

However tonight I decided to try it with some shaders and it was.....better than expected. The bold sentences below are exactly what I typed....

write me a glsl shader for version 1.0 that does 3d projection shadows for a point light
Here's an example of a GLSL shader for version 1.0 that implements 3D projection shadows for a point light:

+ Code Snippet
uniform vec3 lightPosition;
uniform sampler2D shadowMap;
uniform float shadowStrength;

varying vec4 ShadowCoord;

void main()
{
    vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
    shadowCoordinateWdivide.z += 0.0005;

    float distanceFromLight = texture2D( shadowMap, shadowCoordinateWdivide.st ).z;
    float shadow = 1.0;
    if ( ShadowCoord.w > 0.0 )
    {
        shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0;
    }

    vec3 diffuse = shadow * vec3(shadowStrength);
    gl_FragColor = vec4(diffuse, 1.0);
}

In this shader, the lightPosition uniform variable is the position of the point light in world space. The shadowMap uniform variable is a 2D texture that stores the shadow map for the point light. The shadowStrength uniform variable is a scaler that determines the strength of the shadows. The ShadowCoord varying variable holds the shadow coordinate for the current fragment, which is used to sample the shadow map.

In the main function, the shadow coordinate is divided by its w component to get the texture coordinate. The distanceFromLight variable holds the distance from the light to the surface stored in the shadow map for the current fragment. The shadow variable is then calculated by comparing the distance from the light to the surface with the depth value stored in the shadow map. If the distance is greater than the depth, the shadow strength is set to 0.5, otherwise it is set to 1.0.

Finally, the diffuse lighting is calculated by multiplying the shadow strength by the shadowStrength uniform variable and the resulting color is set as the output color for the fragment.




Comment the code to explain what each line does
Here's a commented version of the code for the 3D projection shadow shader:

+ Code Snippet
// Uniform variable for the light position in world space
uniform vec3 lightPosition;

// Uniform variable for the shadow map texture
uniform sampler2D shadowMap;

// Uniform variable for the strength of the shadows
uniform float shadowStrength;

// Varying variable for the shadow coordinate for the current fragment
varying vec4 ShadowCoord;

void main()
{
    // Divide the shadow coordinate by its w component to get the texture coordinate
    vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;

    // Offset the z component slightly to avoid shadow acne
    shadowCoordinateWdivide.z += 0.0005;

    // Sample the shadow map texture to get the distance from the light to the surface
    float distanceFromLight = texture2D( shadowMap, shadowCoordinateWdivide.st ).z;

    // Initialize the shadow strength to 1.0 (fully lit)
    float shadow = 1.0;

    // If the w component of the shadow coordinate is greater than 0, the fragment is in view
    if ( ShadowCoord.w > 0.0 )
    {
        // If the distance from the light to the surface is less than the depth stored in the shadow map,
        // the fragment is in shadow, set the shadow strength to 0.5
        shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0;
    }

    // Calculate the diffuse lighting by multiplying the shadow strength by the shadow strength uniform
    vec3 diffuse = shadow * vec3(shadowStrength);

    // Set the output color for the fragment as the diffuse lighting, with an alpha value of 1.0
    gl_FragColor = vec4(diffuse, 1.0);
}



add in soft shadows
Here's an example of a GLSL shader for version 1.0 that implements soft 3D projection shadows for a point light:

+ Code Snippet
uniform vec3 lightPosition;
uniform sampler2D shadowMap;
uniform float shadowStrength;
uniform float shadowSmoothness;

varying vec4 ShadowCoord;

void main()
{
    vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
    shadowCoordinateWdivide.z += 0.0005;

    float distanceFromLight = texture2D( shadowMap, shadowCoordinateWdivide.st ).z;
    float shadow = 1.0;
    if ( ShadowCoord.w > 0.0 )
    {
        float shadowDelta = shadowSmoothness * (distanceFromLight - shadowCoordinateWdivide.z);
        shadow = clamp(1.0 - shadowDelta, 0.0, 1.0);
    }

    vec3 diffuse = shadow * vec3(shadowStrength);
    gl_FragColor = vec4(diffuse, 1.0);
}

In this version of the shader, a new uniform variable shadowSmoothness has been added. This variable determines the smoothness of the transition from lit to shadowed. The shadow strength is now calculated by subtracting the difference between the distanceFromLight and shadowCoordinateWdivide.z from 1.0 and clamping the result between 0.0 and 1.0. The result is then multiplied by shadowStrength to determine the final diffuse lighting for the fragment.


how can that code be made faster?
Here are a few ways to optimize the code for better performance:

Reduce texture lookups: You can reduce the number of texture lookups by using a higher-resolution shadow map or implementing a variance shadow map instead of a traditional shadow map. This will help reduce the amount of aliasing and reduce the number of times you need to sample the shadow map.

Use a lower-precision texture format: If your GPU supports it, you can use a lower-precision texture format (such as GL_R16F or GL_R32F) for the shadow map, which will reduce the amount of memory bandwidth required to sample the shadow map.

Use an efficient shadow sampling algorithm: Instead of using a simple texture2D lookup to sample the shadow map, you can use more advanced techniques such as percentage-closer filtering (PCF) or an exponential variance shadow map (EVSM) to improve the quality of the shadows and reduce the number of required texture lookups.

Use hardware-accelerated depth comparisons: If your GPU supports it, you can use the shadow2DProj function to perform hardware-accelerated depth comparisons between the light's depth and the depth stored in the shadow map, which can be faster than performing the depth comparison in the fragment shader.

Use the right data type: Use the right data type for your uniform variables. For example, use float instead of vec3 when possible, and use int instead of float when an integer value is sufficient.

By implementing these optimizations, you can improve the performance of your shader and achieve smoother and more accurate shadows.


can you write me a pbr shader for glsl version 1.0 that includes the shadow shader from above
Here's an example of a PBR (physically based rendering) shader for GLSL version 1.0 that includes the shadow shader from above:

+ Code Snippet
uniform vec3 lightPosition;
uniform vec3 cameraPosition;
uniform sampler2D shadowMap;
uniform float shadowStrength;
uniform float shadowSmoothness;

uniform sampler2D albedoMap;
uniform sampler2D normalMap;
uniform sampler2D metallicMap;
uniform sampler2D roughnessMap;
uniform sampler2D aoMap;

varying vec2 TexCoord;
varying vec3 FragPos;
varying vec3 Normal;
varying vec4 ShadowCoord;

vec3 lightColor = vec3(1.0, 1.0, 1.0);
float ambientStrength = 0.1;

vec3 CalcLight(vec3 lightDir, vec3 normal)
{
    float diff = max(dot(normal, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;
    vec3 ambient = ambientStrength * lightColor;
    return (diffuse + ambient);
}

void main()
{
    vec4 shadowCoordinateWdivide = ShadowCoord / ShadowCoord.w ;
    shadowCoordinateWdivide.z += 0.0005;

    float distanceFromLight = texture2D( shadowMap, shadowCoordinateWdivide.st ).z;
    float shadow = 1.0;
    if ( ShadowCoord.w > 0.0 )
    {
        float shadowDelta = shadowSmoothness * (distanceFromLight - shadowCoordinateWdivide.z);
        shadow = clamp(1.0 - shadowDelta, 0.0, 1.0);
    }

    vec3 albedo = texture2D(albedoMap, TexCoord).rgb;
    vec3 normal = texture2D(normalMap, TexCoord).rgb;
    normal = normalize(normal * 2.0 - 1.0);
    float metallic = texture2D(metallicMap, TexCoord).r;
    float roughness = texture2D(roughnessMap, TexCoord).r;
    float ao = texture2D(aoMap, TexCoord).r;

    vec3 lightDir = normalize(lightPosition - FragPos);
    vec3 viewDir = normalize(cameraPosition - FragPos);
    vec3 halfwayDir = normalize(lightDir + viewDir);

    vec3 diffuse = albedo * CalcLight(lightDir, normal);
    vec3 specular = vec3(pow(max(dot(normal, halfwayDir), 0.0), roughness));
    vec3 ambient = albedo * ao;

    vec3 finalColor = (ambient + (1.0 - metallic) * diffuse + metallic * specular) * shadow;
    gl_FragColor = vec4(finalColor, 1.0);
}

In this shader, the light direction, view direction, and halfway direction vectors are calculated based on the fragment's position, normal, and the camera and light positions. The diffuse, specular, and ambient contributions are then calculated using the light direction, normal, albedo, metallic, roughness, and AO (ambient occlusion)
Posted: 1st Feb 2023 22:20
only skimmed your post sp far (as it's a bit of a "wall of text" without code tag usage) but i do appreciate the notion of using it for shaders which i hadn't considered.

otherwise, limited experience with ChatGPT + AppGameKit and i wasn't impressed @ first glance while intending to continue exploring the combination.

still, looking forward to learning how it can further (& augment) my current AppGameKit prowess. and, i'll re-read (and test) the above when i have time.
Posted: 1st Feb 2023 22:26
I've not had much luck, it keeps referencing back to the C T2 code, and the mvp matrix. I understand the mvp is the Model-View-Projection matrix, however I have no idea how to do that in AppGameKit, using T1. Or even using T2.

I tried using agk_World * agk_Proj * agk_View but no luck.

It's good for C code and giving you pointers, but it's certainly not going to replace an AppGameKit coder anytime soon.

Any thoughts on an mpv matrix in an AppGameKit shader?
Posted: 2nd Feb 2023 0:21
Okay so I have next to zero clue about actually writing shaders but have noticed some MPV matrix/vector stuff in the static/animated vertex shader files in the community shadow shader which is ultimately a directional light of which 6 would make up a point light? https://forum.thegamecreators.com/thread/217568
Might help, might not, might be a case of you lot facepalming at my words lol

Edit: I know this is classic board but if you happen to use studio for any reason then don't forget to add #renderer"Basic" as needs inverting for vulkan and prefer best is default in studio - I mention as you have mentioned PBR which there is a demo of in studio using lightmaps
Posted: 6th Feb 2023 17:10
ive tried it it references alot of dbpro commands, at best i think it could write a simple loop and build a type. that said u can ask for code in other language that are similiar for advanced maths ect and convert it easy enough