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

Implement Noise color input.

This commit is contained in:
Sergey Lipskiy 2013-04-15 13:31:01 +07:00
parent 08744df681
commit 63a3cdc720
3 changed files with 123 additions and 22 deletions

View File

@ -11,6 +11,7 @@
#include "OpenGL.h"
#include "Combiner.h"
#include "GLSLCombiner.h"
#include "Noise_shader.h"
static
void display_warning(const char *text, ...)
@ -46,7 +47,7 @@ const char *ColorInput[] = {
"env_color.a",
"vec3(0.5)", // TODO: emulate lod_fraction
"vec3(prim_lod)",
"vec3(1.0)", // TODO: emulate noise
"vec3(0.5 + 0.5*snoise(noiseCoord2D))",
"vec3(k4)",
"vec3(k5)",
"vec3(1.0)",
@ -70,7 +71,7 @@ const char *AlphaInput[] = {
"env_color.a",
"0.5", // TODO: emulate lod_fraction
"prim_lod",
"1.0", // TODO: emulate noise
"1.0",
"k4",
"k5",
"1.0",
@ -107,10 +108,13 @@ static const char* fragment_shader_header =
"uniform float k4; \n"
"uniform float k5; \n"
"uniform float prim_lod; \n"
"uniform int dither_enabled; \n"
"varying vec4 secondary_color; \n"
"varying vec2 noiseCoord2D; \n"
"vec3 input_color; \n"
" \n"
"float calc_light(); \n"
"float snoise(vec2 v); \n"
#ifdef USE_TOONIFY
"void toonify(in float intensity); \n"
#endif
@ -234,6 +238,8 @@ static const char* vertex_shader =
"} \n" // i've found to get it working fast with ATI drivers
;
#else
"uniform float time; \n"
"varying vec2 noiseCoord2D; \n"
"varying vec4 secondary_color; \n"
"void main() \n"
"{ \n"
@ -243,6 +249,7 @@ static const char* vertex_shader =
" gl_TexCoord[1] = gl_MultiTexCoord1; \n"
" gl_FogFragCoord = (gl_Fog.end - gl_FogCoord) * gl_Fog.scale; \n"
" secondary_color = gl_SecondaryColor; \n"
" noiseCoord2D = gl_Vertex.xy + vec2(0.0, time); \n"
"} \n"
;
#endif
@ -260,15 +267,17 @@ void InitGLSLCombiner()
}
static
void CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _fragment_shader) {
int CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _fragment_shader) {
char buf[128];
bool bBracketOpen = false;
int nRes = 0;
for (int i = 0; i < _stage.numOps; ++i) {
switch(_stage.op[i].op) {
case LOAD:
sprintf(buf, "(%s ", _Input[_stage.op[i].param1]);
strcat(_fragment_shader, buf);
bBracketOpen = true;
nRes |= 1 << _stage.op[i].param1;
break;
case SUB:
if (bBracketOpen) {
@ -277,6 +286,7 @@ void CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _
} else
sprintf(buf, "- %s", _Input[_stage.op[i].param1]);
strcat(_fragment_shader, buf);
nRes |= 1 << _stage.op[i].param1;
break;
case ADD:
if (bBracketOpen) {
@ -285,6 +295,7 @@ void CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _
} else
sprintf(buf, "+ %s", _Input[_stage.op[i].param1]);
strcat(_fragment_shader, buf);
nRes |= 1 << _stage.op[i].param1;
break;
case MUL:
if (bBracketOpen) {
@ -293,10 +304,14 @@ void CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _
} else
sprintf(buf, "*%s", _Input[_stage.op[i].param1]);
strcat(_fragment_shader, buf);
nRes |= 1 << _stage.op[i].param1;
break;
case INTER:
sprintf(buf, "mix(%s, %s, %s)", ColorInput[_stage.op[0].param2], _Input[_stage.op[0].param1], _Input[_stage.op[0].param3]);
strcat(_fragment_shader, buf);
nRes |= 1 << _stage.op[i].param1;
nRes |= 1 << _stage.op[i].param2;
nRes |= 1 << _stage.op[i].param3;
break;
// default:
@ -306,35 +321,36 @@ void CompileCombiner(const CombinerStage & _stage, const char** _Input, char * _
if (bBracketOpen)
strcat(_fragment_shader, ")");
strcat(_fragment_shader, "; \n");
return nRes;
}
GLSLCombiner::GLSLCombiner(Combiner *_color, Combiner *_alpha) {
m_vertexShaderObject = vertex_shader_object;
char *fragment_shader = (char*)malloc(4096);
strcpy(fragment_shader, fragment_shader_header);
#if 1
strcat(fragment_shader, " if (dither_enabled > 0) \n");
strcat(fragment_shader, " if (snoise(noiseCoord2D) < 0.5) discard; \n");
strcat(fragment_shader, fragment_shader_readtex0color);
strcat(fragment_shader, fragment_shader_readtex1color);
#if 1
strcat(fragment_shader, " float intensity = calc_light(); \n");
strcat(fragment_shader, " vec_color = vec4(input_color, gl_Color.a); \n");
strcat(fragment_shader, " alpha1 = ");
CompileCombiner(_alpha->stage[0], AlphaInput, fragment_shader);
m_nInputs = CompileCombiner(_alpha->stage[0], AlphaInput, fragment_shader);
strcat(fragment_shader, " color1 = ");
CompileCombiner(_color->stage[0], ColorInput, fragment_shader);
m_nInputs |= CompileCombiner(_color->stage[0], ColorInput, fragment_shader);
strcat(fragment_shader, " combined_color = vec4(color1, alpha1); \n");
if (_alpha->numStages == 2) {
strcat(fragment_shader, " alpha2 = ");
CompileCombiner(_alpha->stage[1], AlphaInput, fragment_shader);
m_nInputs |= CompileCombiner(_alpha->stage[1], AlphaInput, fragment_shader);
} else
strcat(fragment_shader, " alpha2 = alpha1; \n");
if (_color->numStages == 2) {
strcat(fragment_shader, " color2 = ");
CompileCombiner(_color->stage[1], ColorInput, fragment_shader);
m_nInputs |= CompileCombiner(_color->stage[1], ColorInput, fragment_shader);
} else
strcat(fragment_shader, " color2 = color1; \n");
@ -344,16 +360,17 @@ GLSLCombiner::GLSLCombiner(Combiner *_color, Combiner *_alpha) {
#endif
if (gSP.geometryMode & G_FOG)
strcat(fragment_shader, " gl_FragColor = vec4(mix(gl_Fog.color.rgb, gl_FragColor.rgb, gl_FogFragCoord), gl_FragColor.a); \n");
#else
// strcat(fragment_shader, fragment_shader_default);
strcat(fragment_shader, "gl_FragColor = secondary_color; \n");
#endif
strcat(fragment_shader, fragment_shader_end);
strcat(fragment_shader, fragment_shader_calc_light);
#ifdef USE_TOONIFY
strcat(fragment_shader, fragment_shader_toonify);
#endif
strcat(fragment_shader, noise_fragment_shader);
#else // #if 0
// strcat(fragment_shader, fragment_shader_default);
strcat(fragment_shader, "gl_FragColor = secondary_color; \n");
#endif
m_fragmentShaderObject = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
glShaderSourceARB(m_fragmentShaderObject, 1, (const GLcharARB**)&fragment_shader, NULL);
@ -367,6 +384,8 @@ GLSLCombiner::GLSLCombiner(Combiner *_color, Combiner *_alpha) {
glLinkProgramARB(m_programObject);
}
unsigned char btNoiseTime = 0;
void GLSLCombiner::Set() {
combiner.usesT0 = FALSE;
combiner.usesT1 = FALSE;
@ -390,6 +409,8 @@ void GLSLCombiner::Set() {
combiner.usesT1 = TRUE;
}
UpdateColors();
#ifdef _DEBUG
int log_length;
glGetObjectParameterivARB(m_programObject, GL_OBJECT_LINK_STATUS_ARB , &log_length);
@ -425,14 +446,13 @@ void GLSLCombiner::UpdateColors() {
int prim_lod_location = glGetUniformLocationARB(m_programObject, "prim_lod");
glUniform1fARB(prim_lod_location, gDP.primColor.l);
/*
if(dither_enabled)
{
ditherTex_location = glGetUniformLocationARB(program_object, "ditherTex");
glUniform1iARB(ditherTex_location, 2);
if ((m_nInputs & (1<<NOISE)) > 0) {
int time_location = glGetUniformLocationARB(m_programObject, "time");
glUniform1fARB(time_location, ++btNoiseTime);
}
set_lambda();
number_of_programs++;
*/
int nDither = 0;
// int nDither = (gDP.otherMode.colorDither) == 3 ? 1 : 0;
int dither_location = glGetUniformLocationARB(m_programObject, "dither_enabled");
glUniform1iARB(dither_location, nDither);
}

View File

@ -11,6 +11,7 @@ private:
GLhandleARB m_vertexShaderObject;
GLhandleARB m_fragmentShaderObject;
GLhandleARB m_programObject;
int m_nInputs;
};
void InitGLSLCombiner();

80
Noise_shader.h Normal file
View File

@ -0,0 +1,80 @@
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
//
//
"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(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 130.0 * dot(m, g); \n"
"} \n"
" \n"
/*
"varying vec2 v_texCoord2D; \n"
"void main( void ) \n"
"{ \n"
" float n = snoise(v_texCoord2D); \n"
" \n"
" gl_FragColor = vec4(0.5 + 0.5 * vec3(n, n, n), 1.0); \n"
//" vec4 color = vec4(vec3(gl_Color) + 0.5 * vec3(n, n, n), 1.0); \n"
//" gl_FragColor = gl_Color*color; \n"
//" gl_FragColor = color; \n"
"} \n"
*/
;