Skip to content

Instantly share code, notes, and snippets.

@arielm
Last active December 2, 2021 04:51
Show Gist options
  • Save arielm/52cec987bc9f57b3d725cdd8555ef0bb to your computer and use it in GitHub Desktop.
Save arielm/52cec987bc9f57b3d725cdd8555ef0bb to your computer and use it in GitHub Desktop.
Testing OpenGL 2.1 / WebGL1 lighting
#ifdef GL_ES
precision highp float;
#endif
uniform sampler2D u_sampler;
uniform float u_shininess;
varying vec3 v_normal;
varying vec4 v_color;
varying vec2 v_coord;
varying vec3 v_surface_to_light;
varying vec3 v_surface_to_view;
void main() {
vec3 normal = normalize(v_normal);
vec3 surfaceToLightDirection = normalize(v_surface_to_light);
vec3 surfaceToViewDirection = normalize(v_surface_to_view);
vec3 halfVector = normalize(surfaceToLightDirection + surfaceToViewDirection);
float specular = 0.0;
float light = dot(normal, surfaceToLightDirection);
if (light > 0.0) {
specular = pow(dot(normal, halfVector), u_shininess);
}
vec4 color = v_color * texture2D(u_sampler, v_coord);
gl_FragColor = vec4(color.rgb * light + specular, 1.0);
}
attribute vec4 a_position;
attribute vec3 a_normal;
attribute vec4 a_color;
attribute vec2 a_coord;
uniform mat4 u_model_matrix;
uniform mat4 u_view_matrix;
uniform mat4 u_projection_matrix;
uniform mat3 u_normal_matrix;
uniform vec3 u_eye_position;
uniform vec3 u_light_position;
varying vec3 v_normal;
varying vec4 v_color;
varying vec2 v_coord;
varying vec3 v_surface_to_light;
varying vec3 v_surface_to_view;
void main() {
v_normal = u_normal_matrix * a_normal;
v_color = a_color;
v_coord = a_coord;
v_surface_to_light = (u_view_matrix * (vec4(u_light_position, 1.0) - a_position)).xyz;
v_surface_to_view = (u_view_matrix * (vec4(u_eye_position, 1.0) - a_position)).xyz;
gl_Position = u_projection_matrix * u_view_matrix * u_model_matrix * a_position;
}
#include "Sketch.h"
#include "chr/gl/draw/Torus.h"
#include "chr/gl/draw/Sphere.h"
#include "chr/gl/draw/Cylinder.h"
#include "chr/gl/draw/Box.h"
#include "chr/gl/draw/Cube.h"
using namespace std;
using namespace chr;
using namespace gl;
using namespace draw;
Sketch::Sketch()
:
shader(InputSource::resource("Shader.vert"), InputSource::resource("Shader.frag"))
{}
void Sketch::setup()
{
texture = Texture::ImageRequest("checker.png")
.setFlags(image::FLAGS_RBGA)
.setWrap(GL_REPEAT, GL_REPEAT)
.setFilters(GL_NEAREST, GL_NEAREST);
geometryBatch.setTexture(texture);
torusBatch
.setShaderColor(1.0f, 0.5f, 0.0f, 1)
.setTexture(texture);
Box()
.setFrontFace(CCW)
.setColor(0.75f, 0.75f, 0.75f, 1)
.setSize(300, 5, 300)
.append(geometryBatch, Matrix().translate(-150, -5, -150));
Cube()
.setFrontFace(CCW)
.setColor(1, 0.25f, 0, 1)
.setSize(60)
.append(geometryBatch, Matrix().translate(0, -30, 0));
Sphere()
.setFrontFace(CCW)
.setColor(0.25f, 1.0f, 0.0f, 1)
.setSectorCount(60)
.setStackCount(30)
.setRadius(40)
.append(geometryBatch, Matrix().translate(-75, -40, 100));
Cylinder()
.setFrontFace(CCW)
.setColor(0.25f, 0.25f, 1.0f, 1)
.setSectorCount(30)
.setStackCount(1)
.setBaseRadius(40)
.setTopRadius(0)
.setHeight(80)
.append(geometryBatch, Matrix().translate(75, -40, -100).rotateX(D2R * 90));
Cylinder()
.setFrontFace(CCW)
.setColor(0.25f, 0.25f, 1.0f, 1)
.setSectorCount(30)
.setStackCount(1)
.setBaseRadius(40)
.setTopRadius(40)
.setHeight(80)
.append(geometryBatch, Matrix().translate(-75, -40, -100).rotateX(D2R * 90));
Torus()
.setFrontFace(CCW)
.setSliceCount(20)
.setLoopCount(60)
.setInnerRadius(12)
.setOuterRadius(48)
.append(torusBatch, Matrix());
// ---
glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
void Sketch::resize()
{
camera
.setFov(45)
.setClip(0.1f, 1000.0f)
.setWindowSize(windowInfo.size);
}
void Sketch::draw()
{
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ---
camera.getViewMatrix()
.setIdentity()
.scale(1, -1, 1)
.translate(0, 0, -400)
.rotateX(-30 * D2R)
.rotateY(15 * D2R);
// ---
State state;
state
.setShader(shader)
.setShaderMatrix<MODEL>(Matrix())
.setShaderMatrix<VIEW>(camera.getViewMatrix())
.setShaderMatrix<PROJECTION>(camera.getProjectionMatrix())
.setShaderMatrix<NORMAL>(camera.getNormalMatrix())
.setShaderUniform("u_eye_position", camera.getEyePosition())
.setShaderUniform("u_light_position", camera.getEyePosition())
.setShaderUniform("u_shininess", 50.0f)
.apply();
geometryBatch.flush();
Matrix modelMatrix;
modelMatrix
.translate(75, -60, 100)
.rotateY(clock()->getTime());
state
.setShaderMatrix<MODEL>(modelMatrix)
.apply();
torusBatch.flush();
}
#pragma once
#include "chr/cross/Context.h"
#include "chr/gl/Camera.h"
#include "chr/gl/Batch.h"
#include "chr/gl/ShaderProgram.h"
class Sketch : public chr::CrossSketch
{
public:
Sketch();
virtual ~Sketch() {}
void setup() final;
void resize() final;
void draw() final;
protected:
chr::gl::Camera camera;
chr::gl::Texture texture;
chr::gl::ShaderProgram shader;
chr::gl::IndexedVertexBatch<chr::gl::XYZ.N.UV.RGBA> geometryBatch;
chr::gl::IndexedVertexBatch<chr::gl::XYZ.N.UV> torusBatch;
};
@arielm
Copy link
Author

arielm commented Dec 2, 2021

Some context:

  1. Online demo (WebGL)
  2. Made with the chronotext-cross framework
  3. Stack Overflow question

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment