forked from Mirrors/openclonk
Shiny materials, shader reorganisation
This implements the proposal made in the forum for "shiny" materials - material can now determine the angle at which the most light is reflected. Shiny materials might set this lower to approximate a "reflection" effect, and increase the "spottiness" at the same time. To compensate for the lack of brightness without light, "emittance" can be used. Not sure this is the most elegant way to model this - the "proper" way here would be to have emittance, shading and specular as three separate light parameters instead of molding one into the other and using the third to compensate. Furthermore, this reorganises shaders in a major way: We reduce the number of shader files down to three, pushing a number of possible configurations into preprocessor. I believe this should be easier to understand, which for the moment trumps theoretical extensibility benefits.shapetextures
parent
f0030e33e0
commit
cf4ed1b0b7
|
@ -1,52 +0,0 @@
|
|||
|
||||
// Ambient light calculation
|
||||
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
uniform sampler2D ambientTex;
|
||||
|
||||
uniform mat3x2 ambientTransform;
|
||||
uniform float ambientBrightness;
|
||||
#endif
|
||||
//uniform float cullMode; // 0 if backface culling is enabled, 1 if it is disabled
|
||||
// Already declared in LightShader.glsl
|
||||
|
||||
slice(texture+6)
|
||||
{
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
// Ambient light
|
||||
// Extra .xy since some old intel drivers return a vec3
|
||||
float ambient = texture2D(ambientTex, (ambientTransform * vec3(gl_FragCoord.xy, 1.0)).xy).r * ambientBrightness;
|
||||
#else
|
||||
// Lighting disabled: Ambient light everywhere
|
||||
float ambient = 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(light+1)
|
||||
{
|
||||
// Add ambience to brightness
|
||||
#ifdef OC_LANDSCAPE
|
||||
// For landscape, ambient brightness is coming from top
|
||||
vec3 ambientDir = vec3(0.0, -1.0, 0.0);
|
||||
light = mix(light, 1.0 + 1.0 * dot(normal, ambientDir), ambient);
|
||||
#ifdef OC_HAVE_2PX
|
||||
light2 = mix(light2, 1.0 + 1.0 * dot(normal2, ambientDir), ambient);
|
||||
#endif
|
||||
#else
|
||||
#ifdef OC_SKY
|
||||
// For sky, ambient brightness is coming from the front
|
||||
vec3 ambientDir = vec3(0.0, 0.0, 1.0);
|
||||
light = mix(light, max(max(dot(normal, ambientDir), 0.0), cullMode * max(dot(-normal, ambientDir), 0.0)), ambient);
|
||||
#else
|
||||
// For objects, ambient brightness is coming from the sky
|
||||
vec3 ambientDir = normalize(vec3(0.5, -0.5, 0.5));
|
||||
float ambientLight = max(dot(normal, ambientDir), 0.8);
|
||||
// Also, objects do have a rimlight
|
||||
vec3 rimDir = vec3(0.0, 0.0, 1.0);
|
||||
float rimLight = 1.0 - dot(normal, rimDir);
|
||||
ambientLight += ambientLight * rimLight;
|
||||
|
||||
light = mix(light, ambientLight, ambient);
|
||||
#endif
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
|
||||
// uncomment the following lines for debugging light directions:
|
||||
// yellow: light up, blue: light down, turqoise: light right, pink: light left
|
||||
// brightness: light strength
|
||||
//#define LIGHT_DEBUG
|
||||
|
||||
// uncomment the following lines for debugging light color:
|
||||
// the light will always come from the front and have a uniform brightness.
|
||||
//#define LIGHT_DEBUG_COLOR
|
||||
|
||||
// uncomment the following lines to set the light color to pink for all lights for debugging:
|
||||
//#define LIGHT_DEBUG_PINK
|
||||
|
||||
// At what point of light intensity we set the "darkness" point. This
|
||||
// is to compensate for the fact that the engine "smoothes" the light
|
||||
// and therefore will often never arrive at 0 light intensity.
|
||||
const float lightDarknessLevel = 8.0 / 256.0;
|
||||
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
uniform sampler2D ambientTex;
|
||||
|
||||
uniform mat3x2 ambientTransform;
|
||||
uniform float ambientBrightness;
|
||||
|
||||
uniform sampler2D lightTex;
|
||||
#endif
|
||||
|
||||
// Gamma uniforms
|
||||
uniform vec3 gamma;
|
||||
|
||||
// 0 if backface culling is enabled, 1 if it is disabled
|
||||
uniform float cullMode;
|
||||
|
||||
// Light dot product, taking cull mode into account
|
||||
float lightDot(vec3 normal, vec3 lightDir) {
|
||||
return abs(max(-cullMode, dot(normalize(normal), lightDir)));
|
||||
}
|
||||
|
||||
vec3 extend_normal(vec2 v)
|
||||
{
|
||||
// the higher the second value, the further away the light source from the landscape
|
||||
return normalize(vec3(v, 0.45));
|
||||
}
|
||||
|
||||
// Converts the pixel range 0.0..1.0 into the integer range 0..255
|
||||
int f2i(float x) {
|
||||
return int(x * 255.9);
|
||||
}
|
||||
|
||||
slice(texture+5)
|
||||
{
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
|
||||
// Query light texture
|
||||
vec2 lightDirCoord = lightCoord.st;
|
||||
|
||||
vec4 lightPx = texture2D(lightTex, lightDirCoord);
|
||||
float lightBright = 2.0*max(0.0, lightPx.a-lightDarknessLevel);
|
||||
vec3 lightDir = extend_normal(vec2(1.0, 1.0) - lightPx.yz * 3.0);
|
||||
|
||||
// Query light color texture (part of the light texture)
|
||||
vec2 lightColorCoord = lightCoord.st - vec2(0.0, 0.5); // subtract offset for the color texture
|
||||
|
||||
vec3 lightColor = texture2D(lightTex, lightColorCoord.st).rgb;
|
||||
|
||||
// Normalise light colour
|
||||
#ifdef LIGHT_DEBUG_COLOR
|
||||
lightBright = 0.5;
|
||||
lightColor = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
#endif
|
||||
#else
|
||||
// When lighting is disabled, put a light source coming from the camera.
|
||||
// Note that in most cases this does not actually matter, since in the
|
||||
// case with lighting disabled, ambient lighting takes fully over.
|
||||
float lightBright = 0.5;
|
||||
vec3 lightDir = vec3(0.0, 0.0, 1.0);
|
||||
vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
#endif
|
||||
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
// Ambient light
|
||||
// Extra .xy since some old intel drivers return a vec3
|
||||
float ambient = texture2D(ambientTex, (ambientTransform * vec3(gl_FragCoord.xy, 1.0)).xy).r * ambientBrightness;
|
||||
#else
|
||||
// Lighting disabled: Ambient light everywhere
|
||||
float ambient = 1.0;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(light)
|
||||
{
|
||||
|
||||
// Light dot product, taking backface culling into account
|
||||
normal = normalize(normal);
|
||||
float light = lightDot(normal, lightDir);
|
||||
// Amount of reflection, depending on the angle where material reflects most
|
||||
light = min(light / matAngle, 2.0 - light / matAngle);
|
||||
|
||||
#ifdef OC_LANDSCAPE
|
||||
normal2 = normalize(normal2);
|
||||
float light2 = lightDot(normal2, lightDir);
|
||||
light2 = min(light2 / matAngle2, 2.0 - light2 / matAngle2);
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(light+1)
|
||||
{
|
||||
#ifdef OC_LANDSCAPE
|
||||
// For landscape, ambient brightness is coming from top
|
||||
vec3 ambientDir = normalize(vec3(0.0, -1.0, 1.0));
|
||||
#else
|
||||
// For objects, ambient brightness is coming from the front
|
||||
vec3 ambientDir = vec3(0.0, 0.0, 1.0);
|
||||
#endif
|
||||
// Add ambience to brightness
|
||||
lightBright = mix(lightBright, 1.0, ambient);
|
||||
light = mix(light, 0.5 * (ambient + lightDot(normal, ambientDir)), ambient);
|
||||
#ifdef OC_LANDSCAPE
|
||||
light2 = mix(light2, 0.5 * (ambient + lightDot(normal2, ambientDir)), ambient);
|
||||
#endif
|
||||
lightColor = mix(lightColor, vec3(1.0,1.0,1.0), ambient);
|
||||
}
|
||||
|
||||
slice(color+5)
|
||||
{
|
||||
// Normalize light colour
|
||||
vec3 lightColorNorm = sqrt(3.0) * normalize(lightColor);
|
||||
|
||||
// Add light. Depending on material properties, we make it more
|
||||
// "spotty" and allow the material to self-illuminate. The light
|
||||
// brightness overrules everything though (= FoW is last factor).
|
||||
vec3 spotLight = pow(vec3(light,light,light), matSpot);
|
||||
color.rgb = lightBright * color.rgb * (matEmit + lightColorNorm * spotLight);
|
||||
#ifdef OC_LANDSCAPE
|
||||
vec3 spotLight2 = pow(vec3(light2,light2,light2), matSpot2);
|
||||
color2.rgb = lightBright * color2.rgb * (matEmit2 + lightColorNorm * spotLight2);
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(finish+5)
|
||||
{
|
||||
|
||||
#ifdef LIGHT_DEBUG
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
float lightYDir = lightPx.b - 1.0/3.0;
|
||||
float lightXDir = lightPx.g - 1.0/3.0;
|
||||
float lightStrength = lightPx.a;
|
||||
color =
|
||||
vec4(lightStrength * vec3(1.0-1.5*(max(0.0, lightYDir) + max(0.0,lightXDir)),
|
||||
1.0-1.5*(max(0.0, lightYDir) + max(0.0,-lightXDir)),
|
||||
1.0-1.5*max(0.0, -lightYDir)),
|
||||
1.0);
|
||||
#else
|
||||
color = vec4(0.0, 0.0, 0.0, 0.0); // invisible
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
slice(finish+10) {
|
||||
color = vec4(pow(color.rgb, gamma), color.a);
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
|
||||
// Gamma uniforms
|
||||
uniform vec3 gamma;
|
||||
|
||||
slice(finish+10) {
|
||||
color = vec4(pow(color.rgb, gamma), color.a);
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
|
||||
// Input textures
|
||||
uniform sampler2D landscapeTex[2];
|
||||
uniform sampler2D scalerTex;
|
||||
|
@ -11,11 +10,7 @@ uniform vec2 resolution;
|
|||
// Center position
|
||||
uniform vec2 center;
|
||||
// Texture map
|
||||
#ifndef NO_BROKEN_ARRAYS_WORKAROUND
|
||||
uniform sampler1D matMapTex;
|
||||
#else
|
||||
uniform float matMap[256];
|
||||
#endif
|
||||
uniform float materialDepth;
|
||||
uniform vec2 materialSize;
|
||||
|
||||
|
@ -25,21 +20,15 @@ const vec2 scalerStepY = vec2(0.0, 1.0 / 32.0);
|
|||
const vec2 scalerOffset = scalerStepX / 3.0 + scalerStepY / 3.0;
|
||||
const vec2 scalerPixel = vec2(scalerStepX.x, scalerStepY.y) / 3.0;
|
||||
|
||||
// Parameters
|
||||
// How much % the normals from the normal map are added up to the
|
||||
// landscape normal. The higher the strength, the more structure
|
||||
// within the material is visible but also the less the borders
|
||||
// between the different materials stand out.
|
||||
const float normalMapStrength = 0.20;
|
||||
|
||||
// how much % the normals from the normal map are added up to the landscape normal. The higher the strength, the more
|
||||
// structure within the material is visible but also the less the borders between the different materials stand out.
|
||||
const float normalMapStrength = 0.75;
|
||||
|
||||
float queryMatMap(int pix)
|
||||
vec4 queryMatMap(int pix)
|
||||
{
|
||||
#ifndef NO_BROKEN_ARRAYS_WORKAROUND
|
||||
int idx = f2i(texture1D(matMapTex, float(pix) / 256.0 + 0.5 / 256.0).r);
|
||||
return (float(idx) / 256.0 + 0.0 / materialDepth) * materialDepth;
|
||||
//return texture1D(matMapTex, float(pix) / 256.0 + 0.5 / 256.0).r;
|
||||
#else
|
||||
return matMap[pix] * materialDepth;
|
||||
#endif
|
||||
return texture1D(matMapTex, float(pix) / 2.0 / 256.0 + 0.5 / 2.0 / 256.0);
|
||||
}
|
||||
|
||||
slice(coordinate)
|
||||
|
@ -64,44 +53,74 @@ slice(texture)
|
|||
// our pixel color (without/with interpolation)
|
||||
vec4 landscapePx = texture2D(landscapeTex[0], centerCoo);
|
||||
vec4 realLandscapePx = texture2D(landscapeTex[0], texCoo);
|
||||
|
||||
// find scaler coordinate
|
||||
vec2 scalerCoo = scalerOffset + mod(pixelCoo, vec2(1.0, 1.0)) * scalerPixel;
|
||||
int iScaler = f2i(landscapePx.a), iRow = iScaler / 8;
|
||||
scalerCoo.x += float(iScaler - iRow * 8) / 8.0;
|
||||
scalerCoo.y += float(iScaler / 8) / 32.0;
|
||||
|
||||
// query scaler texture
|
||||
vec4 scalerPx = texture2D(scalerTex, scalerCoo);
|
||||
|
||||
// Get "second" landscape pixel
|
||||
vec2 centerCoo2 = centerCoo + fullStep * floor(vec2(-0.5, -0.5) +
|
||||
scalerPx.gb * 255.0 / 64.0);
|
||||
vec4 landscapePx2 = texture2D(landscapeTex[0], centerCoo2);
|
||||
|
||||
}
|
||||
|
||||
slice(material)
|
||||
{
|
||||
|
||||
// Get material pixels
|
||||
float materialIx = queryMatMap(f2i(landscapePx.r));
|
||||
vec4 materialPx = texture(materialTex, vec3(materialCoo, materialIx));
|
||||
vec4 normalPx = texture(materialTex, vec3(materialCoo, materialIx+0.5*materialDepth));
|
||||
// Get material properties from material map
|
||||
int matMapIx = f2i(landscapePx.r);
|
||||
vec4 matMap = queryMatMap(2*matMapIx);
|
||||
vec4 matMapX = queryMatMap(2*matMapIx+1);
|
||||
float materialIx = f2i(matMap.a) / 256.0 * materialDepth;
|
||||
vec3 matEmit = matMap.rgb;
|
||||
vec3 matSpot = matMapX.rgb * 255.9f / 16.0f;
|
||||
float matAngle = matMapX.a;
|
||||
|
||||
// Same for second pixel, but we'll simply use the first normal
|
||||
#ifdef OC_HAVE_2PX
|
||||
float materialIx2 = queryMatMap(f2i(landscapePx2.r));
|
||||
// Query material texture pixels
|
||||
vec4 materialPx = texture(materialTex, vec3(materialCoo, materialIx));
|
||||
vec4 normalPx = texture(materialTex, vec3(materialCoo, materialIx+0.5 * materialDepth));
|
||||
|
||||
// Same for second pixel
|
||||
int matMapIx2 = f2i(landscapePx2.r);
|
||||
vec4 matMap2 = queryMatMap(2*matMapIx2);
|
||||
vec4 matMapX2 = queryMatMap(2*matMapIx2+1);
|
||||
float materialIx2 = f2i(matMap2.a) / 256.0 * materialDepth;
|
||||
vec3 matEmit2 = matMap2.rgb;
|
||||
vec3 matSpot2 = matMapX2.rgb * 255.9f / 16.0f;
|
||||
float matAngle2 = matMapX2.a;
|
||||
|
||||
// Query material texture pixels
|
||||
vec4 materialPx2 = texture(materialTex, vec3(materialCoo, materialIx2));
|
||||
vec4 normalPx2 = texture(materialTex, vec3(materialCoo, materialIx2+0.5*materialDepth));
|
||||
#endif
|
||||
vec4 normalPx2 = texture(materialTex, vec3(materialCoo, materialIx2+0.5 * materialDepth));
|
||||
}
|
||||
|
||||
slice(normal)
|
||||
{
|
||||
// Normal calculation
|
||||
vec3 normal = extend_normal(mix(realLandscapePx.yz, landscapePx.yz, scalerPx.a)
|
||||
- vec2(0.5, 0.5));
|
||||
vec3 normal = extend_normal(1.5 * (mix(realLandscapePx.yz, landscapePx.yz, scalerPx.a)
|
||||
- vec2(0.5, 0.5)));
|
||||
vec3 textureNormal = normalPx.xyz - vec3(0.5,0.5,0.5);
|
||||
normal = normal + textureNormal * normalMapStrength;
|
||||
normal = mix(textureNormal, normal, normalMapStrength);
|
||||
|
||||
#ifdef OC_HAVE_2PX
|
||||
vec3 normal2 = extend_normal(landscapePx2.yz - vec2(0.5, 0.5));
|
||||
vec3 textureNormal2 = normalPx2.xyz - vec3(0.5,0.5,0.5);
|
||||
normal2 = normal2 + textureNormal2 * normalMapStrength;
|
||||
#endif
|
||||
normal2 = mix(textureNormal2, normal2, normalMapStrength);
|
||||
|
||||
}
|
||||
|
||||
slice(color) {
|
||||
#define color gl_FragColor
|
||||
color = materialPx;
|
||||
#ifdef OC_HAVE_2PX
|
||||
vec4 color2 = materialPx2;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(color+10) {
|
||||
// Mix second color into main color according to scaler
|
||||
color = mix(color2, color, scalerPx.r);
|
||||
}
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
|
||||
// Base light calculations
|
||||
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
uniform sampler2D lightTex;
|
||||
#endif
|
||||
uniform float cullMode; // 0 if backface culling is enabled, 1 if it is disabled
|
||||
|
||||
// uncomment the following lines for debugging light directions:
|
||||
// yellow: light up, blue: light down, turqoise: light right, pink: light left
|
||||
// brightness: light strength
|
||||
//#define LIGHT_DEBUG
|
||||
|
||||
// uncomment the following lines for debugging light color:
|
||||
// the light will always come from the front and have a uniform brightness.
|
||||
//#define LIGHT_DEBUG_COLOR
|
||||
|
||||
// uncomment the following lines to set the light color to pink for all lights for debugging:
|
||||
//#define LIGHT_DEBUG_PINK
|
||||
|
||||
// At what point of light intensity we set the "darkness" point. This
|
||||
// is to compensate for the fact that the engine "smoothes" the light
|
||||
// and therefore will often never arrive at 0 light intensity.
|
||||
const float lightDarknessLevel = 8.0 / 256.0;
|
||||
|
||||
slice(texture+5)
|
||||
{
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
|
||||
// Query light texture
|
||||
vec2 lightDirCoord = lightCoord.st;
|
||||
|
||||
vec4 lightPx = texture2D(lightTex, lightDirCoord);
|
||||
float lightBright = max(0.0, lightPx.a-lightDarknessLevel);
|
||||
vec3 lightDir = extend_normal(vec2(1.0, 1.0) - lightPx.yz * 3.0);
|
||||
|
||||
// Query light color texture (part of the light texture)
|
||||
vec2 lightColorCoord = lightCoord.st - vec2(0.0, 0.5); // subtract offset for the color texture
|
||||
|
||||
vec4 lightColor = texture2D(lightTex, lightColorCoord.st);
|
||||
|
||||
#ifdef LIGHT_DEBUG_COLOR
|
||||
lightBright = 0.5;
|
||||
lightDir = vec3(0.0, 0.0, 1.0);
|
||||
#endif
|
||||
#else
|
||||
// When lighting is disabled, put a light source coming from the camera.
|
||||
// Note that in most cases this does not actually matter, since in the
|
||||
// case with lighting disabled, ambient lighting takes fully over.
|
||||
float lightBright = 0.5;
|
||||
vec3 lightDir = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
vec4 lightColor = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(light)
|
||||
{
|
||||
float light = 2.0 * lightBright * max(max(dot(normal, lightDir), 0.0), cullMode * max(dot(-normal, lightDir), 0.0));
|
||||
#ifdef OC_HAVE_2PX
|
||||
float light2 = 2.0 * lightBright * max(max(dot(normal2, lightDir), 0.0), cullMode * max(dot(-normal2, lightDir), 0.0));
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(color+5)
|
||||
{
|
||||
// pink shade for debugging!
|
||||
#ifdef LIGHT_DEBUG_PINK
|
||||
lightColor = vec4(1.0, 0.0, 1.0, 1.0);
|
||||
#endif
|
||||
|
||||
lightColor.rgb = sqrt(3.0) * normalize(lightColor.rgb);
|
||||
|
||||
// Add light
|
||||
color.rgb = light * color.rgb * lightColor.rgb;
|
||||
#ifdef OC_HAVE_2PX
|
||||
color2.rgb = light2 * color2.rgb * lightColor.rgb;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(finish+5)
|
||||
{
|
||||
|
||||
#ifdef LIGHT_DEBUG
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
float lightYDir = lightPx.b - 1.0/3.0;
|
||||
float lightXDir = lightPx.g - 1.0/3.0;
|
||||
float lightStrength = lightPx.a;
|
||||
color =
|
||||
vec4(lightStrength * vec3(1.0-1.5*(max(0.0, lightYDir) + max(0.0,lightXDir)),
|
||||
1.0-1.5*(max(0.0, lightYDir) + max(0.0,-lightXDir)),
|
||||
1.0-1.5*max(0.0, -lightYDir)),
|
||||
1.0);
|
||||
#else
|
||||
color = vec4(0.0, 0.0, 0.0, 0.0); // invisible
|
||||
#endif
|
||||
#endif
|
||||
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
uniform vec4 clrMod;
|
||||
|
||||
slice(init)
|
||||
{
|
||||
#define color gl_FragColor
|
||||
|
||||
#ifdef OC_MESH
|
||||
// TODO: Add emission part of the material. Note we cannot just
|
||||
// add this to the color, but it would need to be handled separately,
|
||||
// such that it is independent from the incident light direction.
|
||||
color = gl_FrontMaterial.diffuse;
|
||||
#else
|
||||
vec4 baseColor = gl_Color;
|
||||
color = baseColor;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
slice(color)
|
||||
{
|
||||
// TODO: Instead of a conditional, we could compute the color as
|
||||
// color = A + B*color + C*clrMod + D*color*clrMod;
|
||||
// Then, mod2 would be A=-0.5, B=1, C=1, D=0
|
||||
// and default would be A=0,B=0,C=0,D=1
|
||||
// Would allow to avoid conditionsals and #ifdefs, but need 4 uniforms...
|
||||
|
||||
// Could also try some sort of 3x3 matrix:
|
||||
// out = (color, clrmod, 1) * (A,B,C,D,E,F,0,0,G) * (color, clrmod, 1)
|
||||
|
||||
#ifdef OC_CLRMOD_MOD2
|
||||
color = clamp(color + clrMod - 0.5, 0.0, 1.0);
|
||||
#else
|
||||
color = color * clrMod;
|
||||
#endif
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
uniform mat3x2 lightTransform;
|
||||
#ifdef OC_WITH_NORMALMAP
|
||||
uniform sampler2D normalTex;
|
||||
#endif
|
||||
|
||||
#ifdef OC_MESH
|
||||
varying vec3 normalDir;
|
||||
#endif
|
||||
|
||||
slice(texture+4)
|
||||
{
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
// prepare texture coordinate for light lookup in LightShader.c
|
||||
// Extra .xy since some old intel drivers return a vec3
|
||||
vec2 lightCoord = (lightTransform * vec3(gl_FragCoord.xy, 1.0)).xy;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(normal)
|
||||
{
|
||||
#ifdef OC_WITH_NORMALMAP
|
||||
vec4 normalPx = texture2D(normalTex, texcoord.xy);
|
||||
vec3 normalPxDir = 2.0 * (normalPx.xyz - vec3(0.5, 0.5, 0.5));
|
||||
vec3 normal = normalize(gl_NormalMatrix * normalPxDir);
|
||||
#else
|
||||
#ifdef OC_MESH
|
||||
vec3 normal = normalDir; // Normal matrix is already applied in vertex shader
|
||||
#else
|
||||
vec3 normal = vec3(0.0, 0.0, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
|
||||
uniform mat3x2 lightTransform;
|
||||
|
||||
#ifdef OC_WITH_NORMALMAP
|
||||
uniform sampler2D normalTex;
|
||||
#endif
|
||||
|
||||
#ifdef OC_MESH
|
||||
varying vec3 normalDir;
|
||||
#endif
|
||||
|
||||
uniform vec4 clrMod;
|
||||
|
||||
#ifdef OC_HAVE_BASE
|
||||
uniform sampler2D baseTex;
|
||||
#endif
|
||||
|
||||
#ifdef OC_HAVE_OVERLAY
|
||||
uniform vec4 overlayClr;
|
||||
uniform sampler2D overlayTex;
|
||||
#endif
|
||||
|
||||
slice(material)
|
||||
{
|
||||
// Default material properties. TODO: Populate them?
|
||||
vec3 matEmit = vec3(0.0,0.0,0.0);
|
||||
vec3 matSpot = vec3(1.0,1.0,1.0);
|
||||
float matAngle = 1.0;
|
||||
}
|
||||
|
||||
slice(texture)
|
||||
{
|
||||
#define color gl_FragColor
|
||||
|
||||
#ifdef OC_MESH
|
||||
// TODO: Add emission part of the material. Note we cannot just
|
||||
// add this to the color, but it would need to be handled separately,
|
||||
// such that it is independent from the incident light direction.
|
||||
color = gl_FrontMaterial.diffuse;
|
||||
#else
|
||||
vec4 baseColor = gl_Color;
|
||||
color = baseColor;
|
||||
#endif
|
||||
|
||||
#ifdef OC_HAVE_BASE
|
||||
color = baseColor * texture2D(baseTex, texcoord.xy);
|
||||
#endif
|
||||
|
||||
#ifdef OC_HAVE_OVERLAY
|
||||
// Get overlay color from overlay texture
|
||||
vec4 overlay = baseColor * overlayClr * texture2D(overlayTex, texcoord.xy);
|
||||
// Mix overlay with texture
|
||||
float alpha0 = 1.0 - (1.0 - color.a) * (1.0 - overlay.a);
|
||||
color = vec4(mix(color.rgb, overlay.rgb, overlay.a / alpha0), alpha0);
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(texture+4)
|
||||
{
|
||||
#ifdef OC_DYNAMIC_LIGHT
|
||||
// prepare texture coordinate for light lookup in LightShader.c
|
||||
// Extra .xy since some old intel drivers return a vec3
|
||||
vec2 lightCoord = (lightTransform * vec3(gl_FragCoord.xy, 1.0)).xy;
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(normal)
|
||||
{
|
||||
#ifdef OC_WITH_NORMALMAP
|
||||
vec4 normalPx = texture2D(normalTex, texcoord.xy);
|
||||
vec3 normalPxDir = 2.0 * (normalPx.xyz - vec3(0.5, 0.5, 0.5));
|
||||
#ifdef OC_MESH
|
||||
// For meshes, the normal matrix is typically provided in Clonk
|
||||
// coordinates, but the normal matrix incorporates a component that
|
||||
// transforms from Ogre to Clonk coordinates. Therefore, we need to
|
||||
// reverse that transformation for meshes.
|
||||
// TODO: This could be optimized since the matrix is so simple that
|
||||
// we don't need to do a full matrix multiplication.
|
||||
mat3 c2o = mat3(0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0);
|
||||
vec3 normal = normalize(c2o * gl_NormalMatrix * normalPxDir);
|
||||
#else
|
||||
vec3 normal = normalize(gl_NormalMatrix * normalPxDir);
|
||||
#endif
|
||||
#else
|
||||
#ifdef OC_MESH
|
||||
vec3 normal = normalDir; // Normal matrix is already applied in vertex shader
|
||||
#else
|
||||
vec3 normal = vec3(0.0, 0.0, 1.0);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
slice(color)
|
||||
{
|
||||
// TODO: Instead of a conditional, we could compute the color as
|
||||
// color = A + B*color + C*clrMod + D*color*clrMod;
|
||||
// Then, mod2 would be A=-0.5, B=1, C=1, D=0
|
||||
// and default would be A=0,B=0,C=0,D=1
|
||||
// Would allow to avoid conditionsals and #ifdefs, but need 4 uniforms...
|
||||
|
||||
// Could also try some sort of 3x3 matrix:
|
||||
// out = (color, clrmod, 1) * (A,B,C,D,E,F,0,0,G) * (color, clrmod, 1)
|
||||
|
||||
#ifdef OC_CLRMOD_MOD2
|
||||
color = clamp(color + clrMod - 0.5, 0.0, 1.0);
|
||||
#else
|
||||
color = color * clrMod;
|
||||
#endif
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
|
||||
#define OC_HAVE_2PX
|
||||
|
||||
slice(texture+5)
|
||||
{
|
||||
// find scaler coordinate
|
||||
vec2 scalerCoo = scalerOffset + mod(pixelCoo, vec2(1.0, 1.0)) * scalerPixel;
|
||||
|
||||
#ifdef SCALER_IN_GPU
|
||||
if(texture2D(landscapeTex[0], centerCoo - fullStepX - fullStepY).r == landscapePx.r)
|
||||
scalerCoo += scalerStepX;
|
||||
if(texture2D(landscapeTex[0], centerCoo - fullStepY).r == landscapePx.r)
|
||||
scalerCoo += 2.0 * scalerStepX;
|
||||
if(texture2D(landscapeTex[0], centerCoo + fullStepX - fullStepY).r == landscapePx.r)
|
||||
scalerCoo += 4.0 * scalerStepX;
|
||||
|
||||
if(texture2D(landscapeTex[0], centerCoo - fullStepX ).r == landscapePx.r)
|
||||
scalerCoo += scalerStepY;
|
||||
if(texture2D(landscapeTex[0], centerCoo + fullStepX ).r == landscapePx.r)
|
||||
scalerCoo += 2.0 * scalerStepY;
|
||||
|
||||
if(texture2D(landscapeTex[0], centerCoo - fullStepX + fullStepY).r == landscapePx.r)
|
||||
scalerCoo += 4.0 * scalerStepY;
|
||||
if(texture2D(landscapeTex[0], centerCoo + fullStepY).r == landscapePx.r)
|
||||
scalerCoo += 8.0 * scalerStepY;
|
||||
if(texture2D(landscapeTex[0], centerCoo + fullStepX + fullStepY).r == landscapePx.r)
|
||||
scalerCoo += 16.0 * scalerStepY;
|
||||
#else
|
||||
int iScaler = f2i(landscapePx.a), iRow = iScaler / 8;
|
||||
scalerCoo.x += float(iScaler - iRow * 8) / 8.0;
|
||||
scalerCoo.y += float(iScaler / 8) / 32.0;
|
||||
#endif
|
||||
|
||||
// Note: scalerCoo will jump around a lot, causing some GPUs to
|
||||
// apparantly get confused with the level-of-detail
|
||||
// calculation. We therefore try to disable LOD.
|
||||
vec4 scalerPx = texture2DLod(scalerTex, scalerCoo, 0.0);
|
||||
|
||||
// gen3 other coordinate calculation. Still struggles a bit with 3-ways
|
||||
vec2 centerCoo2 = centerCoo + fullStep * floor(vec2(-0.5, -0.5) +
|
||||
scalerPx.gb * 255.0 / 64.0);
|
||||
vec4 landscapePx2 = texture2D(landscapeTex[0], centerCoo2);
|
||||
|
||||
}
|
||||
|
||||
slice(color+10) {
|
||||
// Mix second color into main color according to scaler
|
||||
color = mix(color2, color, scalerPx.r);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
uniform vec4 overlayClr;
|
||||
uniform sampler2D overlayTex;
|
||||
|
||||
slice(texture+1)
|
||||
{
|
||||
// Get overlay color from overlay texture
|
||||
vec4 overlay = baseColor * overlayClr * texture2D(overlayTex, texcoord.xy);
|
||||
// Mix overlay with texture
|
||||
float alpha0 = 1.0 - (1.0 - color.a) * (1.0 - overlay.a);
|
||||
color = vec4(mix(color.rgb, overlay.rgb, overlay.a / alpha0), alpha0);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
uniform sampler2D baseTex;
|
||||
|
||||
slice(texture)
|
||||
{
|
||||
color = baseColor * texture2D(baseTex, texcoord.xy);
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
|
||||
// #ifdef NO_TEXTURE_LOD_IN_FRAGMENT
|
||||
#define texture1DLod(t,c,l) texture1D(t,c)
|
||||
#define texture2DLod(t,c,l) texture2D(t,c)
|
||||
// #endif
|
||||
|
||||
vec3 extend_normal(vec2 v)
|
||||
{
|
||||
// the higher the second value, the further away the light source from the landscape
|
||||
return normalize(vec3(v, 0.45));
|
||||
}
|
||||
|
||||
// Converts the pixel range 0.0..1.0 into the integer range 0..255
|
||||
int f2i(float x) {
|
||||
return int(x * 255.9);
|
||||
}
|
||||
|
|
@ -9,4 +9,7 @@ Blast2ObjectRatio=100
|
|||
MaxAirSpeed=100
|
||||
MaxSlide=1
|
||||
Placement=50
|
||||
TextureOverlay=gold
|
||||
TextureOverlay=gold
|
||||
LightEmit=0,215,255
|
||||
LightSpot=64,64,64
|
||||
LightAngle=220
|
||||
|
|
|
@ -10,7 +10,7 @@ void main()
|
|||
color = vec4(1.0, 1.0, 1.0, 1.0);
|
||||
#endif
|
||||
|
||||
slice(init+1)
|
||||
slice(texture+1)
|
||||
{
|
||||
// This picks up the normal map lookup in ObjectLightShader.c:
|
||||
#define OC_WITH_NORMALMAP
|
||||
|
|
|
@ -238,27 +238,15 @@ bool CStdGL::PrepareSpriteShader(C4Shader& shader, const char* name, int ssc, C4
|
|||
shader.AddTexCoord("texcoord");
|
||||
|
||||
// Then load slices for fragment shader
|
||||
shader.AddFragmentSlice(-1, "#define OPENCLONK");
|
||||
shader.AddFragmentSlice(-1, "#define OPENCLONK\n#define SPRITE");
|
||||
if (ssc & C4SSC_MOD2) shader.AddFragmentSlice(-1, "#define OC_CLRMOD_MOD2");
|
||||
if (ssc & C4SSC_NORMAL) shader.AddFragmentSlice(-1, "#define OC_WITH_NORMALMAP");
|
||||
if (ssc & C4SSC_LIGHT) shader.AddFragmentSlice(-1, "#define OC_DYNAMIC_LIGHT");
|
||||
if (ssc & C4SSC_BASE) shader.AddFragmentSlice(-1, "#define OC_HAVE_BASE");
|
||||
if (ssc & C4SSC_OVERLAY) shader.AddFragmentSlice(-1, "#define OC_HAVE_OVERLAY");
|
||||
|
||||
if (additionalDefines)
|
||||
for (const char* const* define = additionalDefines; *define != NULL; ++define)
|
||||
shader.AddFragmentSlice(-1, FormatString("#define %s", *define).getData());
|
||||
|
||||
shader.LoadSlices(pGroups, "UtilShader.glsl");
|
||||
shader.LoadSlices(pGroups, "ObjectBaseShader.glsl");
|
||||
|
||||
if (ssc & C4SSC_BASE) shader.LoadSlices(pGroups, "SpriteTextureShader.glsl");
|
||||
if (ssc & C4SSC_OVERLAY) shader.LoadSlices(pGroups, "SpriteOverlayShader.glsl");
|
||||
|
||||
// In case light is disabled, these shaders use a default light source
|
||||
// (typically ambient light everywhere).
|
||||
shader.LoadSlices(pGroups, "ObjectLightShader.glsl");
|
||||
shader.LoadSlices(pGroups, "LightShader.glsl");
|
||||
shader.LoadSlices(pGroups, "AmbientShader.glsl");
|
||||
shader.LoadSlices(pGroups, "GammaShader.glsl");
|
||||
shader.LoadSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadSlices(pGroups, "ObjectShader.glsl");
|
||||
|
||||
if (additionalSlices)
|
||||
for (const char* const* slice = additionalSlices; *slice != NULL; ++slice)
|
||||
|
|
|
@ -506,12 +506,8 @@ bool C4LandscapeRenderGL::LoadShader(C4GroupSet *pGroups, C4Shader& shader, cons
|
|||
shader.AddFragmentSlice(-1, "#define OC_LANDSCAPE");
|
||||
if(ssc & C4SSC_LIGHT) shader.AddFragmentSlice(-1, "#define OC_DYNAMIC_LIGHT"); // sample light from light texture
|
||||
|
||||
shader.LoadSlices(pGroups, "UtilShader.glsl");
|
||||
shader.LoadSlices(pGroups, "CommonShader.glsl");
|
||||
shader.LoadSlices(pGroups, "LandscapeShader.glsl");
|
||||
shader.LoadSlices(pGroups, "LightShader.glsl");
|
||||
shader.LoadSlices(pGroups, "AmbientShader.glsl");
|
||||
shader.LoadSlices(pGroups, "ScalerShader.glsl");
|
||||
shader.LoadSlices(pGroups, "GammaShader.glsl");
|
||||
|
||||
// Initialise!
|
||||
if (!shader.Init(name, UniformNames)) {
|
||||
|
@ -544,7 +540,6 @@ bool C4LandscapeRenderGL::LoadShaders(C4GroupSet *pGroups)
|
|||
UniformNames[C4LRU_Gamma] = "gamma";
|
||||
UniformNames[C4LRU_Resolution] = "resolution";
|
||||
UniformNames[C4LRU_Center] = "center";
|
||||
UniformNames[C4LRU_MatMap] = "matMap";
|
||||
UniformNames[C4LRU_MatMapTex] = "matMapTex";
|
||||
UniformNames[C4LRU_MaterialDepth] = "materialDepth";
|
||||
UniformNames[C4LRU_MaterialSize] = "materialSize";
|
||||
|
@ -766,7 +761,7 @@ void C4LandscapeRenderGL::AddTexturesFromMap(C4TextureMap *pMap)
|
|||
|
||||
}
|
||||
|
||||
void C4LandscapeRenderGL::BuildMatMap(GLfloat *pFMap, GLubyte *pIMap)
|
||||
void C4LandscapeRenderGL::BuildMatMap(uint32_t *pTex)
|
||||
{
|
||||
// TODO: Still merely an inefficient placeholder for things to come...
|
||||
|
||||
|
@ -778,8 +773,8 @@ void C4LandscapeRenderGL::BuildMatMap(GLfloat *pFMap, GLubyte *pIMap)
|
|||
if(!pEntry->GetTextureName())
|
||||
{
|
||||
// Undefined textures transparent
|
||||
if(pFMap) pFMap[pix] = 0.5 / iMaterialTextureDepth;
|
||||
if(pIMap) pIMap[pix] = 0;
|
||||
pTex[2*pix] = 0;
|
||||
pTex[2*pix+1] = RGBA(0,0,0,255);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -787,8 +782,13 @@ void C4LandscapeRenderGL::BuildMatMap(GLfloat *pFMap, GLubyte *pIMap)
|
|||
int iPhases = 1; const char *p = pEntry->GetTextureName();
|
||||
while((p = strchr(p, '-'))) { p++; iPhases++; }
|
||||
// Hard-coded hack. Fix me!
|
||||
const int iPhaseLength = 300;
|
||||
float phase = (iPhases == 1 ? 0 : float(C4TimeMilliseconds::Now().AsInt() % (iPhases * iPhaseLength)) / iPhaseLength);
|
||||
C4Material *pMaterial = pEntry->GetMaterial();
|
||||
const int iPhaseLength = pMaterial->AnimationSpeed;
|
||||
float phase = 0;
|
||||
if (iPhases > 1) {
|
||||
phase = C4TimeMilliseconds::Now().AsInt() % (iPhases * iPhaseLength);
|
||||
phase /= iPhaseLength;
|
||||
}
|
||||
|
||||
// Find our transition
|
||||
const char *pFrom = pEntry->GetTextureName();
|
||||
|
@ -817,8 +817,17 @@ void C4LandscapeRenderGL::BuildMatMap(GLfloat *pFMap, GLubyte *pIMap)
|
|||
}
|
||||
|
||||
// Assign texture
|
||||
if(pFMap) pFMap[pix] = gTexCoo / iMaterialTextureDepth;
|
||||
if(pIMap) pIMap[pix] = int((gTexCoo * 256.0 / iMaterialTextureDepth) + 0.5);
|
||||
int iTexCoo = int((gTexCoo * 256.0 / iMaterialTextureDepth) + 0.5);
|
||||
pTex[2*pix] = RGBA(
|
||||
Clamp(pMaterial->LightEmit[0], 0, 255),
|
||||
Clamp(pMaterial->LightEmit[1], 0, 255),
|
||||
Clamp(pMaterial->LightEmit[2], 0, 255),
|
||||
iTexCoo);
|
||||
pTex[2*pix+1] = RGBA(
|
||||
Clamp(pMaterial->LightSpot[0], 0, 255),
|
||||
Clamp(pMaterial->LightSpot[1], 0, 255),
|
||||
Clamp(pMaterial->LightSpot[2], 0, 255),
|
||||
Clamp(pMaterial->LightAngle, 0, 255));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -855,15 +864,7 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Ligh
|
|||
ShaderCall.SetUniform2f(C4LRU_Center,
|
||||
centerX / float(Surfaces[0]->Wdt),
|
||||
centerY / float(Surfaces[0]->Hgt));
|
||||
if (shader->HaveUniform(C4LRU_MatMap))
|
||||
{
|
||||
GLfloat MatMap[256];
|
||||
BuildMatMap(MatMap, NULL);
|
||||
ShaderCall.SetUniform1fv(C4LRU_MatMap, 256, MatMap);
|
||||
}
|
||||
|
||||
float fMaterialTextureDepth = iMaterialTextureDepth;
|
||||
ShaderCall.SetUniform1f(C4LRU_MaterialDepth, fMaterialTextureDepth);
|
||||
ShaderCall.SetUniform1f(C4LRU_MaterialDepth, float(iMaterialTextureDepth));
|
||||
ShaderCall.SetUniform2f(C4LRU_MaterialSize,
|
||||
float(iMaterialWidth) / ::Game.C4S.Landscape.MaterialZoom,
|
||||
float(iMaterialHeight) / ::Game.C4S.Landscape.MaterialZoom);
|
||||
|
@ -922,9 +923,9 @@ void C4LandscapeRenderGL::Draw(const C4TargetFacet &cgo, const C4FoWRegion *Ligh
|
|||
}
|
||||
if(ShaderCall.AllocTexUnit(C4LRU_MatMapTex))
|
||||
{
|
||||
GLubyte MatMap[256];
|
||||
BuildMatMap(NULL, MatMap);
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, 1, 256, 0, GL_RED, GL_UNSIGNED_BYTE, MatMap);
|
||||
uint32_t MatMap[2*256];
|
||||
BuildMatMap(MatMap);
|
||||
glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA8, 2*256, 0, GL_RGBA, GL_UNSIGNED_BYTE, MatMap);
|
||||
glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ enum C4LR_Uniforms
|
|||
C4LRU_Gamma,
|
||||
C4LRU_Resolution,
|
||||
C4LRU_Center,
|
||||
C4LRU_MatMap,
|
||||
C4LRU_MatMapTex,
|
||||
C4LRU_MaterialDepth,
|
||||
C4LRU_MaterialSize,
|
||||
|
@ -147,7 +146,7 @@ private:
|
|||
void AddTextureTransition(const char *szFrom, const char *szTo);
|
||||
void AddTextureAnim(const char *szTextureAnim);
|
||||
void AddTexturesFromMap(C4TextureMap *pMap);
|
||||
void BuildMatMap(GLfloat *pFMap, GLubyte *pIMap);
|
||||
void BuildMatMap(uint32_t *pTex);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
|
|
@ -267,6 +267,12 @@ void C4MaterialCore::Clear()
|
|||
MinHeightCount = 0;
|
||||
SplashRate=10;
|
||||
KeepSinglePixels=false;
|
||||
AnimationSpeed = 20;
|
||||
LightAngle = 255;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
LightEmit[i] = 0;
|
||||
LightSpot[i] = 16;
|
||||
}
|
||||
}
|
||||
|
||||
void C4MaterialCore::Default()
|
||||
|
@ -304,7 +310,6 @@ void C4MaterialCore::CompileFunc(StdCompiler *pComp)
|
|||
if (pComp->isCompiler()) Clear();
|
||||
pComp->Name("Material");
|
||||
pComp->Value(mkNamingAdapt(toC4CStr(Name), "Name", ""));
|
||||
pComp->Value(mkNamingAdapt(ColorAnimation, "ColorAnimation", 0));
|
||||
|
||||
const StdEnumEntry<C4MaterialCoreShape> Shapes[] =
|
||||
{
|
||||
|
@ -368,6 +373,10 @@ void C4MaterialCore::CompileFunc(StdCompiler *pComp)
|
|||
pComp->Value(mkNamingAdapt(MinHeightCount, "MinHeightCount", 0));
|
||||
pComp->Value(mkNamingAdapt(SplashRate, "SplashRate", 10));
|
||||
pComp->Value(mkNamingAdapt(KeepSinglePixels, "KeepSinglePixels", false));
|
||||
pComp->Value(mkNamingAdapt(AnimationSpeed, "AnimationSpeed", 100));
|
||||
pComp->Value(mkNamingAdapt(LightAngle, "LightAngle", 255));
|
||||
pComp->Value(mkNamingAdapt(mkArrayAdaptDM(LightEmit, 0), "LightEmit"));
|
||||
pComp->Value(mkNamingAdapt(mkArrayAdaptDM(LightSpot, 16),"LightSpot"));
|
||||
pComp->NameEnd();
|
||||
// material reactions
|
||||
pComp->Value(mkNamingAdapt(mkSTLContainerAdapt(CustomReactionList),
|
||||
|
|
|
@ -180,6 +180,10 @@ public:
|
|||
int32_t MinHeightCount; // minimum material thickness in order for it to be counted
|
||||
int32_t SplashRate;
|
||||
bool KeepSinglePixels; // if true, single pixels are not destroyed (for vehicle)
|
||||
int32_t AnimationSpeed; // frames per animation phase
|
||||
int32_t LightAngle; // light angle at which we have maximum reflection
|
||||
int32_t LightEmit[3]; // amount the material lights up itself
|
||||
int32_t LightSpot[3]; // spot strength
|
||||
|
||||
void Clear();
|
||||
void Default();
|
||||
|
|
|
@ -854,7 +854,6 @@ bool StdMeshMaterialProgram::AddParameterNames(const StdMeshMaterialShaderParame
|
|||
bool StdMeshMaterialProgram::CompileShader(StdMeshMaterialLoader& loader, C4Shader& shader, int ssc)
|
||||
{
|
||||
// Add standard slices
|
||||
shader.AddFragmentSlice(-1, "#define OC_MESH");
|
||||
loader.AddShaderSlices(shader, ssc);
|
||||
// Add our slices
|
||||
shader.AddVertexSlice(-1, "varying vec2 texcoord;");
|
||||
|
|
|
@ -61,27 +61,16 @@ public:
|
|||
{
|
||||
#ifndef USE_CONSOLE
|
||||
// Add mesh-independent slices
|
||||
shader.AddFragmentSlice(-1, "#define OPENCLONK");
|
||||
shader.AddVertexSlice(-1, "#define OPENCLONK");
|
||||
shader.AddFragmentSlice(-1, "#define OPENCLONK\n#define OC_MESH");
|
||||
shader.AddVertexSlice(-1, "#define OPENCLONK\n#define OC_MESH");
|
||||
|
||||
if (ssc & C4SSC_MOD2) shader.AddFragmentSlice(-1, "#define OC_CLRMOD_MOD2");
|
||||
if (ssc & C4SSC_LIGHT) shader.AddFragmentSlice(-1, "#define OC_DYNAMIC_LIGHT");
|
||||
if (ssc & C4SSC_BASE) shader.AddFragmentSlice(-1, "#define OC_HAVE_LIGHT");
|
||||
if (ssc & C4SSC_OVERLAY) shader.AddFragmentSlice(-1, "#define OC_HAVE_LIGHT");
|
||||
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "UtilShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "ObjectBaseShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "MeshShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "GammaShader.glsl");
|
||||
|
||||
// Note that these shader slices are always loaded, even if lighting
|
||||
// is disabled. The shaders then assume a default light if OC_DYNAMIC_LIGHT
|
||||
// is not defined. This avoids completely flat shading for meshes
|
||||
// that are shown as picture graphics for example.
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "ObjectLightShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "LightShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "AmbientShader.glsl");
|
||||
|
||||
if (ssc & C4SSC_BASE) shader.LoadSlices(&::GraphicsResource.Files, "SpriteTextureShader.glsl");
|
||||
if (ssc & C4SSC_OVERLAY) shader.LoadSlices(&::GraphicsResource.Files, "SpriteOverlayShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "CommonShader.glsl");
|
||||
shader.LoadSlices(&::GraphicsResource.Files, "ObjectShader.glsl");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue