Hello, I'm back at figuring out shaders...
I'm trying to retrieve the screen resolution inside a shader, and right now, I found no other way but to create in a ZExpression
ScreenSize : Array <mat4>
Then store the information inside it:
ScreenSize[0][0,0] = App.ScreenWidth;
ScreenSize[0][0,1] = App.ScreenHeight;
Then having a shaderVariable in my shader:
screenSize (ValueArrayRef:ScreenSize, ArrayKind:Mat4)
And use it in the shader:
float ditherScale = min(screenSize[0][0], screenSize[0][1]) / 640.0;
While it works, this seems overly complicated. Is there some other way to do that?
And as I'm writing it, I think it would be best to calculate the ditherScale during initialization, then pass that float to the shader.
How to retrieve screen resolution inside a shader?
Moderator: Moderators
How to retrieve screen resolution inside a shader?
Last edited by Ats on Thu Apr 18, 2024 3:55 pm, edited 1 time in total.
Re: How to retrieve screen resolution inside a shader?
Hi Ats,
But it's easier to give you a proper suggestion when i know exactly what you're trying to do
K
What do you need the screen resolution for in your shader? If it's just to calculate "ditherScale", then simply calculate that value in a ZExpression instead and pass the result as a ShaderVariable.
But it's easier to give you a proper suggestion when i know exactly what you're trying to do
K
Re: How to retrieve screen resolution inside a shader?
That's the conclusion I went through while writing my question, in the end
I'm writing a diffuse + dithering shader (I think I do), with a pixel density that stays the same regardless of the game resolution:
Or maybe the dithering should be made on the final image, post process, I really don't know
I'm writing a diffuse + dithering shader (I think I do), with a pixel density that stays the same regardless of the game resolution:
Code: Select all
#ifdef GL_ES
precision mediump float;
#endif
varying vec3 N;
varying vec3 v;
varying vec4 v_Color;
uniform vec4 globalColor; // = Material.Color
uniform mat4 lightPosition;
uniform mat4 lightColorAmbient;
uniform mat4 fogColor;
// Dithering pattern
const mat3 ditherMatrix = mat3(
0.0, 0.5, 0.125,
0.75, 0.25, 0.625,
0.1875, 0.6875, 0.0625
);
// Screen size
uniform mat4 screenSize;
void main (void)
{
// Light position
vec3 LPosition = vec3(lightPosition[0][0], lightPosition[0][1], lightPosition[0][2]);
vec3 L = normalize(LPosition - v);
// calculate Diffuse Term
vec4 LAmbient = vec4(lightColorAmbient[0][0], lightColorAmbient[0][1], lightColorAmbient[0][2], 1.0);
vec4 LDiffuse = globalColor * LAmbient;
// clamp pour éviter les couleurs brulées sur android avec la distance de la lumière
vec4 Idiff = 3.0 * LDiffuse * max(dot(N,L), 0.0);
// Réglages des contrastes (fait planter le jeu sur android!? Parce que j'avais mis 1 au lieu de 1.0)
Idiff = (0.7 * (Idiff + 1.0) - 1.0 + 0.4) * 0.5 + 0.5;
// Calculate dithering scale based on screen resolution
float ditherScale = min(screenSize[0][0], screenSize[0][1]) / 640.0;
// Dithering for surface shadow
float ditherValue = ditherMatrix[int(gl_FragCoord.x / ditherScale) % 2][int(gl_FragCoord.y / ditherScale) % 3];
float surfaceShadowIntensity = clamp(Idiff.r, 0.0, 1.0);
float ditheredIntensity = mix(surfaceShadowIntensity, surfaceShadowIntensity + 0.05, ditherValue);
vec4 ditheredColor = vec4(ditheredIntensity);
// Fog
vec4 fog = vec4(fogColor[0][0], fogColor[0][1], fogColor[0][2], 1.0);
// Final color
vec4 color = v_Color * ditheredColor;
gl_FragColor = mix(color, fog, clamp(-v.z / 500.0, 0.0, 1.0));
}
Re: How to retrieve screen resolution inside a shader?
Hi Ats,
However, this might not always be the ideal approach .. and this doesn't have much to do with dithering either. Dithering is used to create the illusion of a greater color-depth than you're actually using. This is more like a "brightness pattern overlay", which you could do with a simple blended texture on a fullscreen quad as well.
K
You could use gl_FragCoord for that. Here's a super-basic example .. "dithering" happens at pixel size of 4x4 pixels regardless of the viewport size ( change the pixel_size constant to adjust the desired pixel density ).
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application" ScreenMode="0" FileVersion="2">
<OnLoaded>
<SpawnModel Model="Demo"/>
</OnLoaded>
<Content>
<Model Name="Demo" RotationVelocity="0.2 0.3 0">
<OnRender>
<UseMaterial Material="DemoMaterial"/>
<RenderMesh Mesh="DemoMesh"/>
</OnRender>
</Model>
<Mesh Name="DemoMesh">
<Producers>
<MeshBox/>
</Producers>
</Mesh>
<Shader Name="DemoShader">
<VertexShaderSource>
<![CDATA[//
void main()
{
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}]]>
</VertexShaderSource>
<FragmentShaderSource>
<![CDATA[//
const mat3 dither = mat3(0.0, 0.5, 0.125, 0.75, 0.25, 0.625, 0.1875, 0.6875, 0.0625);
const float pixel_size = 4.0;
//
void main()
{
int x = int(mod(gl_FragCoord.x / pixel_size, 3.0));
int y = int(mod(gl_FragCoord.y / pixel_size, 3.0));
float s = dither[y][x];
gl_FragColor = vec4(s, s, s, 1.0);
}]]>
</FragmentShaderSource>
</Shader>
<Material Name="DemoMaterial" Shading="1" Light="0" Shader="DemoShader"/>
</Content>
</ZApplication>
K
Re: How to retrieve screen resolution inside a shader?
Thanks. I'll see what I can do with that
I also managed to find the topic that was already talking about dithering with your examples:
https://www.emix8.org/forum/viewtopic.p ... 330&p=8649
(The search feature of phpbb isn't great...)
I also managed to find the topic that was already talking about dithering with your examples:
https://www.emix8.org/forum/viewtopic.p ... 330&p=8649
(The search feature of phpbb isn't great...)