Skip to content

Commit

Permalink
Optimizes the integration of shaders and adds some minor changes and …
Browse files Browse the repository at this point in the history
…new features.

- Duplicate shader code is now placed in a separate GLSL file and included in each shader program during loading time
- Adds new ShaderParameters class which simplifies setting shader parameters
- Blocks are now affected by torchlight
- Gel. cubes are now affected by torchlight
- Adds vignette post processing effect which become more intense while dimming
- Screen becomes now blurry when swimming
- Gel. cubes now vary more in size
- Optimizes the AI of Gel. cubes to be a bit more fun and less jumpy
- And some more stuff I forgot to mention. ;)
  • Loading branch information
begla committed Feb 11, 2012
1 parent 0b98bfe commit 4a785f0
Show file tree
Hide file tree
Showing 25 changed files with 428 additions and 199 deletions.
3 changes: 0 additions & 3 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 18 additions & 13 deletions src/org/terasology/data/shaders/block_frag.glsl
Expand Up @@ -2,29 +2,34 @@ uniform sampler2D textureAtlas;

uniform float light;
uniform vec3 colorOffset;

uniform bool textured;
uniform bool carryingTorch;

vec4 srgbToLinear(vec4 color){
return pow(color, vec4(1.0 / GAMMA));
}

vec4 linearToSrgb(vec4 color){
return pow(color, vec4(GAMMA));
}
varying vec3 normal;
varying vec4 vertexWorldPos;

void main(){
vec4 color = vec4(1.0,1.0,1.0,1.0);
vec4 color;

if (textured) {
color = srgbToLinear(texture2D(textureAtlas, vec2(gl_TexCoord[0].x , gl_TexCoord[0].y)));
} else {
color = gl_Color;
}

color.rgb *= gl_Color.rgb * clamp(light, 0.0, 1.0);
color.rgb *= colorOffset.rgb;
float torchlight = 0.0;

if (textured)
// Apply torchlight
if (carryingTorch)
torchlight = torchlight(light(normal, vertexWorldPos), vertexWorldPos);

// Apply light
color.rgb *= clamp(light + torchlight, 0.0, 1.0);

if (textured) {
color.rgb *= colorOffset.rgb;
gl_FragColor = linearToSrgb(color);
else
} else {
gl_FragColor = color;
}
}
6 changes: 6 additions & 0 deletions src/org/terasology/data/shaders/block_vert.glsl
@@ -1,5 +1,11 @@
varying vec3 normal;
varying vec4 vertexWorldPos;

void main()
{
vertexWorldPos = gl_ModelViewMatrix * gl_Vertex;
normal = gl_NormalMatrix * gl_Normal;

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
Expand Down
42 changes: 5 additions & 37 deletions src/org/terasology/data/shaders/chunk_frag.glsl
Expand Up @@ -10,22 +10,11 @@ uniform bool carryingTorch;

varying vec4 vertexWorldPos;
varying vec3 normal;
varying float distance;

uniform vec4 playerPosition;

uniform vec2 waterCoordinate;
uniform vec2 lavaCoordinate;
uniform vec2 grassCoordinate;

vec4 srgbToLinear(vec4 color){
return pow(color, vec4(1.0 / GAMMA));
}

vec4 linearToSrgb(vec4 color){
return pow(color, vec4(GAMMA));
}

void main(){
vec4 texCoord = gl_TexCoord[0];
vec4 color;
Expand Down Expand Up @@ -72,22 +61,16 @@ void main(){

float occlusionValue = gl_TexCoord[1].z;

float highlight = 0.0;
float light = light(normal, vertexWorldPos);
float torchlight = 0.0;

// Calculate Lambertian lighting
vec3 N = normalize(normal * ((gl_FrontFacing) ? 1.0 : -1.0));
vec3 L = normalize(-vertexWorldPos.xyz);

highlight = dot(N,L);

// Apply torchlight
if (carryingTorch) {
torchlight = highlight * clamp(1.0 - (distance / 16.0), 0.0, 1.0) * blocklightDayIntensity;
torchlight = torchlight(light, vertexWorldPos) * blocklightDayIntensity;
}

// Apply some lighting highlights to the daylight light value
vec3 daylightColorValue = vec3(daylightValue * 0.95 + highlight * 0.05);
// Apply some lighting to the daylight light value
vec3 daylightColorValue = vec3(daylightValue * 0.85 + light * 0.15);

float blockBrightness = blocklightValue + torchlight - ((sin(tick*0.05) + 1.0) / 16.0) * blocklightValue;
blockBrightness *= blocklightDayIntensity;
Expand All @@ -96,20 +79,5 @@ void main(){

// Apply the final lighting mix
color.xyz *= (daylightColorValue * occlusionValue + blocklightColorValue * occlusionValue);

// Check if the player is below the water surface
if (!swimming) {
// Apply linear fog
float fog = clamp((gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale, 0.25, 1.0);

gl_FragColor.rgb = linearToSrgb(mix(vec4(1.0) * daylight, color, fog)).rgb;
gl_FragColor.a = color.a;
} else {
// Very foggy below water...
float fog = clamp((16.0 - gl_FogFragCoord) / 16.0, 0.0, 1.0);

// And everything looks a bit blueish and darker
gl_FragColor.rgb = linearToSrgb(mix(vec4(0.0, 0.0, 0.1, 1.0), color * vec4(0.8, 0.8, 0.9, 1.0), fog)).rgb;
gl_FragColor.a = color.a;
}
gl_FragColor = linearToSrgb(color);
}
4 changes: 1 addition & 3 deletions src/org/terasology/data/shaders/chunk_vert.glsl
Expand Up @@ -6,8 +6,6 @@ uniform float wavingCoordinates[32];
uniform vec2 waterCoordinate;
uniform vec2 lavaCoordinate;

varying float distance;

float radialFog(vec4 v1)
{
vec4 v2 = v1 / v1.w;
Expand All @@ -17,7 +15,7 @@ float radialFog(vec4 v1)
void main()
{
vertexWorldPos = gl_ModelViewMatrix * gl_Vertex;
distance = length(vertexWorldPos);
float distance = length(vertexWorldPos);

gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;

Expand Down
8 changes: 0 additions & 8 deletions src/org/terasology/data/shaders/clouds_frag.glsl
Expand Up @@ -2,14 +2,6 @@ uniform sampler2D texture;

uniform float light = 1.0;

vec4 srgbToLinear(vec4 color){
return pow(color, vec4(1.0 / GAMMA));
}

vec4 linearToSrgb(vec4 color){
return pow(color, vec4(GAMMA));
}

void main(){
vec4 color = srgbToLinear(texture2D(texture, vec2(gl_TexCoord[0].x , gl_TexCoord[0].y)));

Expand Down
19 changes: 10 additions & 9 deletions src/org/terasology/data/shaders/gelatinousCube_frag.glsl
@@ -1,21 +1,22 @@
uniform sampler2D texture;
uniform vec4 colorOffset;
uniform bool carryingTorch;

uniform float light = 1.0;

vec4 srgbToLinear(vec4 color){
return pow(color, vec4(1.0 / GAMMA));
}
varying vec3 normal;
varying vec4 vertexWorldPos;

vec4 linearToSrgb(vec4 color){
return pow(color, vec4(GAMMA));
}
uniform float light = 1.0;

void main(){
vec4 color = srgbToLinear(texture2D(texture, vec2(gl_TexCoord[0].x , gl_TexCoord[0].y)));

float torchlight = 0.0;

if (carryingTorch)
torchlight = torchlight(light(normal, vertexWorldPos), vertexWorldPos);

color.rgb *= clamp(gl_Color.rgb, 0.0, 1.0) * colorOffset.rgb;
color.rgb *= pow(0.86, (1.0-light)*15.0);
color.rgb *= pow(0.86, (1.0-light)*15.0) + torchlight;
color.a = gl_Color.a;

gl_FragColor = linearToSrgb(color);
Expand Down
8 changes: 7 additions & 1 deletion src/org/terasology/data/shaders/gelatinousCube_vert.glsl
@@ -1,12 +1,18 @@
uniform float tick;

varying vec3 normal;
varying vec4 vertexWorldPos;

void main()
{
vec4 vertexPos = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_FrontColor = gl_Color;

vertexPos.y += cos(tick*0.25 + vertexPos.x * 0.25) * 0.2;
vertexWorldPos = gl_ModelViewMatrix * gl_Vertex;
normal = gl_NormalMatrix * gl_Normal;

vertexPos.y += cos(tick*0.1 + vertexPos.x * 0.1) * sin(tick*0.1 + vertexPos.x * 0.1 + 0.483921) * 0.15;

gl_Position = vertexPos;
}
18 changes: 18 additions & 0 deletions src/org/terasology/data/shaders/globalFunctionsFragIncl.glsl
@@ -0,0 +1,18 @@
float light(vec3 normal, vec4 worldPos) {
vec3 N = normalize(normal * ((gl_FrontFacing) ? 1.0 : -1.0));
vec3 L = normalize(-worldPos.xyz);

return dot(N,L);
}

float torchlight(float light, vec4 worldPos) {
return light * clamp(1.0 - (length(worldPos) / 16.0), 0.0, 1.0);
}

vec4 srgbToLinear(vec4 color) {
return pow(color, vec4(1.0 / GAMMA));
}

vec4 linearToSrgb(vec4 color) {
return pow(color, vec4(GAMMA));
}
Empty file.
8 changes: 0 additions & 8 deletions src/org/terasology/data/shaders/particle_frag.glsl
Expand Up @@ -5,14 +5,6 @@ uniform float texOffsetX = 0.0;
uniform float texOffsetY = 0.0;
uniform vec3 colorOffset = vec3(1.0, 1.0, 1.0);

vec4 srgbToLinear(vec4 color){
return pow(color, vec4(1.0 / GAMMA));
}

vec4 linearToSrgb(vec4 color){
return pow(color, vec4(GAMMA));
}

void main(){
vec4 color = srgbToLinear(texture2D(textureAtlas, vec2(gl_TexCoord[0].x + texOffsetX , gl_TexCoord[0].y + texOffsetY )));

Expand Down
20 changes: 16 additions & 4 deletions src/org/terasology/data/shaders/post_frag.glsl
Expand Up @@ -3,6 +3,7 @@ uniform sampler2D texBloom;
uniform sampler2D texDepth;
uniform sampler2D texBlur;

uniform bool swimming;
uniform float exposure = 1.0;
const float brightMax = 1.0;

Expand Down Expand Up @@ -32,11 +33,22 @@ void main(){
float depth = linDepth();
float blur = 0.0;

if (depth > 0.1)
if (depth > 0.1 && !swimming)
blur = clamp((depth - 0.1) / 0.1, 0.0, 1.0);
else if (swimming)
blur = 1.0;

// Display depth map
//gl_FragColor = vec4(linDepth());
vec4 finalColor = mix(color, colorBlur, blur);

gl_FragColor = mix(color, colorBlur, blur);
vec2 vignette = vec2(0.25, 0.25);

float d = distance(gl_TexCoord[0].xy, vec2(0.5,0.5));

// Vignette
if (swimming)
finalColor.rgb *= (1.0 - d) / 4.0;
else
finalColor.rgb *= (1.0 - d);

gl_FragColor = finalColor;
}
27 changes: 9 additions & 18 deletions src/org/terasology/logic/characters/GelatinousCube.java
Expand Up @@ -16,14 +16,14 @@
*/
package org.terasology.logic.characters;

import org.lwjgl.opengl.GL20;
import org.terasology.game.Terasology;
import org.terasology.logic.manager.ShaderManager;
import org.terasology.logic.manager.TextureManager;
import org.terasology.model.structures.AABB;
import org.terasology.model.structures.ShaderParameters;
import org.terasology.rendering.primitives.Mesh;
import org.terasology.rendering.primitives.TessellatorHelper;
import org.terasology.rendering.primitives.Tessellator;
import org.terasology.rendering.primitives.TessellatorHelper;
import org.terasology.rendering.world.WorldRenderer;
import org.terasology.utilities.MathHelper;

Expand All @@ -41,8 +41,6 @@
public final class GelatinousCube extends Character {

private final Mesh _mesh;

private static final float WIDTH_HALF = 0.5f, HEIGHT_HALF = 0.5f;
private static final Vector3f[] COLORS = {new Vector3f(1.0f, 1.0f, 0.2f), new Vector3f(1.0f, 0.2f, 0.2f), new Vector3f(0.2f, 1.0f, 0.2f), new Vector3f(1.0f, 1.0f, 0.2f)};

private long _lastChangeOfDirectionAt = Terasology.getInstance().getTime();
Expand All @@ -54,7 +52,7 @@ public final class GelatinousCube extends Character {
public GelatinousCube(WorldRenderer parent) {
super(parent, 0.02, 1.5, 0.2, true);

_randomSize = (float) MathHelper.clamp((_parent.getWorldProvider().getRandom().randomDouble() + 1.0) / 2.0 + 0.15);
_randomSize = (float) (((_parent.getWorldProvider().getRandom().randomDouble() + 1.0) / 2.0) * 2.0 + 0.15);
_randomColorId = Math.abs(_parent.getWorldProvider().getRandom().randomInt()) % COLORS.length;

Tessellator tessellator = new Tessellator();
Expand All @@ -78,14 +76,10 @@ public void render() {

TextureManager.getInstance().bindTexture("slime");

// Setup the shader
ShaderManager.getInstance().enableShader("gelatinousCube");
int tick = GL20.glGetUniformLocation(ShaderManager.getInstance().getShader("gelatinousCube"), "tick");
GL20.glUniform1f(tick, _parent.getTick());
int cOffset = GL20.glGetUniformLocation(ShaderManager.getInstance().getShader("gelatinousCube"), "colorOffset");
GL20.glUniform4f(cOffset, COLORS[_randomColorId].x, COLORS[_randomColorId].y, COLORS[_randomColorId].z, 1.0f);
int light = GL20.glGetUniformLocation(ShaderManager.getInstance().getShader("gelatinousCube"), "light");
GL20.glUniform1f(light, _parent.getRenderingLightValueAt(getPosition()));
ShaderParameters params = ShaderManager.getInstance().getShaderParameters("gelatinousCube");
params.setFloat4("colorOffset", COLORS[_randomColorId].x, COLORS[_randomColorId].y, COLORS[_randomColorId].z, 1.0f);
params.setFloat("light", _parent.getRenderingLightValueAt(getPosition()));

_mesh.render();

Expand All @@ -103,20 +97,17 @@ public void processMovement() {
_movementTarget.set(_parent.getPlayer().getPosition());
}

if (Terasology.getInstance().getTime() - _lastChangeOfDirectionAt > 5000 || distanceToPlayer <= 5) {
if (Terasology.getInstance().getTime() - _lastChangeOfDirectionAt > 12000 || distanceToPlayer <= 5) {
_movementTarget.set(getPosition().x + _parent.getWorldProvider().getRandom().randomDouble() * 500, getPosition().y, getPosition().z + _parent.getWorldProvider().getRandom().randomDouble() * 500);
_lastChangeOfDirectionAt = Terasology.getInstance().getTime();
}

lookAt(_movementTarget);
walkForward();

if (_parent.getWorldProvider().getRandom().randomDouble() < -0.94)
jump();
}

protected AABB generateAABBForPosition(Vector3d p) {
return new AABB(p, new Vector3d(WIDTH_HALF, HEIGHT_HALF, WIDTH_HALF));
return new AABB(p, new Vector3d(_randomSize / 2, _randomSize / 2, _randomSize / 2));
}

public AABB getAABB() {
Expand All @@ -130,6 +121,6 @@ protected void handleVerticalCollision() {

@Override
protected void handleHorizontalCollision() {
_lastChangeOfDirectionAt = 0;
jump();
}
}
13 changes: 0 additions & 13 deletions src/org/terasology/logic/characters/Player.java
Expand Up @@ -507,19 +507,6 @@ public void renderHand() {
TextureManager.getInstance().bindTexture("char");
ShaderManager.getInstance().enableShader("block");

int light = GL20.glGetUniformLocation(ShaderManager.getInstance().getShader("block"), "light");
GL20.glUniform1f(light, _parent.getRenderingLightValueAt(getPosition()));

// Make sure the hand is not affected by the biome color. ZOMBIES!!!!
FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(3);
colorBuffer.put(1.0f);
colorBuffer.put(1.0f);
colorBuffer.put(1.0f);
colorBuffer.flip();

int colorOffset = GL20.glGetUniformLocation(ShaderManager.getInstance().getShader("block"), "colorOffset");
GL20.glUniform3(colorOffset, colorBuffer);

glPushMatrix();
glTranslatef(0.8f, -1.1f + (float) calcBobbingOffset((float) Math.PI / 8f, 0.05f, 2.5f) - _handMovementAnimationOffset * 0.5f, -1.0f - _handMovementAnimationOffset * 0.5f);
glRotatef(-45f - _handMovementAnimationOffset * 64.0f, 1.0f, 0.0f, 0.0f);
Expand Down

0 comments on commit 4a785f0

Please sign in to comment.