Home - MahdiMahava/hello_world GitHub Wiki

Welcome to the hello_world wiki! olololo Materials Fragment shader code for the models in Pool is stored in one big string. All 3D models use the same vertex shader. When the shader is compiled, the fragment shader used is determined by appending a main function to the end of the shader string. The shader compiler is expected to do eliminate dead code.

var mainString = 'void main() {' + ' gl_FragColor = ' + name + 'PixelShader();' + '}';

effect.loadVertexShaderFromString(vertexShaderString); effect.loadPixelShaderFromString(pixelShaderString + mainString); This way, pixel shaders can call any other functions inside the shader string. The function lighting(), which does a variant of the standard Phong lighting calculation, gets called by most of the other pixel shaders. The color of the felt pigment is determined by a function. To change the color of the felt, therefore, you only have to change it in one place.

vec4 feltPigment(vec3 p) { return vec4(0.1, 0.45, 0.15, 1.0); } If you cange the color of the felt in that function, the rails which use a different shader and the subtle reflection in the bottom of the ball will change too.

To add a new material, you only have to add its pixel main function to the shader code and add the name of the material here:

g_materials = { 'solid':{}, 'felt':{}, 'wood':{}, 'cushion':{}, 'billiard':{}, 'ball':{}, 'shadowPlane':{}}; This method of putting all shaders in one string would probably not be practical for a complicated game with lots of shaders, but for Pool, with just a handful of shaders, we get away with it.

Shadows Each ball's shadow is accomplished by drawing the top face of the table to a render target using a shader that takes the position of the ball as a uniform parameter.

vec4 shadowPlanePixelShader() { vec2 p = vworldPosition.xy - ballCenter; vec2 q = (vworldPosition.xy / lightWorldPosition.z);

vec2 offset = (1.0 - 1.0 / (vec2(1.0, 1.0) + abs(q))) * sign(q); float t = mix(smoothstep(0.9, 0.0, length(p - length(p) * offset) / 2.0), smoothstep(1.0, 0.0, length(p) / 10.0), 0.15); return shadowOn * vec4(t, t, t, t); } The preceding code draws two soft white blobs originating from the center of the ball. The call to lerp blends the two blobs together. The first blob is meant to be the shadow cast by the light onto the table. For a touch of realism, that blob is skewed away from the light source. The second blob is meant to be a subtle ambient occlusion effect, so it falls off evenly. You can see the white blobs that get drawn by setting the variable SHADOWPOV to true.