lights for gles2

This commit is contained in:
aap 2020-05-14 00:07:34 +02:00
parent 0fec15b06b
commit 57634dc46d
13 changed files with 185 additions and 252 deletions

View File

@ -18,29 +18,7 @@ main(void)
v_color = in_color;
v_color.rgb += u_ambLight.rgb*surfAmbient;
#ifdef DIRECTIONALS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_directLights[i].enabled == 0.0)
break;
v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;
}
#endif
#ifdef POINTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_pointLights[i].enabled == 0.0)
break;
v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;
}
#endif
#ifdef SPOTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_spotLights[i].enabled == 0.0)
break;
v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;
}
#endif
v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;
v_color = clamp(v_color, 0.0f, 1.0);
v_color *= u_matColor;

View File

@ -19,29 +19,7 @@ const char *default_vert_src =
" v_color = in_color;\n"
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
"#ifdef DIRECTIONALS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_directLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef POINTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_pointLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef SPOTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_spotLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n"
" v_color = clamp(v_color, 0.0f, 1.0);\n"
" v_color *= u_matColor;\n"

View File

@ -10,22 +10,14 @@ uniform mat4 u_proj;
uniform mat4 u_view;
#define MAX_LIGHTS 8
struct Light {
float enabled;
float radius;
float minusCosAngle;
float hardSpot;
vec4 position;
vec4 direction;
vec4 color;
};
// Object
uniform mat4 u_world;
uniform vec4 u_ambLight;
uniform Light u_directLights[MAX_LIGHTS];
uniform Light u_pointLights[MAX_LIGHTS];
uniform Light u_spotLights[MAX_LIGHTS];
uniform mat4 u_world;
uniform vec4 u_ambLight;
uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot
uniform vec4 u_lightPosition[MAX_LIGHTS];
uniform vec4 u_lightDirection[MAX_LIGHTS];
uniform vec4 u_lightColor[MAX_LIGHTS];
uniform vec4 u_matColor;
uniform vec4 u_surfProps; // amb, spec, diff, extra
@ -34,44 +26,45 @@ uniform vec4 u_surfProps; // amb, spec, diff, extra
#define surfSpecular (u_surfProps.y)
#define surfDiffuse (u_surfProps.z)
vec3 DoDirLight(Light L, vec3 N)
vec3 DoDynamicLight(vec3 V, vec3 N)
{
float l = max(0.0, dot(N, -L.direction.xyz));
return l*L.color.rgb;
}
vec3 DoPointLight(Light L, vec3 V, vec3 N)
{
// As on PS2
vec3 dir = V - L.position.xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/L.radius));
float l = max(0.0, dot(N, -normalize(dir)));
return l*L.color.rgb*atten;
}
vec3 DoSpotLight(Light L, vec3 V, vec3 N)
{
// As on PS2
vec3 dir = V - L.position.xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/L.radius));
dir /= dist;
float l = max(0.0, dot(N, -dir));
float pcos = dot(dir, L.direction.xyz); // cos to point
float ccos = -L.minusCosAngle;
float falloff = (pcos-ccos)/(1.0-ccos);
if(falloff < 0.0) // outside of cone
l = 0.0;
l *= max(falloff, L.hardSpot);
return l*L.color.xyz*atten;
vec3 color = vec3(0.0, 0.0, 0.0);
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_lightParams[i].x == 0.0)
break;
if(u_lightParams[i].x == 1.0){
// direct
float l = max(0.0, dot(N, -u_lightDirection[i].xyz));
color += l*u_lightColor[i].rgb;
/*
}else if(u_lightParams[i].x == 2.0){
// point
vec3 dir = V - u_lightPosition[i].xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));
float l = max(0.0, dot(N, -normalize(dir)));
color += l*u_lightColor[i].rgb*atten;
}else if(u_lightParams[i].x == 3.0){
// spot
vec3 dir = V - u_lightPosition[i].xyz;
float dist = length(dir);
float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));
dir /= dist;
float l = max(0.0, dot(N, -dir));
float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point
float ccos = -u_lightParams[i].z;
float falloff = (pcos-ccos)/(1.0-ccos);
if(falloff < 0.0) // outside of cone
l = 0.0;
l *= max(falloff, u_lightParams[i].w);
return l*u_lightColor[i].rgb*atten;
*/
}
}
return color;
}
float DoFog(float w)
{
return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);
}
#define DIRECTIONALS
//#define POINTLIGHTS
//#define SPOTLIGHTS

View File

@ -11,22 +11,14 @@ const char *header_vert_src =
"uniform mat4 u_view;\n"
"#define MAX_LIGHTS 8\n"
"struct Light {\n"
" float enabled;\n"
" float radius;\n"
" float minusCosAngle;\n"
" float hardSpot;\n"
" vec4 position;\n"
" vec4 direction;\n"
" vec4 color;\n"
"};\n"
"// Object\n"
"uniform mat4 u_world;\n"
"uniform vec4 u_ambLight;\n"
"uniform Light u_directLights[MAX_LIGHTS];\n"
"uniform Light u_pointLights[MAX_LIGHTS];\n"
"uniform Light u_spotLights[MAX_LIGHTS];\n"
"uniform mat4 u_world;\n"
"uniform vec4 u_ambLight;\n"
"uniform vec4 u_lightParams[MAX_LIGHTS]; // type, radius, minusCosAngle, hardSpot\n"
"uniform vec4 u_lightPosition[MAX_LIGHTS];\n"
"uniform vec4 u_lightDirection[MAX_LIGHTS];\n"
"uniform vec4 u_lightColor[MAX_LIGHTS];\n"
"uniform vec4 u_matColor;\n"
"uniform vec4 u_surfProps; // amb, spec, diff, extra\n"
@ -35,45 +27,46 @@ const char *header_vert_src =
"#define surfSpecular (u_surfProps.y)\n"
"#define surfDiffuse (u_surfProps.z)\n"
"vec3 DoDirLight(Light L, vec3 N)\n"
"vec3 DoDynamicLight(vec3 V, vec3 N)\n"
"{\n"
" float l = max(0.0, dot(N, -L.direction.xyz));\n"
" return l*L.color.rgb;\n"
"}\n"
"vec3 DoPointLight(Light L, vec3 V, vec3 N)\n"
"{\n"
" // As on PS2\n"
" vec3 dir = V - L.position.xyz;\n"
" float dist = length(dir);\n"
" float atten = max(0.0, (1.0 - dist/L.radius));\n"
" float l = max(0.0, dot(N, -normalize(dir)));\n"
" return l*L.color.rgb*atten;\n"
"}\n"
"vec3 DoSpotLight(Light L, vec3 V, vec3 N)\n"
"{\n"
" // As on PS2\n"
" vec3 dir = V - L.position.xyz;\n"
" float dist = length(dir);\n"
" float atten = max(0.0, (1.0 - dist/L.radius));\n"
" dir /= dist;\n"
" float l = max(0.0, dot(N, -dir));\n"
" float pcos = dot(dir, L.direction.xyz); // cos to point\n"
" float ccos = -L.minusCosAngle;\n"
" float falloff = (pcos-ccos)/(1.0-ccos);\n"
" if(falloff < 0.0) // outside of cone\n"
" l = 0.0;\n"
" l *= max(falloff, L.hardSpot);\n"
" return l*L.color.xyz*atten;\n"
" vec3 color = vec3(0.0, 0.0, 0.0);\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_lightParams[i].x == 0.0)\n"
" break;\n"
" if(u_lightParams[i].x == 1.0){\n"
" // direct\n"
" float l = max(0.0, dot(N, -u_lightDirection[i].xyz));\n"
" color += l*u_lightColor[i].rgb;\n"
"/*\n"
" }else if(u_lightParams[i].x == 2.0){\n"
" // point\n"
" vec3 dir = V - u_lightPosition[i].xyz;\n"
" float dist = length(dir);\n"
" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n"
" float l = max(0.0, dot(N, -normalize(dir)));\n"
" color += l*u_lightColor[i].rgb*atten;\n"
" }else if(u_lightParams[i].x == 3.0){\n"
" // spot\n"
" vec3 dir = V - u_lightPosition[i].xyz;\n"
" float dist = length(dir);\n"
" float atten = max(0.0, (1.0 - dist/u_lightParams[i].y));\n"
" dir /= dist;\n"
" float l = max(0.0, dot(N, -dir));\n"
" float pcos = dot(dir, u_lightDirection[i].xyz); // cos to point\n"
" float ccos = -u_lightParams[i].z;\n"
" float falloff = (pcos-ccos)/(1.0-ccos);\n"
" if(falloff < 0.0) // outside of cone\n"
" l = 0.0;\n"
" l *= max(falloff, u_lightParams[i].w);\n"
" return l*u_lightColor[i].rgb*atten;\n"
"*/\n"
" }\n"
" }\n"
" return color;\n"
"}\n"
"float DoFog(float w)\n"
"{\n"
" return clamp((w - u_fogEnd)*u_fogRange, u_fogDisable, 1.0);\n"
"}\n"
"#define DIRECTIONALS\n"
"//#define POINTLIGHTS\n"
"//#define SPOTLIGHTS\n"
;

View File

@ -16,10 +16,5 @@ main(void)
v_fog = DoFog(gl_Position.z);
gl_Position.xyz *= gl_Position.w;
v_color = in_color;
//v_color.r = 0.0;
//v_color.g = 0.0;
//v_color.b = 0.0;
//v_color.a = 1.0;
//v_fog = 1.0;
v_tex0 = in_tex0;
}

View File

@ -17,11 +17,6 @@ const char *im2d_vert_src =
" v_fog = DoFog(gl_Position.z);\n"
" gl_Position.xyz *= gl_Position.w;\n"
" v_color = in_color;\n"
"//v_color.r = 0.0;\n"
"//v_color.g = 0.0;\n"
"//v_color.b = 0.0;\n"
"//v_color.a = 1.0;\n"
"//v_fog = 1.0;\n"
" v_tex0 = in_tex0;\n"
"}\n"
;

View File

@ -22,29 +22,7 @@ main(void)
v_color = in_color;
v_color.rgb += u_ambLight.rgb*surfAmbient;
#ifdef DIRECTIONALS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_directLights[i].enabled == 0.0)
break;
v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;
}
#endif
#ifdef POINTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_pointLights[i].enabled == 0.0)
break;
v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;
}
#endif
#ifdef SPOTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_spotLights[i].enabled == 0.0)
break;
v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;
}
#endif
v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;
v_color = clamp(v_color, 0.0f, 1.0);
v_color *= u_matColor;

View File

@ -23,29 +23,7 @@ const char *matfx_env_vert_src =
" v_color = in_color;\n"
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
"#ifdef DIRECTIONALS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_directLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef POINTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_pointLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef SPOTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_spotLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n"
" v_color = clamp(v_color, 0.0f, 1.0);\n"
" v_color *= u_matColor;\n"

View File

@ -25,33 +25,13 @@ main(void)
gl_Position = u_proj * u_view * V;
vec3 N = mat3(u_world) * SkinNormal;
v_tex0 = in_tex0;
v_color = in_color;
v_color.rgb += u_ambLight.rgb*surfAmbient;
#ifdef DIRECTIONALS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_directLights[i].enabled == 0.0)
break;
v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;
}
#endif
#ifdef POINTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_pointLights[i].enabled == 0.0)
break;
v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;
}
#endif
#ifdef SPOTLIGHTS
for(int i = 0; i < MAX_LIGHTS; i++){
if(u_spotLights[i].enabled == 0.0)
break;
v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;
}
#endif
v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;
v_color = clamp(v_color, 0.0f, 1.0);
v_color *= u_matColor;
v_tex0 = in_tex0;
v_fog = DoFog(gl_Position.z);
}

View File

@ -26,34 +26,14 @@ const char *skin_vert_src =
" gl_Position = u_proj * u_view * V;\n"
" vec3 N = mat3(u_world) * SkinNormal;\n"
" v_tex0 = in_tex0;\n"
" v_color = in_color;\n"
" v_color.rgb += u_ambLight.rgb*surfAmbient;\n"
"#ifdef DIRECTIONALS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_directLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoDirLight(u_directLights[i], N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef POINTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_pointLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoPointLight(u_pointLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
"#ifdef SPOTLIGHTS\n"
" for(int i = 0; i < MAX_LIGHTS; i++){\n"
" if(u_spotLights[i].enabled == 0.0)\n"
" break;\n"
" v_color.rgb += DoSpotLight(u_spotLights[i], V.xyz, N)*surfDiffuse;\n"
" }\n"
"#endif\n"
" v_color.rgb += DoDynamicLight(V.xyz, N)*surfDiffuse;\n"
" v_color = clamp(v_color, 0.0f, 1.0);\n"
" v_color *= u_matColor;\n"
" v_tex0 = in_tex0;\n"
" v_fog = DoFog(gl_Position.z);\n"
"}\n"
;

View File

@ -97,6 +97,16 @@ struct UniformObject
UniformLight spotLights[MAX_LIGHTS];
};
struct {
float type;
float radius;
float minusCosAngle;
float hardSpot;
} lightParams[MAX_LIGHTS];
V4d lightPosition[MAX_LIGHTS];
V4d lightDirection[MAX_LIGHTS];
RGBAf lightColor[MAX_LIGHTS];
const char *shaderDecl330 = "#version 330\n";
const char *shaderDecl100es =
"#version 100\n"\
@ -140,7 +150,10 @@ int32 u_view;
// Object
int32 u_world;
int32 u_ambLight;
// TODO: lights!
int32 u_lightParams;
int32 u_lightPosition;
int32 u_lightDirection;
int32 u_lightColor;
#endif
int32 u_matColor;
@ -681,6 +694,7 @@ setWorldMatrix(Matrix *mat)
int32
setLights(WorldLights *lightData)
{
#ifndef RW_GLES2
int i, np, ns;
Light *l;
int32 bits;
@ -735,9 +749,70 @@ setLights(WorldLights *lightData)
break;
}
}
#else
int i, n;
Light *l;
int32 bits;
uniformObject.ambLight = lightData->ambient;
bits = 0;
if(lightData->numAmbients)
bits |= VSLIGHT_AMBIENT;
n = 0;
for(i = 0; i < lightData->numDirectionals && i < 8; i++){
l = lightData->directionals[i];
lightParams[n].type = 1.0f;
lightColor[n] = l->color;
memcpy(&lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d));
bits |= VSLIGHT_POINT;
n++;
if(n >= MAX_LIGHTS)
goto out;
}
for(i = 0; i < lightData->numLocals; i++){
Light *l = lightData->locals[i];
switch(l->getType()){
case Light::POINT:
lightParams[n].type = 2.0f;
lightParams[n].radius = l->radius;
lightColor[n] = l->color;
memcpy(&lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d));
bits |= VSLIGHT_POINT;
n++;
if(n >= MAX_LIGHTS)
goto out;
break;
case Light::SPOT:
case Light::SOFTSPOT:
lightParams[n].type = 3.0f;
lightParams[n].minusCosAngle = l->minusCosAngle;
lightParams[n].radius = l->radius;
lightColor[n] = l->color;
memcpy(&lightPosition[n], &l->getFrame()->getLTM()->pos, sizeof(V3d));
memcpy(&lightDirection[n], &l->getFrame()->getLTM()->at, sizeof(V3d));
// lower bound of falloff
if(l->getType() == Light::SOFTSPOT)
lightParams[n].hardSpot = 0.0f;
else
lightParams[n].hardSpot = 1.0f;
bits |= VSLIGHT_SPOT;
n++;
if(n >= MAX_LIGHTS)
goto out;
break;
}
}
lightParams[n].type = 0.0f;
out:
#endif
objectDirty = 1;
return 0;
return bits;
}
void
@ -773,7 +848,10 @@ flushCache(void)
if(objectDirty){
glUniformMatrix4fv(U(u_world), 1, 0, (float*)&uniformObject.world);
glUniform4fv(U(u_ambLight), 1, (float*)&uniformObject.ambLight);
// TODO: lights somehow
glUniform4fv(U(u_lightParams), MAX_LIGHTS, (float*)lightParams);
glUniform4fv(U(u_lightPosition), MAX_LIGHTS, (float*)lightPosition);
glUniform4fv(U(u_lightDirection), MAX_LIGHTS, (float*)lightDirection);
glUniform4fv(U(u_lightColor), MAX_LIGHTS, (float*)lightColor);
objectDirty = 0;
}
@ -1216,6 +1294,10 @@ initOpenGL(void)
u_view = registerUniform("u_view");
u_world = registerUniform("u_world");
u_ambLight = registerUniform("u_ambLight");
u_lightParams = registerUniform("u_lightParams");
u_lightPosition = registerUniform("u_lightPosition");
u_lightDirection = registerUniform("u_lightDirection");
u_lightColor = registerUniform("u_lightColor");
lastShaderUploaded = nil;
#else
registerBlock("Scene");

View File

@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "../rwbase.h"
#include "../rwerror.h"
@ -31,8 +32,10 @@ registerUniform(const char *name)
i = findUniform(name);
if(i >= 0) return i;
// TODO: print error
if(uniformRegistry.numUniforms+1 >= MAX_UNIFORMS)
if(uniformRegistry.numUniforms+1 >= MAX_UNIFORMS){
assert(0 && "no space for uniform");
return -1;
}
uniformRegistry.uniformNames[uniformRegistry.numUniforms] = strdup(name);
return uniformRegistry.numUniforms++;
}
@ -199,7 +202,7 @@ Shader::create(const char **vsrc, const char **fsrc)
printf("\n");
#endif
#ifdef xxxRW_GLES2
#ifdef RW_GLES2
int numAttribs;
glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &numAttribs);
for(i = 0; i < numAttribs; i++){

View File

@ -5,7 +5,7 @@ namespace gl3 {
// TODO: make this dynamic
enum {
MAX_UNIFORMS = 20,
MAX_UNIFORMS = 40,
MAX_BLOCKS = 20
};