1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-04 10:03:36 +00:00

Switch from shader based pseudo-random simplex noise to texture based one.

This commit is contained in:
Sergey Lipskiy 2015-02-16 21:38:46 +06:00
parent 7d51a7eb75
commit 47e4f4e8e4
7 changed files with 149 additions and 173 deletions

View File

@ -86,21 +86,6 @@ public:
void CopyFromRDRAM( u32 _address, bool _bUseAlpha);
private:
struct PBOBinder {
#ifndef GLES2
PBOBinder(GLuint _PBO)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _PBO);
}
~PBOBinder() {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
#else
PBOBinder(GLubyte* _ptr) : ptr(_ptr) {}
~PBOBinder() {free(ptr);}
GLubyte* ptr;
#endif
};
CachedTexture * m_pTexture;
#ifndef GLES2
GLuint m_PBO;

View File

@ -69,6 +69,22 @@ private:
GLenum m_drawBuffer;
};
struct PBOBinder {
#ifndef GLES2
PBOBinder(GLuint _PBO)
{
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _PBO);
}
~PBOBinder() {
glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
}
#else
PBOBinder(GLubyte* _ptr) : ptr(_ptr) {}
~PBOBinder() { free(ptr); }
GLubyte* ptr;
#endif
};
inline
FrameBufferList & frameBufferList()
{

View File

@ -8,11 +8,12 @@
#include "GLSLCombiner.h"
#include "FrameBuffer.h"
#include "DepthBuffer.h"
#include "RSP.h"
#include "VI.h"
#include "Log.h"
#define SHADER_PRECISION
#include "Shaders.h"
#include "Noise_shader.h"
static GLuint g_vertex_shader_object;
static GLuint g_calc_light_shader_object;
@ -63,6 +64,101 @@ bool checkProgramLinkStatus(GLuint obj)
return true;
}
static const GLuint noiseTexIndex = 2;
class NoiseTexture
{
public:
NoiseTexture() : m_pTexture(NULL), m_PBO(0), m_DList(0) {}
void init();
void destroy();
void update();
private:
CachedTexture * m_pTexture;
#ifndef GLES2
GLuint m_PBO;
#else
GLubyte* m_PBO;
#endif
u32 m_DList;
} noiseTex;
void NoiseTexture::init()
{
m_pTexture = textureCache().addFrameBufferTexture();
m_pTexture->format = G_IM_FMT_RGBA;
m_pTexture->clampS = 1;
m_pTexture->clampT = 1;
m_pTexture->frameBufferTexture = TRUE;
m_pTexture->maskS = 0;
m_pTexture->maskT = 0;
m_pTexture->mirrorS = 0;
m_pTexture->mirrorT = 0;
m_pTexture->realWidth = 640;
m_pTexture->realHeight = 480;
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight;
textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
// Generate Pixel Buffer Object. Initialize it later
#ifndef GLES2
glGenBuffers(1, &m_PBO);
#endif
}
void NoiseTexture::destroy()
{
if (m_pTexture != NULL) {
textureCache().removeFrameBufferTexture(m_pTexture);
m_pTexture = NULL;
}
#ifndef GLES2
glDeleteBuffers(1, &m_PBO);
m_PBO = 0;
#endif
}
void NoiseTexture::update()
{
if (m_DList == RSP.DList)
return;
const u32 dataSize = VI.width*VI.height;
if (dataSize == 0)
return;
#ifndef GLES2
PBOBinder binder(m_PBO);
glBufferData(GL_PIXEL_UNPACK_BUFFER, dataSize, NULL, GL_DYNAMIC_DRAW);
GLubyte* ptr = (GLubyte*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
#else
m_PBO = (GLubyte*)malloc(dataSize);
GLubyte* ptr = m_PBO;
PBOBinder binder(m_PBO);
#endif // GLES2
if (ptr == NULL)
return;
for (u32 y = 0; y < VI.height; ++y) {
for (u32 x = 0; x < VI.width; ++x)
ptr[x + y*VI.width] = rand()&0xFF;
}
#ifndef GLES2
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER); // release the mapped buffer
#endif
glActiveTexture(GL_TEXTURE0 + noiseTexIndex);
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
#ifndef GLES2
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_RED, GL_UNSIGNED_BYTE, 0);
#else
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VI.width, VI.height, GL_RED, GL_UNSIGNED_BYTE, m_PBO);
#endif
m_DList = RSP.DList;
}
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static
void InitZlutTexture()
@ -184,7 +280,7 @@ void InitShaderCombiner()
assert(checkShaderCompileStatus(g_calc_mipmap_shader_object));
g_calc_noise_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(g_calc_noise_shader_object, 1, &noise_fragment_shader, NULL);
glShaderSource(g_calc_noise_shader_object, 1, &fragment_shader_noise, NULL);
glCompileShader(g_calc_noise_shader_object);
assert(checkShaderCompileStatus(g_calc_noise_shader_object));
@ -203,6 +299,7 @@ void InitShaderCombiner()
InitZlutTexture();
InitShadowMapShader();
noiseTex.init();
#endif // GL_IMAGE_TEXTURES_SUPPORT
#endif // GLES2
}
@ -226,6 +323,7 @@ void DestroyShaderCombiner() {
g_calc_depth_shader_object = 0;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
noiseTex.destroy();
DestroyZlutTexture();
DestroyShadowMapShader();
#endif // GL_IMAGE_TEXTURES_SUPPORT
@ -249,7 +347,7 @@ const char *ColorInput[] = {
"uEnvColor.a",
"lod_frac", // TODO: emulate lod_fraction
"vec3(uPrimLod)",
"vec3(0.5 + 0.5*snoise(vNoiseCoord2D))",
"vec3(0.5 + 0.5*snoise())",
"vec3(uK4)",
"vec3(uK5)",
"vec3(1.0)",
@ -273,7 +371,7 @@ const char *AlphaInput[] = {
"uEnvColor.a",
"lod_frac",
"uPrimLod",
"0.5 + 0.5*snoise(vNoiseCoord2D)",
"0.5 + 0.5*snoise()",
"uK4",
"uK5",
"1.0",
@ -531,6 +629,7 @@ ShaderCombiner::~ShaderCombiner() {
void ShaderCombiner::_locateUniforms() {
LocateUniform(uTex0);
LocateUniform(uTex1);
LocateUniform(uTexNoise);
LocateUniform(uTlutImage);
LocateUniform(uZlutImage);
LocateUniform(uDepthImage);
@ -559,7 +658,6 @@ void ShaderCombiner::_locateUniforms() {
LocateUniform(uK4);
LocateUniform(uK5);
LocateUniform(uPrimLod);
LocateUniform(uNoiseTime);
LocateUniform(uScreenWidth);
LocateUniform(uScreenHeight);
LocateUniform(uMinLod);
@ -614,6 +712,7 @@ void ShaderCombiner::update(bool _bForce) {
_setIUniform(m_uniforms.uTex0, 0, _bForce);
_setIUniform(m_uniforms.uTex1, 1, _bForce);
_setIUniform(m_uniforms.uTexNoise, noiseTexIndex, _bForce);
_setFUniform(m_uniforms.uScreenWidth, (float)video().getWidth(), _bForce);
_setFUniform(m_uniforms.uScreenHeight, (float)video().getHeight(), _bForce);
@ -729,8 +828,10 @@ void ShaderCombiner::updateColors(bool _bForce)
_setIUniform(m_uniforms.uGammaCorrectionEnabled, *REG.VI_STATUS & 8, _bForce);
const int nDither = (gDP.otherMode.cycleType < G_CYC_COPY) && (gDP.otherMode.colorDither == G_CD_NOISE || gDP.otherMode.alphaDither == G_AD_NOISE || gDP.otherMode.alphaCompare == G_AC_DITHER) ? 1 : 0;
if ((m_nInputs & (1<<NOISE)) + nDither != 0)
_setFUniform(m_uniforms.uNoiseTime, (float)(rand()&255), _bForce);
if ((m_nInputs & (1 << NOISE)) + nDither != 0) {
_setFV2Uniform(m_uniforms.uScreenScale, video().getScaleX(), video().getScaleY(), _bForce);
noiseTex.update();
}
gDP.changed &= ~CHANGED_COMBINE_COLORS;
}

View File

@ -35,14 +35,14 @@ private:
struct UniformLocation
{
iUniform uTex0, uTex1, uTlutImage, uZlutImage, uDepthImage,
iUniform uTex0, uTex1, uTexNoise, uTlutImage, uZlutImage, uDepthImage,
uFogMode, uFogUsage, uEnableLod, uEnableAlphaTest,
uEnableDepth, uEnableDepthCompare, uEnableDepthUpdate,
uDepthMode, uDepthSource, uFb8Bit, uFbFixedAlpha, uRenderState, uSpecialBlendMode,
uMaxTile, uTextureDetail, uTexturePersp,
uAlphaCompareMode, uAlphaDitherMode, uColorDitherMode, uGammaCorrectionEnabled;
fUniform uFogMultiplier, uFogOffset, uK4, uK5, uPrimLod, uNoiseTime, uScreenWidth, uScreenHeight,
fUniform uFogMultiplier, uFogOffset, uK4, uK5, uPrimLod, uScreenWidth, uScreenHeight,
uMinLod, uDeltaZ, uAlphaTestValue;
fv4Uniform uEnvColor, uPrimColor, uFogColor, uCenterColor, uScaleColor, uBlendColor;

View File

@ -29,7 +29,7 @@
<string>About GLideN64</string>
</property>
<property name="windowIcon">
<iconset resource="icon.qrc">
<iconset>
<normaloff>:/Icon.png</normaloff>:/Icon.png</iconset>
</property>
<property name="modal">
@ -90,7 +90,7 @@
</font>
</property>
<property name="text">
<string>Olivier Thacker</string>
<string>Olivieryuyu</string>
</property>
</widget>
</item>
@ -134,7 +134,7 @@
</font>
</property>
<property name="text">
<string>Funder name</string>
<string>Mush Man</string>
</property>
</widget>
</item>
@ -222,7 +222,7 @@
</font>
</property>
<property name="text">
<string>Funder name</string>
<string>zilmar</string>
</property>
</widget>
</item>
@ -420,7 +420,7 @@ p, li { white-space: pre-wrap; }
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;Orkin&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; - author of original glN64 graphics plugin&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;Hiroshi Morii&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; - author of GlideHQ texture library&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;Ian McEwan, Ashima Arts&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; - authors of the noise shader. Copyright (C) 2011 Ashima Arts.&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;Nathaniel Meyer&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; - author of the blur shader. Copyright: Nutty Software&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:10pt; font-weight:600;&quot;&gt;Nathaniel Meyer&lt;/span&gt;&lt;span style=&quot; font-size:10pt;&quot;&gt; - author of the blur shader. Copyright: Nutty Software&lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:10pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>
@ -446,9 +446,7 @@ p, li { white-space: pre-wrap; }
</item>
</layout>
</widget>
<resources>
<include location="icon.qrc"/>
</resources>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>

View File

@ -1,128 +0,0 @@
const char *noise_fragment_shader =
//
// Description : Array and textureless GLSL 2D simplex noise function.
// Author : Ian McEwan, Ashima Arts.
// Maintainer : ijm
// Lastmod : 20110822 (ijm)
// License : Copyright (C) 2011 Ashima Arts. All rights reserved.
// Distributed under the MIT License. See LICENSE file.
// https://github.com/ashima/webgl-noise
//
//
#ifdef SHADER_PRECISION
"#version 150 core \n"
"mediump vec3 mod289(mediump vec3 x) { \n"
" return x - floor(x * (1.0 / 289.0)) * 289.0; \n"
"} \n"
" \n"
"mediump vec2 mod289(mediump vec2 x) { \n"
" return x - floor(x * (1.0 / 289.0)) * 289.0; \n"
"} \n"
" \n"
"mediump vec3 permute(mediump vec3 x) { \n"
" return mod289(((x*34.0)+1.0)*x); \n"
"} \n"
" \n"
"lowp float snoise(in mediump vec2 v) \n"
"{ \n"
" const mediump vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 \n"
" 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) \n"
" -0.577350269189626, // -1.0 + 2.0 * C.x \n"
" 0.024390243902439); // 1.0 / 41.0 \n"
// First corner
" mediump vec2 i = floor(v + dot(v, C.yy) ); \n"
" mediump vec2 x0 = v - i + dot(i, C.xx); \n"
" \n"
// Other corners
" mediump vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); \n"
" mediump vec4 x12 = x0.xyxy + C.xxzz; \n"
" x12.xy -= i1; \n"
" \n"
// Permutations
" i = mod289(i); // Avoid truncation effects in permutation \n"
" mediump vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) \n"
" + i.x + vec3(0.0, i1.x, 1.0 )); \n"
" \n"
" mediump vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n"
" m = m*m ; \n"
" m = m*m ; \n"
" \n"
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
" \n"
" mediump vec3 x = 2.0 * fract(p * C.www) - 1.0; \n"
" mediump vec3 h = abs(x) - 0.5; \n"
" mediump vec3 ox = floor(x + 0.5); \n"
" mediump vec3 a0 = x - ox; \n"
" \n"
// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
" m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); \n"
" \n"
// Compute final noise value at P
" mediump vec3 g; \n"
" g.x = a0.x * x0.x + h.x * x0.y; \n"
" g.yz = a0.yz * x12.xz + h.yz * x12.yw; \n"
" return 130.0 * dot(m, g); \n"
"} \n"
" \n"
#else
"#version 150 core \n"
"vec3 mod289(vec3 x) { \n"
" return x - floor(x * (1.0 / 289.0)) * 289.0; \n"
"} \n"
" \n"
"vec2 mod289(vec2 x) { \n"
" return x - floor(x * (1.0 / 289.0)) * 289.0; \n"
"} \n"
" \n"
"vec3 permute(vec3 x) { \n"
" return mod289(((x*34.0)+1.0)*x); \n"
"} \n"
" \n"
"float snoise(in vec2 v) \n"
" { \n"
" const vec4 C = vec4(0.211324865405187, // (3.0-sqrt(3.0))/6.0 \n"
" 0.366025403784439, // 0.5*(sqrt(3.0)-1.0) \n"
" -0.577350269189626, // -1.0 + 2.0 * C.x \n"
" 0.024390243902439); // 1.0 / 41.0 \n"
// First corner
" vec2 i = floor(v + dot(v, C.yy) ); \n"
" vec2 x0 = v - i + dot(i, C.xx); \n"
" \n"
// Other corners
" vec2 i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0); \n"
" vec4 x12 = x0.xyxy + C.xxzz; \n"
" x12.xy -= i1; \n"
" \n"
// Permutations
" i = mod289(i); // Avoid truncation effects in permutation \n"
" vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) \n"
" + i.x + vec3(0.0, i1.x, 1.0 )); \n"
" \n"
" vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);\n"
" m = m*m ; \n"
" m = m*m ; \n"
" \n"
// Gradients: 41 points uniformly over a line, mapped onto a diamond.
// The ring size 17*17 = 289 is close to a multiple of 41 (41*7 = 287)
" \n"
" vec3 x = 2.0 * fract(p * C.www) - 1.0; \n"
" vec3 h = abs(x) - 0.5; \n"
" vec3 ox = floor(x + 0.5); \n"
" vec3 a0 = x - ox; \n"
" \n"
// Normalise gradients implicitly by scaling m
// Approximation of: m *= inversesqrt( a0*a0 + h*h );
" m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h ); \n"
" \n"
// Compute final noise value at P
" vec3 g; \n"
" g.x = a0.x * x0.x + h.x * x0.y; \n"
" g.yz = a0.yz * x12.xz + h.yz * x12.yw; \n"
" return clamp(130.0 * dot(m, g), -1.0, 1.0); \n"
"} \n"
" \n"
#endif
;

View File

@ -9,7 +9,6 @@ static const char* vertex_shader =
" \n"
"uniform int uRenderState; \n"
"uniform int uTexturePersp; \n"
"uniform lowp float uNoiseTime; \n"
" \n"
"uniform int uFogMode; \n"
"uniform lowp int uFogUsage; \n"
@ -29,7 +28,6 @@ static const char* vertex_shader =
"out mediump vec2 vTexCoord0; \n"
"out mediump vec2 vTexCoord1; \n"
"out mediump vec2 vLodTexCoord; \n"
"out mediump vec2 vNoiseCoord2D; \n"
"out lowp float vNumLights; \n"
"out mediump float vFogFragCoord; \n"
#else
@ -42,7 +40,6 @@ static const char* vertex_shader =
" \n"
"uniform int uRenderState; \n"
"uniform int uTexturePersp; \n"
"uniform float uNoiseTime; \n"
" \n"
"uniform int uFogMode; \n"
"uniform int uFogUsage; \n"
@ -62,7 +59,6 @@ static const char* vertex_shader =
"out vec2 vTexCoord0; \n"
"out vec2 vTexCoord1; \n"
"out vec2 vLodTexCoord; \n"
"out vec2 vNoiseCoord2D; \n"
"out float vNumLights; \n"
"out float vFogFragCoord; \n"
#endif
@ -120,7 +116,6 @@ static const char* vertex_shader =
" vTexCoord1 = aTexCoord1; \n"
" vNumLights = 0.0; \n"
" } \n"
" vNoiseCoord2D = vec2(gl_Position.x*uScreenWidth, gl_Position.y*uScreenHeight + uNoiseTime);\n"
" gl_ClipDistance[0] = gl_Position.w - gl_Position.z; \n"
"} \n"
;
@ -151,7 +146,6 @@ static const char* fragment_shader_header_common_variables =
"in mediump vec2 vTexCoord0;\n"
"in mediump vec2 vTexCoord1;\n"
"in mediump vec2 vLodTexCoord;\n"
"in mediump vec2 vNoiseCoord2D;\n"
"in lowp float vNumLights; \n"
"in mediump float vFogFragCoord;\n"
"lowp vec3 input_color; \n"
@ -181,7 +175,6 @@ static const char* fragment_shader_header_common_variables =
"in vec2 vTexCoord0; \n"
"in vec2 vTexCoord1; \n"
"in vec2 vLodTexCoord; \n"
"in vec2 vNoiseCoord2D; \n"
"in float vNumLights; \n"
"in float vFogFragCoord; \n"
"vec3 input_color; \n"
@ -192,14 +185,14 @@ static const char* fragment_shader_header_common_variables =
static const char* fragment_shader_header_common_functions =
#ifdef SHADER_PRECISION
" \n"
"lowp float snoise(in mediump vec2 v); \n"
"lowp float snoise(); \n"
"mediump float calc_light(in lowp float fLights, in lowp vec3 input_color, out lowp vec3 output_color);\n"
"mediump float mipmap(out lowp vec4 readtex0, out lowp vec4 readtex1); \n"
"bool depth_compare(); \n"
"bool alpha_test(in lowp float alphaValue); \n"
#else
" \n"
"float snoise(in vec2 v); \n"
"float snoise(); \n"
"float calc_light(in float fLights, in vec3 input_color, out vec3 output_color);\n"
"float mipmap(out vec4 readtex0, out vec4 readtex1); \n"
"bool depth_compare(); \n"
@ -287,7 +280,7 @@ static const char* fragment_shader_header_main =
"void main() \n"
"{ \n"
" if (uAlphaCompareMode == 3) {//dither \n"
" if (snoise(vNoiseCoord2D) < 0.0) discard; \n"
" if (snoise() < 0.0) discard; \n"
" } \n"
" lowp vec4 vec_color, combined_color; \n"
" lowp float alpha1, alpha2; \n"
@ -298,7 +291,7 @@ static const char* fragment_shader_header_main =
"void main() \n"
"{ \n"
" if (uAlphaCompareMode == 3) {//dither \n"
" if (snoise(vNoiseCoord2D) < 0.0) discard; \n"
" if (snoise() < 0.0) discard; \n"
" } \n"
" vec4 vec_color, combined_color; \n"
" float alpha1, alpha2; \n"
@ -308,14 +301,14 @@ static const char* fragment_shader_header_main =
static const char* fragment_shader_color_dither =
" if (uColorDitherMode == 2) { \n"
" color2 += 0.03125*snoise(vNoiseCoord2D); \n"
" color2 += 0.03125*snoise(); \n"
" color2 = clamp(color2, 0.0, 1.0); \n"
" } \n"
;
static const char* fragment_shader_alpha_dither =
" if (uAlphaDitherMode == 2) { \n"
" alpha2 += 0.03125*snoise(vNoiseCoord2D); \n"
" alpha2 += 0.03125*snoise(); \n"
" alpha2 = clamp(alpha2, 0.0, 1.0); \n"
" } \n"
;
@ -533,6 +526,17 @@ static const char* fragment_shader_mipmap =
#endif
;
static const char* fragment_shader_noise =
"#version 330 core \n"
"uniform sampler2D uTexNoise; \n"
"uniform mediump vec2 uScreenScale; \n"
"lowp float snoise() \n"
"{ \n"
" ivec2 coord = ivec2(gl_FragCoord.xy/uScreenScale); \n"
" return (texelFetch(uTexNoise, coord, 0).r - 0.5)*2.0;\n"
"} \n"
;
#ifdef GL_IMAGE_TEXTURES_SUPPORT
static const char* depth_compare_shader_float =
"#version 430 \n"